Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

messy

Package Overview
Dependencies
Maintainers
2
Versions
73
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

messy - npm Package Compare versions

Comparing version 6.2.0 to 6.3.0

72

lib/HttpRequest.js

@@ -0,4 +1,6 @@

/*global btoa*/
var Message = require('./Message'),
RequestLine = require('./RequestLine'),
util = require('util');
util = require('util'),
_ = require('underscore');

@@ -8,6 +10,7 @@ function HttpRequest(obj) {

this.encrypted = false;
this.port = 80;
Message.call(this, obj);
}
HttpRequest.metadataPropertyNames = ['encrypted', 'cert', 'key', 'ca'];
HttpRequest.metadataPropertyNames = ['host', 'port', 'encrypted', 'cert', 'key', 'ca', 'rejectUnauthorized'];

@@ -31,2 +34,16 @@ HttpRequest.propertyNames = Message.propertyNames.concat(HttpRequest.metadataPropertyNames).concat(RequestLine.propertyNames).concat(['requestLine']);

Message.prototype.populateFromObject.call(this, obj);
if (typeof obj.url === 'string') {
var fragments = obj.url.split(' ');
if (fragments.length > 1) {
this.method = fragments.shift();
}
if (fragments.length > 0) {
this.populateFromUrl(fragments[0]);
obj = _.extend({}, obj);
obj.url = this.path;
}
if (fragments.length > 1) {
this.protocol = fragments[1];
}
}
if (typeof obj.requestLine !== 'undefined') {

@@ -44,2 +61,41 @@ this.requestLine.populate(obj.requestLine);

HttpRequest.prototype.populateFromUrl = function (url) {
var fragments = url.split(' ');
if (fragments.length > 1) {
this.method = fragments.shift();
}
if (fragments.length > 0) {
var matchUrl = fragments[0].match(/^(https?:)\/\/(?:([^:@\/]+(?::[^@\/]+?))@)?((?:[a-z0-9](?:[\-a-z0-9]*[a-z0-9])?\.)+[a-z][\-a-z]*[a-z]|(?:(?:[0-9]|1?[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|1?[0-9][0-9]|2[0-4][0-9]|25[0-5]))(:\d{1,5})?(\/[\w\-\.~%!$&'\(\)*+,;=:@\/]*(?:\?[\w\-\.~%!$&'\(\)*+,;=:@\/?]*)?(?:#[\w\-\.~%!$&'\(\)*+,;=:@\/?#]*)?)?$/);
if (matchUrl) {
var protocol = matchUrl[1],
auth = matchUrl[2],
host = matchUrl[3],
port = matchUrl[4],
path = matchUrl[5];
if (!this.headers.has('Host')) {
this.headers.set('Host', host + (port || ''));
}
this.host = host;
if (typeof port !== 'undefined') {
this.port = parseInt(port.substr(1), 10);
} else if (protocol === 'https:') {
this.port = 443;
}
if (typeof auth !== 'undefined') {
this.headers.set('Authorization', 'Basic ' + (typeof Buffer !== 'undefined' ? new Buffer(auth, 'utf-8').toString('base64') : btoa(auth)));
}
if (protocol === 'https:') {
this.encrypted = true;
}
this.path = path || '/';
} else {
this.path = fragments[0];
}
}
if (fragments.length >= 2) {
this.protocol = fragments[2];
}
};
HttpRequest.prototype.populateFromString = function (str) {

@@ -49,4 +105,14 @@ var matchRequestLine = str.match(/^([^\r\n]*)(\r\n?|\n\r?|$)/);

if (matchRequestLine) {
this.requestLine.populateFromString(matchRequestLine[1]);
Message.prototype.populateFromString.call(this, str.substr(matchRequestLine[0].length));
var requestLineStr = matchRequestLine[1],
requestLineFragments = requestLineStr.split(' ');
if (requestLineFragments.length === 1) {
requestLineFragments.unshift('GET');
}
if (requestLineFragments.length >= 2) {
this.populateFromUrl(requestLineFragments[1]);
requestLineFragments[1] = this.path;
}
requestLineStr = requestLineFragments.join(' ');
this.requestLine.populateFromString(requestLineStr);
}

@@ -53,0 +119,0 @@ return this;

4

lib/HttpResponse.js

@@ -17,3 +17,5 @@ var Message = require('./Message'),

HttpResponse.prototype.populate = function (obj) {
if (obj && typeof obj === 'object' && (typeof Buffer === 'undefined' || !Buffer.isBuffer(obj))) {
if (typeof obj === 'number') {
this.populateFromObject({ statusCode: obj });
} else if (obj && typeof obj === 'object' && (typeof Buffer === 'undefined' || !Buffer.isBuffer(obj))) {
this.populateFromObject(obj);

@@ -20,0 +22,0 @@ } else {

@@ -1,2 +0,2 @@

/*global unescape, btoa, atob*/
/*global unescape, btoa, atob, JSON*/
var Headers = require('./Headers'),

@@ -47,6 +47,14 @@ isRegExp = require('./isRegExp'),

}
if (typeof obj.rawBody !== 'undefined') {
if (typeof obj.parts !== 'undefined') {
this.parts = (Array.isArray(obj.parts) ? obj.parts : [ obj.parts ]).map(function (part) {
return part && part.isMessyMessage ? part : new Message(part);
});
} else if (typeof obj.rawBody !== 'undefined') {
this.rawBody = obj.rawBody;
} else if (typeof obj.body !== 'undefined') {
this.body = obj.body;
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(obj.body)) {
this.unchunkedBody = obj.body;
} else {
this.body = obj.body;
}
} else if (typeof obj.unchunkedBody !== 'undefined') {

@@ -257,2 +265,3 @@ this.unchunkedBody = obj.unchunkedBody;

} else {
var boundary = this.boundary || '';
if (this._bodyMustBeBuffer) {

@@ -265,3 +274,3 @@ var chunks = [];

}
chunks.push(new Buffer('--' + this.boundary + '\r\n'));
chunks.push(new Buffer('--' + boundary + '\r\n'));
var serializedPart = part.serialize();

@@ -274,6 +283,6 @@ if (!Buffer.isBuffer(serializedPart)) {

chunks.push(new Buffer('\r\n--' + this.boundary + '--\r\n'));
chunks.push(new Buffer('\r\n--' + boundary + '--\r\n'));
return Buffer.concat(chunks);
} else {
return '--' + this.boundary + '\r\n' + this._parts.join('\r\n--' + this.boundary + '\r\n') + '\r\n--' + this.boundary + '--\r\n';
return '--' + boundary + '\r\n' + this._parts.join('\r\n--' + boundary + '\r\n') + '\r\n--' + boundary + '--\r\n';
}

@@ -363,26 +372,24 @@ }

if (!this._parts && this.isMultipart) {
var boundary = this.boundary;
if (boundary) {
var bodyAsString;
if (typeof Buffer === 'function' && Buffer.isBuffer(this.body)) {
bodyAsString = this.body.toString('ascii');
} else {
bodyAsString = this.body;
var boundary = this.boundary || '',
bodyAsString;
if (typeof Buffer === 'function' && Buffer.isBuffer(this.body)) {
bodyAsString = this.body.toString('ascii');
} else {
bodyAsString = this.body;
}
var boundaryRegExp = new RegExp('(^|\r\n?|\n\r?)--' + quoteRegExp(boundary) + '(--)?(?:\r\n?|\n\r?|$)', 'g'),
startIndex = -1,
parts = [],
match;
// TODO: Basic validation of end marker etc.
while ((match = boundaryRegExp.exec(bodyAsString))) {
var index = match.index;
if (startIndex !== -1) {
parts.push(new Message(this.body.slice(startIndex, index)));
}
var boundaryRegExp = new RegExp('(^|\r\n?|\n\r?)--' + quoteRegExp(boundary) + '(--)?(?:\r\n?|\n\r?|$)', 'g'),
startIndex = -1,
parts = [],
match;
// TODO: Basic validation of end marker etc.
while ((match = boundaryRegExp.exec(bodyAsString))) {
var index = match.index;
if (startIndex !== -1) {
parts.push(new Message(this.body.slice(startIndex, index)));
}
startIndex = index + match[0].length;
}
if (parts.length > 0) {
this._parts = parts;
}
startIndex = index + match[0].length;
}
if (parts.length > 0) {
this._parts = parts;
}
}

@@ -389,0 +396,0 @@ return this._parts;

@@ -10,3 +10,5 @@ function StatusLine(obj) {

StatusLine.prototype.populate = function (obj) {
if (typeof obj === 'string') {
if (typeof obj === 'number') {
this.populateFromObject({ statusCode: obj });
} else if (typeof obj === 'string') {
this.populateFromString(obj);

@@ -13,0 +15,0 @@ } else if (obj && typeof obj === 'object' && !Buffer.isBuffer(obj)) {

{
"name": "messy",
"version": "6.2.0",
"version": "6.3.0",
"description": "Object model for HTTP and RFC822 messages",

@@ -12,3 +12,3 @@ "main": "lib/index.js",

"test": "mocha && npm run lint",
"travis": "npm test && npm run coverage && <coverage/lcov.info coveralls",
"travis": "npm test && npm run coverage && (<coverage/lcov.info coveralls || true)",
"coverage": "NODE_ENV=development istanbul cover _mocha -- --reporter dot && echo google-chrome coverage/lcov-report/index.html"

@@ -29,7 +29,7 @@ },

"devDependencies": {
"coveralls": "=2.11.1",
"istanbul": "=0.3.0",
"jshint": "=2.5.3",
"mocha": "=1.21.4",
"unexpected": "6.3.1"
"coveralls": "2.11.2",
"istanbul": "0.3.15",
"jshint": "2.8.0",
"mocha": "2.2.5",
"unexpected": "8.0.1"
},

@@ -36,0 +36,0 @@ "dependencies": {

@@ -19,3 +19,3 @@ /*global describe, it*/

expect(httpConversation.exchanges, 'to be a non-empty array whose items satisfy', 'to be an', HttpExchange);
expect(httpConversation.exchanges, 'to have items satisfying', 'to be an', HttpExchange);
expect(

@@ -22,0 +22,0 @@ httpConversation.toString(),

@@ -162,2 +162,118 @@ /*global describe, it*/

});
describe('without a verb in the request line', function () {
it('should assume GET', function () {
expect(new HttpRequest('/foo'), 'to satisfy', {
method: 'GET',
path: '/foo'
});
});
});
it('should accept host and port as options', function () {
expect(new HttpRequest({ host: 'foo.com', port: 987 }), 'to have properties', {
host: 'foo.com',
port: 987
});
});
describe('with a url passed in the request line', function () {
it('should set the Host header', function () {
var httpRequest = new HttpRequest('GET http://foo.com/');
expect(httpRequest.headers.get('Host'), 'to equal', 'foo.com');
});
it('should set the host property', function () {
expect(new HttpRequest('GET http://foo.com/').host, 'to equal', 'foo.com');
});
it('should set the port property when explicitly given', function () {
expect(new HttpRequest('GET http://foo.com:987/').port, 'to equal', 987);
});
it('should set the port property to 80 when http', function () {
expect(new HttpRequest('GET http://foo.com/').port, 'to equal', 80);
});
it('should set the port property to 443 when https', function () {
expect(new HttpRequest('GET https://foo.com/').port, 'to equal', 443);
});
it('should set the path', function () {
expect(new HttpRequest('GET http://foo.com/heythere/you').path, 'to equal', '/heythere/you');
});
it('should set the Host header and include the port if given', function () {
var httpRequest = new HttpRequest('GET http://foo.com:987/');
expect(httpRequest.headers.get('Host'), 'to equal', 'foo.com:987');
});
it('should not overwrite an explicit Host header', function () {
var httpRequest = new HttpRequest('GET http://foo.com/\r\nHost: bar.com');
expect(httpRequest.headers.get('Host'), 'to equal', 'bar.com');
});
it('should set the "encrypted" property if the protocol is https', function () {
expect(new HttpRequest('GET https://foo.com/'), 'to satisfy', { encrypted: true });
});
it('should not set the "encrypted" property if the protocol is http', function () {
expect(new HttpRequest('GET http://foo.com/'), 'to satisfy', { encrypted: expect.it('to be falsy') });
});
it('should set the Authorization header if credentials are passed in the url', function () {
var httpRequest = new HttpRequest('GET https://foo:bar@foo.com/');
expect(httpRequest.headers.get('Authorization'), 'to equal', 'Basic Zm9vOmJhcg==');
});
});
describe('with a url passed in an options object', function () {
it('should set the Host header', function () {
var httpRequest = new HttpRequest({ url: 'GET http://foo.com/' });
expect(httpRequest.headers.get('Host'), 'to equal', 'foo.com');
});
it('should set the host property', function () {
expect(new HttpRequest({ url: 'GET http://foo.com/' }).host, 'to equal', 'foo.com');
});
it('should set the port property when explicitly given', function () {
expect(new HttpRequest({ url: 'GET http://foo.com:987/' }).port, 'to equal', 987);
});
it('should set the port property to 80 when http', function () {
expect(new HttpRequest({ url: 'GET http://foo.com/' }).port, 'to equal', 80);
});
it('should set the port property to 443 when https', function () {
expect(new HttpRequest({ url: 'GET https://foo.com/' }).port, 'to equal', 443);
});
it('should set the path', function () {
expect(new HttpRequest({ url: 'GET http://foo.com/heythere/you' }).path, 'to equal', '/heythere/you');
});
it('should set the Host header and include the port if given', function () {
var httpRequest = new HttpRequest({ url: 'GET http://foo.com:987/' });
expect(httpRequest.headers.get('Host'), 'to equal', 'foo.com:987');
});
it('should not overwrite an explicit Host header', function () {
var httpRequest = new HttpRequest({ url: 'GET http://foo.com/', headers: { Host: 'bar.com' } });
expect(httpRequest.headers.get('Host'), 'to equal', 'bar.com');
});
it('should set the "encrypted" property if the protocol is https', function () {
expect(new HttpRequest({ url: 'GET https://foo.com/' }), 'to satisfy', { encrypted: true });
});
it('should not set the "encrypted" property if the protocol is http', function () {
expect(new HttpRequest({ url: 'GET http://foo.com/' }), 'to satisfy', { encrypted: expect.it('to be falsy') });
});
it('should set the Authorization header if credentials are passed in the url', function () {
var httpRequest = new HttpRequest({ url: 'GET https://foo:bar@foo.com/' });
expect(httpRequest.headers.get('Authorization'), 'to equal', 'Basic Zm9vOmJhcg==');
});
});
});

@@ -43,2 +43,8 @@ /*global describe, it*/

it('should accept a number and interpret it as the status code', function () {
expect(new HttpResponse(404), 'to have properties', {
statusCode: 404
});
});
it('should parse a partial status line', function () {

@@ -45,0 +51,0 @@ expect(new HttpResponse('HTTP/1.1 200'), 'to have properties', {

@@ -169,2 +169,7 @@ /*global describe, it*/

it('should treat a body passed as a Buffer as the unchunked body', function () {
var message = new Message({ body: new Buffer([0xff]) });
expect(message._unchunkedBody, 'to equal', new Buffer([0xff]));
});
describe('#hasEmptyBody', function () {

@@ -229,2 +234,75 @@ it('should consider a zero length Buffer to be an empty body', function () {

describe('with parts passed to the constructor', function () {
it('should accept both messy.Message instances and valid constructor arguments ', function () {
var message = new Message({
headers: 'Content-Type: multipart/mixed',
parts: [
new Message('Content-Type: text/html\r\n\r\n<h1>Hello, world!</h1>'),
{ headers: 'Content-Type: text/plain', body: 'Hello, world!' },
'Content-Type: text/foo\r\n\r\nhey'
]
});
expect(message.parts.length, 'to equal', 3);
expect(
message.toString(),
'to equal',
'Content-Type: multipart/mixed\r\n' +
'\r\n' +
'--\r\n' +
'Content-Type: text/html\r\n' +
'\r\n' +
'<h1>Hello, world!</h1>\r\n' +
'--\r\n' +
'Content-Type: text/plain\r\n' +
'\r\n' +
'Hello, world!\r\n' +
'--\r\n' +
'Content-Type: text/foo\r\n' +
'\r\n' +
'hey\r\n' +
'----\r\n'
);
});
it('should pick up the boundary with boundary', function () {
var message = new Message({
headers: 'Content-Type: multipart/mixed; boundary=foo',
parts: [
new Message('Content-Type: text/html\r\n\r\n<h1>Hello, world!</h1>')
]
});
expect(message.parts.length, 'to equal', 1);
expect(
message.toString(),
'to equal',
'Content-Type: multipart/mixed; boundary=foo\r\n' +
'\r\n' +
'--foo\r\n' +
'Content-Type: text/html\r\n' +
'\r\n' +
'<h1>Hello, world!</h1>\r\n' +
'--foo--\r\n'
);
});
it('should allow passing a single part', function () {
var message = new Message({
headers: 'Content-Type: multipart/mixed; boundary=foo',
parts: new Message('Content-Type: text/html\r\n\r\n<h1>Hello, world!</h1>')
});
expect(message.parts.length, 'to equal', 1);
expect(
message.toString(),
'to equal',
'Content-Type: multipart/mixed; boundary=foo\r\n' +
'\r\n' +
'--foo\r\n' +
'Content-Type: text/html\r\n' +
'\r\n' +
'<h1>Hello, world!</h1>\r\n' +
'--foo--\r\n'
);
});
});
describe('with a multipart body', function () {

@@ -533,2 +611,7 @@ var src =

});
it('should decode application/x-www-form-urlencoded as text', function () {
var src = new Buffer('Content-Type: application/x-www-form-urlencoded\n\nfoo=bar&data=%5B%22foo.txt%22%5D', 'ascii');
expect(new Message(src).body, 'to equal', 'foo=bar&data=%5B%22foo.txt%22%5D');
});
});

@@ -535,0 +618,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc