making small changes

This commit is contained in:
Brian Whitney 2018-12-15 21:14:46 -05:00
parent c0f4dc6c64
commit 1d0d539797

View file

@ -22,7 +22,7 @@ class Mime {
* Internet MessageFormat constructor * Internet MessageFormat constructor
*/ */
constructor(input) { constructor(input) {
this.input = input; this.mimeObj = Mime._parseMime(input);
} }
/** /**
@ -34,18 +34,18 @@ class Mime {
* @returns {File[]} * @returns {File[]}
*/ */
decodeMime(decodeWords) { decodeMime(decodeWords) {
if (!this.input) { if (!this.mimeObj) {
return []; return [];
} }
const emlObj = Mime._splitParseHead(this.input); //const emlObj = Mime._splitParseHead(this.input);
if (!emlObj.body) { //if (!emlObj.body) {
throw new OperationError("No body was found"); // throw new OperationError("No body was found");
} //}
if (decodeWords) { if (decodeWords) {
emlObj.rawHeader = Mime.replaceEncodedWord(emlObj.rawHeader); emlObj.rawHeader = Mime.replaceEncodedWord(emlObj.rawHeader);
} }
const retval = [new File([emlObj.rawHeader], "Header", {type: "text/plain"})]; //const retval = [new File([emlObj.rawHeader], "Header", {type: "text/plain"})];
let testval = Mime._parseMime(this.input); //let testval = Mime._parseMime(this.input);
testval.forEach(function(fileObj){ testval.forEach(function(fileObj){
let name = fileObj.name; let name = fileObj.name;
if (fileObj.name === null) { if (fileObj.name === null) {
@ -227,15 +227,26 @@ class Mime {
} }
/** /**
* Walks a MIME document and returns an array of Mime data. * Helper function to return objects as an array.
* *
* @param {string} mimeObj
* @returns {object[]} * @returns {object[]}
*/ */
static _parseMime(mimeObj) { toObjArray() {
mimeObj = Mime._splitParseHead(mimeObj); const out = [];
const contType = Mime._decodeComplexField(mimeObj, "content-type"); Mime.walkMime(this.mimeObj, mimePart => out.push(mimePart));
const boundary = Mime._decodeComplexField(mimeObj, "content-type", "boundary"); return out;
}
/**
* Walks a MIME document and returns an array of Mime data.
*
* @param {string} mimeData
* @returns {object}
*/
static _parseMime(mimeData) {
let mimeObj = Mime._splitParseHead(mimeData);
const contType = Mime.decodeComplexField(mimeObj, "content-type");
const boundary = Mime.decodeComplexField(mimeObj, "content-type", "boundary");
if (contType && contType.startsWith("multipart/")) { if (contType && contType.startsWith("multipart/")) {
if (!boundary) { if (!boundary) {
throw new OperationError("Invalid mulitpart section no boundary"); throw new OperationError("Invalid mulitpart section no boundary");
@ -249,28 +260,40 @@ class Mime {
return mimeObj return mimeObj
} }
/**
* Executes methods on a mime object. These methods should modify the mimeObj.
*
* @param {Object} mimeObj
* @param {function[]} methods
* @param {boolean} recursive
* @returns {null}
*/
static walkMime(mimeObj, methods, recursive=true) { static walkMime(mimeObj, methods, recursive=true) {
let contType = Mime._decodeComplexField(mimeObj, "content-type"); let contType = Mime.decodeComplexField(mimeObj, "content-type");
if (contType && contType.startsWith("mulipart/") && recursive) { if (recursive && contType && contType.startsWith("mulitpart/")) {
mimeObj.body.forEach(obj => Mime.walkMime(obj, methods, recursive)); mimeObj.body.forEach(obj => Mime.walkMime(obj, methods));
} else { } else {
methods.forEach(method => method(mimeObj)); methods.forEach(method => method(mimeObj));
} }
} }
/**
* Attempts to decode a mimeObj's data by applying appropriate character and content decoders based on the header data.
*
* @param {Object} mimeObj
* @returns {null}
*/
static decodeMimeMessage(mimeObj) { static decodeMimeMessage(mimeObj) {
let contType = Mime._decodeComplexField(mimeObj, "content-type"), let contType = Mime.decodeComplexField(mimeObj, "content-type"),
charEnc = Mime._decodeComplexField(mimeObj, "content-type", "charset"), charEnc = Mime.decodeComplexField(mimeObj, "content-type", "charset"),
//name = Mime._decodeComplexField(mimeObj, "content-disposition", "filename"), contEnc = Mime.decodeComplexField(mimeObj, "content-transfer-encoding");
//nameAlt = Mime._decodeComplexField(mimeObj, "content-type", "name"),
contEnc = Mime._decodeComplexField(mimeObj, "content-transfer-encoding");
if (contType != null) { if (contType != null) {
if (!charEnc && contType.startsWith("text/")) { if (!charEnc && contType.startsWith("text/")) {
charEnc = "us-ascii"; charEnc = "us-ascii";
} }
} }
if (contEnc && typeof mimeObj.body === "string") { if (contEnc && typeof mimeObj.body === "string") {
mimeObj.body = Mime._decodeMimeData(mimeObj.body, charEnc, contEnc); mimeObj.body = Mime.decodeMimeData(mimeObj.body, charEnc, contEnc);
} }
} }
@ -295,6 +318,7 @@ class Mime {
} }
//TODO: Allow only a header as input
/** /**
* Breaks the header from the body and parses the header. The returns an * Breaks the header from the body and parses the header. The returns an
* object or null. The object contains the raw header, decoded body, and * object or null. The object contains the raw header, decoded body, and
@ -356,7 +380,7 @@ class Mime {
* @param {string} field * @param {string} field
* @returns {string} * @returns {string}
*/ */
static _decodeComplexField(mimeObj, field, subfield="value") { static decodeComplexField(mimeObj, field, subfield="value") {
if (mimeObj.header.hasOwnProperty(field)) { if (mimeObj.header.hasOwnProperty(field)) {
const fieldSplit = mimeObj.header[field][0].split(/;\s+/g); const fieldSplit = mimeObj.header[field][0].split(/;\s+/g);
for (let i = 0; i < fieldSplit.length; i++) { for (let i = 0; i < fieldSplit.length; i++) {
@ -381,6 +405,7 @@ class Mime {
return null; return null;
} }
//TODO: make this a yield instead of string array.
/** /**
* Splits a Mime document by the current boundaries and attempts to account * Splits a Mime document by the current boundaries and attempts to account
* for the current new line size which can be either the standard \r\n or \n. * for the current new line size which can be either the standard \r\n or \n.
@ -394,21 +419,18 @@ class Mime {
const newline = input.indexOf("\r") >= 0 ? "\r\n" : "\n"; const newline = input.indexOf("\r") >= 0 ? "\r\n" : "\n";
const boundaryStr = newline.concat("--", boundary); const boundaryStr = newline.concat("--", boundary);
const last = input.indexOf(newline.concat("--", boundary, "--")); const last = input.indexOf(newline.concat("--", boundary, "--"));
for (;;) { let begin = 0;
let start = input.indexOf(boundaryStr, start); for (let end = 0; end !== last; begin = end) {
if (start < 0) { begin = input.indexOf(boundaryStr, begin);
if (begin < 0) {
break; break;
} }
start += boundaryStr.length; begin += boundaryStr.length;
const end = input.indexOf(boundaryStr, start); end = input.indexOf(boundaryStr, begin);
if (end <= start) { if (end <= begin) {
break; break;
} }
output.push(input.substring(start, end)); output.push(input.substring(begin, end));
if (end === last) {
break;
}
start = end;
} }
return output; return output;
} }