SAP-BTP-Spielwiese/app1/node_modules/http-headers/index.js

138 lines
3.7 KiB
JavaScript
Raw Permalink Normal View History

'use strict'
var nextLine = require('next-line')
// RFC-2068 Start-Line definitions:
// Request-Line: Method SP Request-URI SP HTTP-Version CRLF
// Status-Line: HTTP-Version SP Status-Code SP Reason-Phrase CRLF
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 (data, onlyHeaders) {
return parse(normalize(data), onlyHeaders)
}
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],
url: 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 parseHeaders (str) {
var headers = {}
var next = nextLine(str)
var line = next()
var index, name, value
if (startLine.test(line)) line = next()
while (line) {
// subsequent lines in multi-line headers start with whitespace
if (line[0] === ' ' || line[0] === '\t') {
value += ' ' + line.trim()
line = next()
continue
}
if (name) addHeaderLine(name, value, headers)
index = line.indexOf(':')
name = line.substr(0, index)
value = line.substr(index + 1).trim()
line = next()
}
if (name) addHeaderLine(name, value, headers)
return headers
}
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) {
var nl = str.indexOf('\r\n')
if (nl === -1) return str
else return str.slice(0, nl)
}
// 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
}
}
}