diff --git a/__tests__/integration.js b/__tests__/integration.js index f1c09a99..2e6ee91d 100644 --- a/__tests__/integration.js +++ b/__tests__/integration.js @@ -103,6 +103,40 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo expect(response).toEqual(expectedResponse) }) + test('headers get lowercased', async () => { + app = express() + router = express.Router() + app.use('/', router) + serverlessExpressInstance = serverlessExpress({ app }) + router.get('/foo', (req, res) => { + const xHeaders = Object.fromEntries( + Object.entries(req.headers).filter(([name]) => name.startsWith('x-header-')) + ) + res.json({ xHeaders }) + }) + const event = makeEvent({ + eventSourceName: 'apiGatewayV1', + path: '/foo', + httpMethod: 'GET', + multiValueHeaders: undefined, + headers: { + 'X-Header-One': 'Value1', + 'x-header-two': 'Value2' + } + }) + const response = await serverlessExpressInstance(event) + const expectedResponse = makeResponse({ + eventSourceName: 'apiGatewayV1', + body: JSON.stringify({ + xHeaders: { + 'x-header-one': 'Value1', + 'x-header-two': 'Value2' + } + }) + }) + expect(response).toMatchObject(expectedResponse) + }) + test('resolutionMode = CALLBACK', (done) => { const jsonResponse = { data: { name: 'Brett' } } router.get('/users', (req, res) => { @@ -287,7 +321,7 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo const response = await serverlessExpressInstance(event) const expectedResponse = makeResponse({ eventSourceName, - body: JSON.stringify({ data: { name: name } }), + body: JSON.stringify({ data: { name } }), multiValueHeaders: { 'content-length': ['29'], etag: ['W/"1d-9ERga12t1e/5eBdg3k9zfIvAfWo"'] diff --git a/src/request.js b/src/request.js index a50e45f3..53450c4e 100644 --- a/src/request.js +++ b/src/request.js @@ -15,6 +15,16 @@ module.exports = class ServerlessRequest extends http.IncomingMessage { destroy: Function.prototype }) + // IncomingMessage has a lot of logic for when to lowercase or alias well-known header names, + // so we delegate to that logic here + const headerEntries = Object.entries(headers) + const rawHeaders = new Array(headerEntries.length * 2) + for (let i = 0; i < headerEntries.length; i++) { + rawHeaders[i * 2] = headerEntries[i][0] + rawHeaders[i * 2 + 1] = headerEntries[i][1] + } + this._addHeaderLines(rawHeaders, rawHeaders.length) + Object.assign(this, { ip: remoteAddress, complete: true, @@ -22,7 +32,6 @@ module.exports = class ServerlessRequest extends http.IncomingMessage { httpVersionMajor: '1', httpVersionMinor: '1', method, - headers, body, url })