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

messy

Package Overview
Dependencies
Maintainers
1
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 0.2.1 to 0.3.0

112

lib/Headers.js
var foldHeaderLine = require('./foldHeaderLine'),
formatHeaderName = require('./formatHeaderName');
function Headers(valuesByName) {
function Headers(objectOrString) {
this.valuesByName = {};
if (valuesByName && typeof valuesByName === 'object') {
this.setAll(valuesByName);
}
this.populate(objectOrString);
}
Headers.prototype.populate = function (objectOrString) {
if (typeof objectOrString === 'string') {
this.populateFromString(objectOrString);
} else if (objectOrString && typeof objectOrString === 'object') {
this.setAll(objectOrString);
}
};
Headers.prototype.populateFromString = function (str) {
var that = this,
state = 'startLine',
currentHeaderName = '',
currentValue = '';
function flush() {
if (currentHeaderName.length > 0) {
that.set(currentHeaderName, currentValue);
}
currentHeaderName = '';
currentValue = '';
state = 'startLine';
}
for (var i = 0 ; i < str.length ; i += 1) {
var ch = str[i];
if (state === 'startLine') {
if (ch === ':') {
state = 'startHeaderValue';
} else if (ch === '\r' || ch === '\n') {
// Parse error or terminating CRLFCRLF
if (ch === '\r' && str[i + 1] === '\n' || (ch === '\n' && str[i + 1] === '\r')) {
i += 2;
} else {
i += 1;
}
flush();
return i;
} else {
currentHeaderName += ch;
}
} else if (state === 'startHeaderValue' || state === 'headerValue') {
if (state === 'startHeaderValue') {
if (ch === ' ') {
// Ignore space after :
continue;
} else {
state = 'headerValue';
}
}
if (ch === '\r') {
if (str[i + 1] === '\n') {
if (/[ \t]/.test(str[i + 2])) {
// Skip past CRLF\s fold
i += 2;
} else {
i += 1;
flush();
}
} else if (/[ \t]/.test(str[i + 1])) {
// Skip past CR\s fold
i += 1;
} else {
flush();
}
} else if (ch === '\n') {
if (str[i + 1] === '\r') {
if (/[ \t]/.test(str[i + 2])) {
// Skip past LFCR\s fold
i += 2;
} else {
i += 1;
flush();
}
} else if (/[ \t]/.test(str[i + 1])) {
// Skip past LF\s fold
i += 1;
} else {
flush();
}
} else {
currentValue += ch;
}
}
}
flush();
return i;
};
Headers.prototype.setAll = function (valuesByName) {

@@ -70,2 +156,20 @@ Object.keys(valuesByName).forEach(function (headerName) {

// hasHeader('Content-Length')
// hasHeader('Content-Type', 'text/html');
// hasHeader('Cookie', ['foo=bar', 'baz=quux']);
Headers.prototype.hasHeader = function (headerName, stringOrArray) {
var values = this.valuesByName[headerName.toLowerCase()];
if (typeof stringOrArray === 'undefined') {
return !!values;
} else {
if (Array.isArray(stringOrArray)) {
return stringOrArray.every(function (expectedValue) {
return values.indexOf(String(expectedValue)) !== -1;
});
} else {
return values.length === 1 && values[0] === String(stringOrArray);
}
}
};
Headers.prototype.equals = function (other) {

@@ -72,0 +176,0 @@ var headerNames = this.getNames(),

10

lib/HttpResponse.js

@@ -29,7 +29,7 @@ var Message = require('./Message'),

HttpResponse.prototype.populateStatusLineFromString = function (statusLine) {
var statusLineFragments = statusLine.split(/\s+/);
if (statusLineFragments.length === 3) {
this.protocol = statusLineFragments[0];
this.statusCode = parseInt(statusLineFragments[1], 10);
this.statusMessage = statusLineFragments[2];
var matchStatusLine = statusLine.match(/^(\S+) (\d+) (.+)$/);
if (matchStatusLine) {
this.protocol = matchStatusLine[1];
this.statusCode = parseInt(matchStatusLine[2], 10);
this.statusMessage = matchStatusLine[3];
} else {

@@ -36,0 +36,0 @@ throw new Error('Could not parse status line: ' + statusLine);

@@ -11,3 +11,8 @@ /*global unescape*/

} else if (stringOrObjectOrBuffer && typeof stringOrObjectOrBuffer === 'object') {
this.headers.setAll(stringOrObjectOrBuffer);
if (typeof stringOrObjectOrBuffer.headers !== 'undefined') {
this.headers.populate(stringOrObjectOrBuffer.headers);
}
if (typeof stringOrObjectOrBuffer.body !== 'undefined') {
this.body = stringOrObjectOrBuffer.body;
}
}

@@ -17,25 +22,5 @@ }

Message.prototype.populateFromBuffer = function (buffer) {
var endOfHeadersIndex = 0,
latestLineBreaks = '';
while (endOfHeadersIndex < buffer.length) {
var octet = buffer[endOfHeadersIndex];
if (octet === 0xd || octet === 0xa) { // \r
latestLineBreaks += octet === 0xd ? '\r' : '\n';
if (/\r\r$|\n\n$|\r\n\r\n$|\n\r\n\r$/.test(latestLineBreaks)) {
endOfHeadersIndex += 1;
break;
}
} else {
latestLineBreaks = '';
}
endOfHeadersIndex += 1;
}
if (endOfHeadersIndex < buffer.length) {
this.body = buffer.slice(endOfHeadersIndex);
}
// Hack: Interpret non-ASCII in headers as iso-8859-1:
var str = '';
for (var i = 0 ; i < endOfHeadersIndex ; i += 1) {
for (var i = 0 ; i < buffer.length ; i += 1) {
var octet = buffer[i];

@@ -47,88 +32,18 @@ if (octet > 127) {

}
if (/\r\r$|\n\n$|\r\n\r\n$|\n\r\n\r$/.test(str)) {
i += 1;
if (i < buffer.length) {
this.body = buffer.slice(i);
}
break;
}
}
this.populateFromString(str, true);
this.headers.populateFromString(str, true);
};
Message.prototype.populateFromString = function (str, ignoreBody) {
var that = this,
state = 'startLine',
currentHeaderName = '',
currentValue = '';
function flush() {
if (currentHeaderName.length > 0) {
that.headers.set(currentHeaderName, currentValue);
}
currentHeaderName = '';
currentValue = '';
state = 'startLine';
Message.prototype.populateFromString = function (str) {
var bodyStartIndex = this.headers.populateFromString(str);
if (bodyStartIndex < str.length) {
this.body = str.substr(bodyStartIndex);
}
for (var i = 0 ; i < str.length ; i += 1) {
var ch = str[i];
if (state === 'startLine') {
if (ch === ':') {
state = 'startHeaderValue';
} else if (ch === '\r' || ch === '\n') {
// Parse error or terminating CRLFCRLF
if (!ignoreBody) {
if (ch === '\r' && str[i + 1] === '\n' || (ch === '\n' && str[i + 1] === '\r')) {
if (str.length >= i + 2) {
that.body = str.substr(i + 2);
}
} else {
if (str.length >= i + 1) {
that.body = str.substr(i + 1);
}
}
}
flush();
return;
} else {
currentHeaderName += ch;
}
} else if (state === 'startHeaderValue' || state === 'headerValue') {
if (state === 'startHeaderValue') {
if (ch === ' ') {
// Ignore space after :
continue;
} else {
state = 'headerValue';
}
}
if (ch === '\r') {
if (str[i + 1] === '\n') {
if (/[ \t]/.test(str[i + 2])) {
// Skip past CRLF\s fold
i += 2;
} else {
i += 1;
flush();
}
} else if (/[ \t]/.test(str[i + 1])) {
// Skip past CR\s fold
i += 1;
} else {
flush();
}
} else if (ch === '\n') {
if (str[i + 1] === '\r') {
if (/[ \t]/.test(str[i + 2])) {
// Skip past LFCR\s fold
i += 2;
} else {
i += 1;
flush();
}
} else if (/[ \t]/.test(str[i + 1])) {
// Skip past LF\s fold
i += 1;
} else {
flush();
}
} else {
currentValue += ch;
}
}
}
flush();
};

@@ -135,0 +50,0 @@

{
"name": "messy",
"version": "0.2.1",
"version": "0.3.0",
"description": "Object model for HTTP and RFC822 messages",

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

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

@@ -16,0 +16,0 @@ "keywords": [

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

describe('Headers', function () {
it('should accept a string', function () {
var headers = new Headers('Subject: hey, dude!');
expect(headers.get('subject'), 'to equal', 'hey, dude!');
expect(headers.toString(), 'to equal', 'Subject: hey, dude!\r\n');
});
it('should fold the lines when serializing', function () {

@@ -8,0 +14,0 @@ var headers = new Headers({subject: 'hey there, dude!'});

@@ -14,2 +14,10 @@ /*global describe, it*/

it('should parse a status line with more than one word in the status message', function () {
var httpResponse = new HttpResponse('HTTP/1.1 412 Precondition Failed');
expect(httpResponse.protocol, 'to equal', 'HTTP/1.1');
expect(httpResponse.statusCode, 'to equal', 412);
expect(httpResponse.statusMessage, 'to equal', 'Precondition Failed');
expect(httpResponse.toString(), 'to equal', 'HTTP/1.1 412 Precondition Failed\r\n\r\n');
});
it('should parse a status line followed by headers', function () {

@@ -16,0 +24,0 @@ var httpResponse = new HttpResponse('HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n');

@@ -6,2 +6,16 @@ /*global describe, it*/

describe('Message', function () {
it('should accept an options object with headers and body', function () {
var message = new Message({
headers: {
Received: ['foo', 'bar'],
Subject: 'hey'
},
body: 'abc'
});
expect(message.body, 'to equal', 'abc');
expect(message.headers.getAll('received'), 'to equal', ['foo', 'bar']);
expect(message.headers.getAll('subject'), 'to equal', ['hey']);
expect(message.toString(), 'to equal', 'Received: foo\r\nReceived: bar\r\nSubject: hey\r\n\r\nabc');
});
it('should parse the headers from the input', function () {

@@ -159,4 +173,4 @@ var message = new Message('From: thisguy@example.com\r\nTo: thisotherguy@example.com');

expect(message.body, 'to equal', Buffer.concat([new Buffer('this is the:body', 'utf-8'), new Buffer([0xf8, 0xe6])]));
expect(message.toString(), 'to equal', 'Foo: bar\r\n\r\nthis is the:body��');
expect(message.toString(), 'to equal', 'Foo: bar\r\n\r\nthis is the:body\ufffd\ufffd');
});
});
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