diff --git a/lib/core/request.js b/lib/core/request.js index c6d887d3fd5..936e11d8db1 100644 --- a/lib/core/request.js +++ b/lib/core/request.js @@ -410,145 +410,74 @@ function processHeader (request, key, val, skipAppend = false) { return } - const mayBeLowerCasedKey = headerNameLowerCasedRecord[key] - - if (mayBeLowerCasedKey !== undefined) { - switch (mayBeLowerCasedKey) { - case 'host': { - if (request.host !== null) break - if (headerCharRegex.exec(val) !== null) { - throw new InvalidArgumentError(`invalid ${key} header`) - } - // Consumed by Client - request.host = val - return - } - case 'content-length': { - if (request.contentLength !== null) break - request.contentLength = parseInt(val, 10) - if (!Number.isFinite(request.contentLength)) { - throw new InvalidArgumentError('invalid content-length header') - } - return - } - case 'content-type': { - if (request.contentType !== null) break - request.contentType = val - if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) - else request.headers += processHeaderValue(key, val) - return - } - case 'transfer-encoding': { - throw new InvalidArgumentError('invalid transfer-encoding header') - } - case 'connection': { - const value = typeof val === 'string' ? val.toLowerCase() : null - if (value !== 'close' && value !== 'keep-alive') { - throw new InvalidArgumentError('invalid connection header') - } else if (value === 'close') { - request.reset = true - } - return - } - case 'keep-alive': { - throw new InvalidArgumentError('invalid keep-alive header') - } - case 'upgrade': { - throw new InvalidArgumentError('invalid upgrade header') - } - case 'expect': { - throw new NotSupportedError('expect header not supported') + let headerName = headerNameLowerCasedRecord[key] + + if (headerName === undefined) { + headerName = key.toLowerCase() + if (!util.isValidHTTPToken(headerName)) { + throw new InvalidArgumentError('invalid header key') + } + } + + switch (headerName) { + case 'host': { + if (request.host !== null) break + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) } + // Consumed by Client + request.host = val + return } - if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - if (skipAppend) { - if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` - else request.headers[key] = processHeaderValue(key, val[i], skipAppend) - } else { - request.headers += processHeaderValue(key, val[i]) - } + case 'content-length': { + if (request.contentLength !== null) break + request.contentLength = parseInt(val, 10) + if (!Number.isFinite(request.contentLength)) { + throw new InvalidArgumentError('invalid content-length header') } - } else { + return + } + case 'content-type': { + if (request.contentType !== null) break + request.contentType = val if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) else request.headers += processHeaderValue(key, val) + return + } + case 'transfer-encoding': { + throw new InvalidArgumentError('invalid transfer-encoding header') + } + case 'connection': { + const value = typeof val === 'string' ? val.toLowerCase() : null + if (value !== 'close' && value !== 'keep-alive') { + throw new InvalidArgumentError('invalid connection header') + } else if (value === 'close') { + request.reset = true + } + return + } + case 'keep-alive': { + throw new InvalidArgumentError('invalid keep-alive header') + } + case 'upgrade': { + throw new InvalidArgumentError('invalid upgrade header') + } + case 'expect': { + throw new NotSupportedError('expect header not supported') } - return } - - if ( - request.host === null && - key.length === 4 && - key.toLowerCase() === 'host' - ) { - if (headerCharRegex.exec(val) !== null) { - throw new InvalidArgumentError(`invalid ${key} header`) - } - // Consumed by Client - request.host = val - } else if ( - request.contentLength === null && - key.length === 14 && - key.toLowerCase() === 'content-length' - ) { - request.contentLength = parseInt(val, 10) - if (!Number.isFinite(request.contentLength)) { - throw new InvalidArgumentError('invalid content-length header') - } - } else if ( - request.contentType === null && - key.length === 12 && - key.toLowerCase() === 'content-type' - ) { - request.contentType = val - if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) - else request.headers += processHeaderValue(key, val) - } else if ( - key.length === 17 && - key.toLowerCase() === 'transfer-encoding' - ) { - throw new InvalidArgumentError('invalid transfer-encoding header') - } else if ( - key.length === 10 && - key.toLowerCase() === 'connection' - ) { - const value = typeof val === 'string' ? val.toLowerCase() : null - if (value !== 'close' && value !== 'keep-alive') { - throw new InvalidArgumentError('invalid connection header') - } else if (value === 'close') { - request.reset = true - } - } else if ( - key.length === 10 && - key.toLowerCase() === 'keep-alive' - ) { - throw new InvalidArgumentError('invalid keep-alive header') - } else if ( - key.length === 7 && - key.toLowerCase() === 'upgrade' - ) { - throw new InvalidArgumentError('invalid upgrade header') - } else if ( - key.length === 6 && - key.toLowerCase() === 'expect' - ) { - throw new NotSupportedError('expect header not supported') - } else if (!util.isValidHTTPToken(key)) { - throw new InvalidArgumentError('invalid header key') - } else { - if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - if (skipAppend) { - if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` - else request.headers[key] = processHeaderValue(key, val[i], skipAppend) - } else { - request.headers += processHeaderValue(key, val[i]) - } + if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + if (skipAppend) { + if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` + else request.headers[key] = processHeaderValue(key, val[i], skipAppend) + } else { + request.headers += processHeaderValue(key, val[i]) } - } else { - if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) - else request.headers += processHeaderValue(key, val) } + } else { + if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) } }