Comparing version 3.1.3 to 3.2.0
@@ -12,2 +12,10 @@ var foldHeaderLine = require('./foldHeaderLine'), | ||
Headers.prototype.serializeHeaderValue = function (parsedHeaderValue) { | ||
return parsedHeaderValue; | ||
}; | ||
Headers.prototype.parseHeaderValue = function (serializedHeaderValue) { | ||
return String(serializedHeaderValue); | ||
}; | ||
Headers.prototype.populate = function (obj, doNotStringify) { | ||
@@ -115,3 +123,5 @@ if (typeof obj === 'string') { | ||
if (!doNotStringify) { | ||
value = value.map(String); | ||
value = value.map(function (serializedHeaderValue) { | ||
return this.parseHeaderValue(serializedHeaderValue); | ||
}, this); | ||
} | ||
@@ -128,3 +138,3 @@ if (this.valuesByName[headerNameLowerCase]) { | ||
if (!doNotStringify) { | ||
value = String(value); | ||
value = this.parseHeaderValue(value); | ||
} | ||
@@ -175,6 +185,8 @@ if (this.valuesByName[headerNameLowerCase]) { | ||
} else { | ||
this.valuesByName[headerNameLowerCase] = valueOrValues.map(String); | ||
this.valuesByName[headerNameLowerCase] = valueOrValues.map(function (value) { | ||
return this.parseHeaderValue(value); | ||
}, this); | ||
} | ||
} else { | ||
(this.valuesByName[headerNameLowerCase] = this.valuesByName[headerNameLowerCase] || []).push(String(valueOrValues)); | ||
(this.valuesByName[headerNameLowerCase] = this.valuesByName[headerNameLowerCase] || []).push(this.parseHeaderValue(valueOrValues)); | ||
} | ||
@@ -303,4 +315,4 @@ }; | ||
this.valuesByName[lowerCaseHeaderName].forEach(function (value) { | ||
result += formatHeaderName(lowerCaseHeaderName) + ': ' + foldHeaderLine(value, maxLineLength, maxLineLength - lowerCaseHeaderName.length - 2) + '\r\n'; | ||
}); | ||
result += formatHeaderName(lowerCaseHeaderName) + ': ' + foldHeaderLine(this.serializeHeaderValue(value), maxLineLength, maxLineLength - lowerCaseHeaderName.length - 2) + '\r\n'; | ||
}, this); | ||
}, this); | ||
@@ -307,0 +319,0 @@ return result; |
/*global unescape*/ | ||
var Headers = require('./Headers'), | ||
isRegExp = require('./isRegExp'); | ||
isRegExp = require('./isRegExp'), | ||
rfc2231 = require('rfc2231'); | ||
@@ -10,3 +11,3 @@ function quoteRegExp(str) { | ||
function Message(obj) { | ||
this.headers = new Headers(); | ||
this.headers = new this.HeadersConstructor(); | ||
this.populate(obj); | ||
@@ -17,2 +18,4 @@ } | ||
Message.prototype.HeadersConstructor = Headers; | ||
Message.prototype.populate = function (obj) { | ||
@@ -36,3 +39,2 @@ if (typeof Buffer === 'function' && Buffer.isBuffer(obj)) { | ||
} | ||
this.populateMultipartBody(); | ||
return this; | ||
@@ -60,3 +62,2 @@ }; | ||
this.headers.populateFromString(str, true); | ||
this.populateMultipartBody(); | ||
return this; | ||
@@ -70,3 +71,2 @@ }; | ||
} | ||
this.populateMultipartBody(); | ||
return this; | ||
@@ -123,2 +123,48 @@ }; | ||
Object.defineProperty(Message.prototype, 'fileName', { | ||
get: function () { | ||
var contentDisposition = this.headers.get('Content-Disposition'); | ||
if (contentDisposition) { | ||
var tokens = contentDisposition.split(/\s*;\s*/), | ||
parameters = {}; | ||
for (var i = 1 ; i < tokens.length ; i += 1) { | ||
var matchKeyValue = tokens[i].match(/^([^=]+)=(.*)$/); | ||
if (matchKeyValue && !(matchKeyValue[1] in parameters)) { | ||
parameters[matchKeyValue[1]] = matchKeyValue[2]; | ||
} else { | ||
return; | ||
} | ||
} | ||
var decodedParameters = rfc2231.unfoldAndDecodeParameters(parameters); | ||
if (decodedParameters.filename) { | ||
return decodedParameters.filename; | ||
} | ||
} | ||
// TODO: Try falling back to the name attribute of the Content-Type header | ||
}, | ||
set: function (fileName) { | ||
var contentDisposition = this.headers.get('Content-Disposition') || 'attachment'; | ||
if (contentDisposition) { | ||
var tokens = contentDisposition.split(/\s*;\s*/), | ||
tokensAfterUpdate = [tokens[0]]; | ||
for (var i = 1 ; i < tokens.length ; i += 1) { | ||
var matchKeyValue = tokens[i].match(/^([^=]+)=.*$/); | ||
if (matchKeyValue) { | ||
if (!/^filename(?:\*\d*)$/.test(matchKeyValue[1])) { | ||
tokensAfterUpdate.push(tokens[i]); | ||
} | ||
} else { | ||
throw new Error('Cannot set fileName due to unparseable token ' + tokens[i]); | ||
} | ||
} | ||
var folded = rfc2231.encodeAndFoldParameters({filename: fileName}); | ||
Object.keys(folded).forEach(function (parameterName) { | ||
tokensAfterUpdate.push(parameterName + '=' + folded[parameterName]); | ||
}); | ||
this.headers.set('Content-Disposition', tokensAfterUpdate.join('; ')); | ||
} | ||
// TODO: Update the name attribute of the Content-Type header | ||
} | ||
}); | ||
function buffersEqual(a, b) { | ||
@@ -125,0 +171,0 @@ if (a === b) { |
{ | ||
"name": "messy", | ||
"version": "3.1.3", | ||
"version": "3.2.0", | ||
"description": "Object model for HTTP and RFC822 messages", | ||
@@ -35,4 +35,6 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"rfc2047": "1.0.0", | ||
"rfc2231": "1.1.0", | ||
"underscore": "^1.6.0" | ||
} | ||
} |
@@ -99,12 +99,2 @@ /*global describe, it*/ | ||
it.skip('should rfc2047 decode the header values', function () { | ||
expect(new Message('Subject: =?iso-8859-1?Q?=A1?=Hola, se=?iso-8859-1?Q?=F1?=or!').get('subject'), 'to equal', '¡Hola, señor!'); | ||
}); | ||
it.skip('should rfc2047 encode when serializing', function () { | ||
var message = new Message(); | ||
message.set('subject', '¡Hola, señor!'); | ||
expect(message.toString(), 'to equal', 'Subject: =?iso-8859-1?Q?=A1?=Hola, se=?iso-8859-1?Q?=F1?=or!\r\n\r\n'); | ||
}); | ||
it('should produce an empty string when handed an empty buffer', function () { | ||
@@ -234,2 +224,4 @@ expect(new Message(new Buffer(0)).toString(), 'to equal', ''); | ||
message.populateMultipartBody(); | ||
expect(message.body, 'to equal', [ | ||
@@ -244,3 +236,7 @@ new Message(new Buffer('Content-Disposition: form-data; name="recipient"\r\n\r\nandreas@one.com', 'utf-8')), | ||
it('should decode the multipart parts when the body is passed as a string', function () { | ||
expect(new Message(src).body, 'to equal', [ | ||
var message = new Message(src); | ||
message.populateMultipartBody(); | ||
expect(message.body, 'to equal', [ | ||
new Message('Content-Disposition: form-data; name="recipient"\r\n\r\nandreas@one.com'), | ||
@@ -253,2 +249,36 @@ new Message('Content-Disposition: form-data; name="Name "\r\n\r\nThe name'), | ||
}); | ||
it('should support a fileName getter which automatically rfc2231 decodes the Content-Disposition filename', function () { | ||
var message = new Message( | ||
'Content-Disposition: attachment;\r\n' + | ||
' filename*0*=utf-8\'\'%72%C3%A6%61%6C%6C%79%20%73%63%72%65%77%65%64%20%75;\r\n' + | ||
' filename*1*=%70%20%6C%6F%6E%67%20%61%74%74%61%63%68%6D%65%6E%74%20%66%69;\r\n' + | ||
' filename*2*=%6C%65%6E%61%6D%65%20%77%69%74%68%20%73%6D%69%6C%65%79%73%E2;\r\n' + | ||
' filename*3*=%98%BA%20%61%6E%64%20%E2%98%BA%61%6E%64%20%C2%A1%48%6F%6C%61;\r\n' + | ||
' filename*4*=%2C%20%73%65%C3%B1%6F%72%21%20%61%6E%64%20%66%6F%72%65%69%67;\r\n' + | ||
' filename*5*=%6E%20%77%65%69%72%64%6E%65%73%73%D7%9D%D7%95%D7%9C%D7%A9%20;\r\n' + | ||
' filename*6*=%D7%9F%D7%91%20%D7%99%D7%9C%D7%98%D7%A4%D7%A0%20%69%6E%20%69;\r\n' + | ||
' filename*7*=%74%2E%E2%98%BA'); | ||
expect(message.fileName, 'to equal', 'ræally screwed up long attachment filename with smileys☺ and ☺and ¡Hola, señor! and foreign weirdnessםולש ןב ילטפנ in it.☺'); | ||
}); | ||
it('should support a fileName setter which updates the Content-Disposition filename with the rfc2231 encoded representation', function () { | ||
var message = new Message({body: 'bar'}); | ||
message.fileName = 'ræally screwed up long attachment filename with smileys☺ and ☺and ¡Hola, señor! and foreign weirdnessםולש ןב ילטפנ in it.☺'; | ||
expect( | ||
message.toString(), | ||
'to equal', | ||
'Content-Disposition: attachment;\r\n' + | ||
' filename*0*=utf-8\'\'%72%C3%A6%61%6C%6C%79%20%73%63%72%65%77%65%64%20%75;\r\n' + | ||
' filename*1*=%70%20%6C%6F%6E%67%20%61%74%74%61%63%68%6D%65%6E%74%20%66%69;\r\n' + | ||
' filename*2*=%6C%65%6E%61%6D%65%20%77%69%74%68%20%73%6D%69%6C%65%79%73%E2;\r\n' + | ||
' filename*3*=%98%BA%20%61%6E%64%20%E2%98%BA%61%6E%64%20%C2%A1%48%6F%6C%61;\r\n' + | ||
' filename*4*=%2C%20%73%65%C3%B1%6F%72%21%20%61%6E%64%20%66%6F%72%65%69%67;\r\n' + | ||
' filename*5*=%6E%20%77%65%69%72%64%6E%65%73%73%D7%9D%D7%95%D7%9C%D7%A9%20;\r\n' + | ||
' filename*6*=%D7%9F%D7%91%20%D7%99%D7%9C%D7%98%D7%A4%D7%A0%20%69%6E%20%69;\r\n' + | ||
' filename*7*=%74%2E%E2%98%BA\r\n' + | ||
'\r\n' + | ||
'bar' | ||
); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
88571
29
1887
3
+ Addedrfc2047@1.0.0
+ Addedrfc2231@1.1.0
+ Addediconv-lite@0.4.5(transitive)
+ Addedrfc2047@1.0.0(transitive)
+ Addedrfc2231@1.1.0(transitive)