diff --git a/lib/mailparser.js b/lib/mailparser.js index 4ea939a..71c4118 100644 --- a/lib/mailparser.js +++ b/lib/mailparser.js @@ -477,6 +477,9 @@ MailParser.prototype._processHeaderLine = function(pos){ case "content-id": this._currentNode.meta.contentId = this._trimQuotes(value); break; + case "content-location": + this._currentNode.meta.contentLocation = this._trimQuotes(value); + break; } if(this._currentNode.parsedHeaders[key]){ @@ -810,7 +813,7 @@ MailParser.prototype._finalizeContents = function(){ if(!this._currentNode.attachment){ if(this._currentNode.meta.contentType == "text/html"){ - this._currentNode.meta.charset = this._detectHTMLCharset(this._currentNode.content) || this._currentNode.meta.charset || this.options.defaultCharset || "iso-8859-1"; + this._currentNode.meta.charset = this._detectHTMLCharset(this._currentNode.content) || this._currentNode.meta.charset || this.options.defaultCharset || "iso-8859-1"; } if(this._currentNode.meta.transferEncoding == "quoted-printable"){ @@ -888,6 +891,10 @@ MailParser.prototype._processMimeTree = function(){ } htmlLevel = this.mailData.html[i].level; returnValue.html = this.mailData.html[i].content; + + if(this.mailData.html[i].contentLocation){ + returnValue.contentLocation = this.mailData.html[i].contentLocation; + } }else{ if(!returnValue.alternatives){ returnValue.alternatives = []; @@ -967,9 +974,58 @@ MailParser.prototype._processMimeTree = function(){ } } + if(returnValue.contentLocation){ + this._processMHTContentLocation(returnValue); + } + process.nextTick(this.emit.bind(this, "end", returnValue)); }; +/** + *

Replaces content-location values with content-id values (if needed)

+ * + * @param {Object} returnValue Value to be returned with "end" + */ +MailParser.prototype._processMHTContentLocation = function(returnValue){ + var base = returnValue.contentLocation || "", + basePath, + attachmentList = [], + attachment, + absolutePath, + relativePath, + counter = 0; + + if(!returnValue.html){ + return false; + } + + basePath = base.split("/"); + basePath.pop(); + basePath = basePath.join("/")+"/"; + + for(var i=0, len = (returnValue.attachments || []).length; iWalks the mime tree and runs processMimeNode on each node of the tree

* @@ -1009,7 +1065,7 @@ MailParser.prototype._processMimeNode = function(node, level, mimeMultipart){ } } } - this.mailData.html.push({content: this._updateHTMLCharset(node.content || ""), level: level}); + this.mailData.html.push({content: this._updateHTMLCharset(node.content || ""), level: level, contentLocation: node.meta.contentLocation}); return; case "text/plain": this.mailData.text.push({content: node.content || "", level: level}); diff --git a/test/mailparser.js b/test/mailparser.js index 4d81db1..08d7531 100644 --- a/test/mailparser.js +++ b/test/mailparser.js @@ -754,7 +754,7 @@ exports["Transfer encoding"] = { var mailparser = new MailParser(); mailparser.end(mail); mailparser.on("end", function(mail){ - test.equal(mail.text, "=�=�ÄÖÜ="); + test.equal(mail.text, "=�=�ÄÖÜ"); test.done(); }); }, @@ -1190,5 +1190,34 @@ exports["Attachment info"] = { test.equal(mail.attachments && mail.attachments[0] && mail.attachments[0].contentType, "application/pdf"); test.done(); }); + }, + "MHT Content-Location replace": function(test){ + var encodedText = "Content-type: multipart/mixed; boundary=ABC\r\n"+ + "\r\n"+ + "--ABC\r\n"+ + "Content-Type: text/html; charset=utf-8\r\n"+ + "Content-Location: http://www.example.com/index.html\r\n"+ + "Content-Transfer-Encoding: 8bit\r\n"+ + "\r\n"+ + "\r\n"+ + "--ABC\r\n"+ + "Content-Type: image/png\r\n"+ + "Content-Location: http://www.example.com/images/logo.png\r\n"+ + "Content-Transfer-Encoding: base64\r\n"+ + "\r\n"+ + "AAECAwQFBg==\r\n"+ + "--ABC--", + expectedHash = "9aa461e1eca4086f9230aa49c90b0c61", + mail = new Buffer(encodedText, "utf-8"); + + var mailparser = new MailParser(); + + mailparser.write(mail); + mailparser.end(); + + mailparser.on("end", function(mail){ + test.ok(mail.attachments && mail.attachments[0] && mail.attachments[0].contentId && mail.html.indexOf("cid:"+mail.attachments[0].contentId)); + test.done(); + }); } };