UNPKG

rcs-data

Version:

RCS消息数据结构

153 lines 5.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseHeaderValue = exports.parse = void 0; const grammar_1 = require("./grammar"); const entity_1 = require("./entity"); const debug = require('debug')('mime:parse'); const debugerror = require('debug')('mime:ERROR:parse'); const REGEXP_VALID_MIME_HEADER = /^([a-zA-Z0-9!#$%&'+,\-\^_`|~]+)[ \t]*:[ \t]*(.+)$/; function parse(rawMessage) { if (typeof rawMessage !== 'string') { throw new TypeError('given data must be a string'); } let entity = new entity_1.Entity(); if (!parseEntity(entity, rawMessage, true)) { debugerror('invalid MIME message'); return false; } return entity; } exports.parse = parse; function parseEntity(entity, rawEntity, topLevel) { debug('parseEntity()'); let headersEnd = -1, rawHeaders, rawBody, contentType, boundary, boundaryRegExp, boundaryEndRegExp, match, partStart, parts = [], i, len, subEntity; if (/^[^\r\n]/.test(rawEntity)) { headersEnd = rawEntity.indexOf('\r\n\r\n'); } if (headersEnd !== -1) { rawHeaders = rawEntity.slice(0, headersEnd); rawBody = rawEntity.slice(headersEnd + 4); } else if (topLevel) { debugerror('parseEntity() | wrong MIME headers in top level entity'); return false; } else { if (/^\r\n/.test(rawEntity)) { rawBody = rawEntity.slice(2); } else { debugerror('parseEntity() | wrong sub-entity'); return false; } } if (rawHeaders && !parseEntityHeaders(entity, rawHeaders)) { return false; } contentType = entity.contentType; if (contentType && contentType.type === 'multipart') { boundary = contentType.params.boundary; if (!boundary) { debugerror('parseEntity() | "multipart" Content-Type must have "boundary" parameter'); return false; } boundaryRegExp = new RegExp('(\\r\\n)?--' + boundary + '[\\t ]*\\r\\n', 'g'); boundaryEndRegExp = new RegExp('\\r\\n--' + boundary + '--[\\t ]*'); while (true) { match = boundaryRegExp.exec(rawBody); if (match) { if (partStart !== undefined) { parts.push(rawBody.slice(partStart, match.index)); } partStart = boundaryRegExp.lastIndex; } else { if (partStart === undefined) { debugerror('parseEntity() | no bodies found in a "multipart" sub-entity'); return false; } boundaryEndRegExp.lastIndex = partStart; match = boundaryEndRegExp.exec(rawBody); if (!match) { debugerror('parseEntity() | no ending boundary in a "multipart" sub-entity'); return false; } parts.push(rawBody.slice(partStart, match.index)); break; } } entity._body = []; for (i = 0, len = parts.length; i < len; i++) { subEntity = new entity_1.Entity(); entity._body.push(subEntity); if (!parseEntity(subEntity, parts[i])) { debugerror('invalid MIME sub-entity'); return false; } } } else { entity._body = rawBody; } return true; } function parseEntityHeaders(entity, rawHeaders) { let lines = rawHeaders.split('\r\n'); let line, i, len; for (i = 0, len = lines.length; i < len; i++) { line = lines[i]; while (/^[ \t]/.test(lines[i + 1])) { line = line + ' ' + lines[i + 1].trim(); i++; } if (!parseHeader(entity, line)) { debugerror('parseEntityHeaders() | invalid MIME header: "%s"', line); return false; } } return true; } function parseHeader(entity, rawHeader) { let match = rawHeader.match(REGEXP_VALID_MIME_HEADER); if (!match) { debugerror('invalid MIME header "%s"', rawHeader); return false; } let name, value, rule, data; name = grammar_1.grammar.headerize(match[1]); value = match[2]; rule = grammar_1.grammar.headerRules[name] || grammar_1.grammar.unknownHeaderRule; try { data = parseHeaderValue(rule, value); } catch (error) { debugerror('wrong MIME header: "%s"', rawHeader); return false; } entity._headers[name] = data; return true; } function parseHeaderValue(rule, value) { let parsedValue, i, len; let data = {}; if (typeof rule.reg !== 'function') { parsedValue = value.match(rule.reg); if (!parsedValue) { throw new Error('parseHeaderValue() failed for ' + value); } for (i = 0, len = rule.names.length; i < len; i++) { if (parsedValue[i + 1] !== undefined) { data[rule.names[i]] = parsedValue[i + 1]; } } } else { data = rule.reg(value); if (!data) { throw new Error('parseHeaderValue() failed for ' + value); } } return data; } exports.parseHeaderValue = parseHeaderValue; //# sourceMappingURL=parse.js.map