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

http-headers

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

http-headers - npm Package Compare versions

Comparing version 1.2.0 to 2.0.0

112

index.js
'use strict'
var strip = require('strip-lines')
var nextLine = require('next-line')

@@ -10,16 +9,35 @@

var startLine = /^[A-Z_]+(\/\d\.\d)? /
var requestLine = /^([A-Z_]+) (.+) [A-Z]+\/(\d)\.(\d)$/
var statusLine = /^[A-Z]+\/(\d)\.(\d) (\d{3}) (.*)$/
module.exports = function (str) {
return parse(normalize(str))
module.exports = function (data, onlyHeaders) {
return parse(normalize(data), onlyHeaders)
}
function normalize (str) {
if (str && str._header) str = str._header // extra headers from http.ServerResponse object
if (!str || typeof str.toString !== 'function') return ''
str = str.toString().trim()
if (startLine.test(str)) str = strip(str, 1)
return str
function parse (str, onlyHeaders) {
var line = firstLine(str)
var match
if (onlyHeaders && startLine.test(line)) {
return parseHeaders(str)
} else if ((match = line.match(requestLine)) !== null) {
return {
method: match[1],
path: match[2],
version: { major: parseInt(match[3], 10), minor: parseInt(match[4], 10) },
headers: parseHeaders(str)
}
} else if ((match = line.match(statusLine)) !== null) {
return {
version: { major: parseInt(match[1], 10), minor: parseInt(match[2], 10) },
statusCode: parseInt(match[3], 10),
statusMessage: match[4],
headers: parseHeaders(str)
}
} else {
return parseHeaders(str)
}
}
function parse (str) {
function parseHeaders (str) {
var headers = {}

@@ -30,2 +48,4 @@ var next = nextLine(str)

if (startLine.test(line)) line = next()
while (line) {

@@ -39,3 +59,3 @@ // subsequent lines in multi-line headers start with whitespace

if (name) addMessageHeader()
if (name) addHeaderLine(name, value, headers)

@@ -49,11 +69,71 @@ index = line.indexOf(':')

if (name) addMessageHeader()
if (name) addHeaderLine(name, value, headers)
return headers
}
function addMessageHeader () {
name = name.toLowerCase()
if (name in headers) headers[name] += ', ' + value
else headers[name] = value
function normalize (str) {
if (str && str._header) str = str._header // extra headers from http.ServerResponse object
if (!str || typeof str.toString !== 'function') return ''
return str.toString().trim()
}
function firstLine (str) {
return str.slice(0, str.indexOf('\r\n'))
}
// The following function is lifted from:
// https://github.com/nodejs/node/blob/f1294f5bfd7f02bce8029818be9c92de59749137/lib/_http_incoming.js#L116-L170
//
// Add the given (field, value) pair to the message
//
// Per RFC2616, section 4.2 it is acceptable to join multiple instances of the
// same header with a ', ' if the header in question supports specification of
// multiple values this way. If not, we declare the first instance the winner
// and drop the second. Extended header fields (those beginning with 'x-') are
// always joined.
function addHeaderLine (field, value, dest) {
field = field.toLowerCase()
switch (field) {
// Array headers:
case 'set-cookie':
if (dest[field] !== undefined) {
dest[field].push(value)
} else {
dest[field] = [value]
}
break
// list is taken from:
// https://mxr.mozilla.org/mozilla/source/netwerk/protocol/http/src/nsHttpHeaderArray.cpp
case 'content-type':
case 'content-length':
case 'user-agent':
case 'referer':
case 'host':
case 'authorization':
case 'proxy-authorization':
case 'if-modified-since':
case 'if-unmodified-since':
case 'from':
case 'location':
case 'max-forwards':
case 'retry-after':
case 'etag':
case 'last-modified':
case 'server':
case 'age':
case 'expires':
// drop duplicates
if (dest[field] === undefined) dest[field] = value
break
default:
// make comma-separated list
if (typeof dest[field] === 'string') {
dest[field] += ', ' + value
} else {
dest[field] = value
}
}
}

9

package.json
{
"name": "http-headers",
"version": "1.2.0",
"version": "2.0.0",
"description": "Parse http headers",

@@ -14,4 +14,3 @@ "main": "index.js",

"dependencies": {
"next-line": "^1.0.0",
"strip-lines": "^1.0.1"
"next-line": "^1.0.0"
},

@@ -39,5 +38,5 @@ "devDependencies": {

"coordinates": [
55.68773059999999,
12.5956059
55.6876679,
12.5955582
]
}

@@ -6,7 +6,7 @@ # http-headers

Extract and parse headers from an HTTP request or reponse.
Parse the start-line and headers from an HTTP request or reponse.
Converts:
```
```http
HTTP/1.1 200 OK

@@ -23,5 +23,12 @@ Date: Tue, 10 Jun 2014 07:19:27 GMT

```js
{ date: 'Tue, 10 Jun 2014 07:19:27 GMT',
connection: 'keep-alive',
'transfer-encoding': 'chunked' }
{
version: { major: 1, minor: 1 },
statusCode: 200,
statusMessage: 'OK',
headers: {
date: 'Tue, 10 Jun 2014 07:19:27 GMT',
connection: 'keep-alive',
'transfer-Encoding': 'chunked'
}
}
```

@@ -31,3 +38,2 @@

- Auto-detects and ignores HTTP start-line if present
- Auto-detects and ignores body if present

@@ -38,3 +44,3 @@ - Fully [RFC 2068](http://www.rfc-base.org/txt/rfc-2068.txt) compliant

- Support multi-line headers (lines will be joined with a space)
- Support repeating headers (values will be joined with `, `)
- Support repeating headers

@@ -44,3 +50,3 @@ ## Installation

```
npm install http-headers
npm install http-headers --save
```

@@ -62,3 +68,3 @@

// parse incoming data as an HTTP request and extra HTTP headers
console.log('Request headers:', httpHeaders(data))
console.log(httpHeaders(data))
})

@@ -79,3 +85,3 @@ }).listen(8080)

res.end('Hello World')
console.log('Response headers:', httpHeaders(res))
console.log(httpHeaders(res))
}).listen(8080)

@@ -102,11 +108,106 @@ ```

```js
httpHeaders(data[, onlyHeaders])
```
httpHeaders([ string | buffer | http.ServerReponse ])
Arguments:
- `data` - A string, buffer or instance of `http.ServerReponse`
- `onlyHeaders` - An optional boolean. If `true`, only the headers
object will be returned. Defaults to `false`
### Request example
If given a request as input:
```http
GET /foo HTTP/1.1
Date: Tue, 10 Jun 2014 07:19:27 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Hello World
```
The module returns a JavaScript object with each element representing a
parsed header. All header names are lowercased.
Returns:
```js
{
method: 'GET',
path: '/foo',
version: { major: 1, minor: 1 },
headers: {
date: 'Tue, 10 Jun 2014 07:19:27 GMT',
connection: 'keep-alive',
'transfer-Encoding': 'chunked'
}
}
```
### Response example
If given a request as input:
```http
HTTP/1.1 200 OK
Date: Tue, 10 Jun 2014 07:19:27 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Hello World
```
Returns:
```js
{
version: { major: 1, minor: 1 },
statusCode: 200,
statusMessage: 'OK',
headers: {
date: 'Tue, 10 Jun 2014 07:19:27 GMT',
connection: 'keep-alive',
'transfer-Encoding': 'chunked'
}
}
```
### `onlyHeaders` example
If the optional second argument is set to `true`, only headers are
returned no matter the type of input:
```js
{
date: 'Tue, 10 Jun 2014 07:19:27 GMT',
connection: 'keep-alive',
'transfer-Encoding': 'chunked'
}
```
### No Start-Line
If the `data` given does not contain an HTTP Start-Line, only the
headers are returned, even if the `onlyHeaders` argument is `false`:
```http
Date: Tue, 10 Jun 2014 07:19:27 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Hello World
```
Returns:
```js
{
date: 'Tue, 10 Jun 2014 07:19:27 GMT',
connection: 'keep-alive',
'transfer-Encoding': 'chunked'
}
```
## License
MIT

@@ -12,2 +12,5 @@ 'use strict'

'Transfer-Encoding: chunked\r\n' +
'Age: foo\r\n' +
'Age: bar\r\n' +
'Set-Cookie: cookie\r\n' +
'X-List: A\r\n' +

@@ -21,12 +24,27 @@ 'X-Multi-Line-Header: Foo\r\n' +

var result = {
var headerResult = {
date: 'Tue, 10 Jun 2014 07:29:20 GMT',
connection: 'keep-alive',
'transfer-encoding': 'chunked',
age: 'foo',
'set-cookie': ['cookie'],
'x-list': 'A, B',
'x-multi-line-header': 'Foo Bar'
}
var responseResult = {
version: { major: 1, minor: 1 },
statusCode: 200,
statusMessage: 'OK',
headers: headerResult
}
var requestResult = {
method: 'GET',
path: '/foo',
version: { major: 1, minor: 1 },
headers: headerResult
}
test('no argument', function (t) {
t.deepEqual(httpHeaders(), {})
t.deepEqual(httpHeaders(undefined, true), {})
t.end()

@@ -37,2 +55,3 @@ })

t.deepEqual(httpHeaders(''), {})
t.deepEqual(httpHeaders('', true), {})
t.end()

@@ -43,2 +62,3 @@ })

t.deepEqual(httpHeaders({}), {})
t.deepEqual(httpHeaders({}, true), {})
t.end()

@@ -49,2 +69,3 @@ })

t.deepEqual(httpHeaders(new Buffer('')), {})
t.deepEqual(httpHeaders(new Buffer(''), true), {})
t.end()

@@ -54,6 +75,10 @@ })

test('start-line + header', function (t) {
t.deepEqual(httpHeaders(requestLine + msgHeaders), result)
t.deepEqual(httpHeaders(statusLine + msgHeaders), result)
t.deepEqual(httpHeaders(new Buffer(requestLine + msgHeaders)), result)
t.deepEqual(httpHeaders(new Buffer(statusLine + msgHeaders)), result)
t.deepEqual(httpHeaders(requestLine + msgHeaders), requestResult)
t.deepEqual(httpHeaders(statusLine + msgHeaders), responseResult)
t.deepEqual(httpHeaders(new Buffer(requestLine + msgHeaders)), requestResult)
t.deepEqual(httpHeaders(new Buffer(statusLine + msgHeaders)), responseResult)
t.deepEqual(httpHeaders(requestLine + msgHeaders, true), headerResult)
t.deepEqual(httpHeaders(statusLine + msgHeaders, true), headerResult)
t.deepEqual(httpHeaders(new Buffer(requestLine + msgHeaders), true), headerResult)
t.deepEqual(httpHeaders(new Buffer(statusLine + msgHeaders), true), headerResult)
t.end()

@@ -63,4 +88,6 @@ })

test('headers only', function (t) {
t.deepEqual(httpHeaders(msgHeaders), result)
t.deepEqual(httpHeaders(new Buffer(msgHeaders)), result)
t.deepEqual(httpHeaders(msgHeaders), headerResult)
t.deepEqual(httpHeaders(new Buffer(msgHeaders)), headerResult)
t.deepEqual(httpHeaders(msgHeaders, true), headerResult)
t.deepEqual(httpHeaders(new Buffer(msgHeaders), true), headerResult)
t.end()

@@ -70,6 +97,10 @@ })

test('full http response', function (t) {
t.deepEqual(httpHeaders(requestMsg), result)
t.deepEqual(httpHeaders(responseMsg), result)
t.deepEqual(httpHeaders(new Buffer(requestMsg)), result)
t.deepEqual(httpHeaders(new Buffer(responseMsg)), result)
t.deepEqual(httpHeaders(requestMsg), requestResult)
t.deepEqual(httpHeaders(responseMsg), responseResult)
t.deepEqual(httpHeaders(new Buffer(requestMsg)), requestResult)
t.deepEqual(httpHeaders(new Buffer(responseMsg)), responseResult)
t.deepEqual(httpHeaders(requestMsg, true), headerResult)
t.deepEqual(httpHeaders(responseMsg, true), headerResult)
t.deepEqual(httpHeaders(new Buffer(requestMsg), true), headerResult)
t.deepEqual(httpHeaders(new Buffer(responseMsg), true), headerResult)
t.end()

@@ -82,2 +113,3 @@ })

t.deepEqual(httpHeaders(res), {})
t.deepEqual(httpHeaders(res, true), {})
t.end()

@@ -88,2 +120,3 @@ })

t.deepEqual(httpHeaders({ _header: undefined }), {})
t.deepEqual(httpHeaders({ _header: undefined }, true), {})
t.end()

@@ -94,2 +127,3 @@ })

t.deepEqual(httpHeaders({ _header: '' }), {})
t.deepEqual(httpHeaders({ _header: '' }, true), {})
t.end()

@@ -99,5 +133,12 @@ })

t.test('normal _header property', function (t) {
t.deepEqual(httpHeaders({ _header: statusLine + msgHeaders }), result)
t.deepEqual(httpHeaders({ _header: statusLine + msgHeaders }), responseResult)
t.deepEqual(httpHeaders({ _header: statusLine + msgHeaders }, true), headerResult)
t.end()
})
})
test('set-cookie', function (t) {
t.deepEqual(httpHeaders('Set-Cookie: foo'), { 'set-cookie': ['foo'] })
t.deepEqual(httpHeaders('Set-Cookie: foo\r\nSet-Cookie: bar'), { 'set-cookie': ['foo', 'bar'] })
t.end()
})

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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