rcs-data
Version:
RCS消息数据结构
153 lines • 5.3 kB
JavaScript
;
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