From 4ca0adbaa508d9b22b71637f6b27dd02c3b554ad Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Fri, 17 Nov 2023 08:12:04 -0600 Subject: [PATCH] refactor: make content type header case-insensitive (#135) * refactor: make content type header case-insensitive * format * fix * fix * make test more clear --- lambda/parse-request-body.ts | 2 +- lambda/proxy.test.ts | 6 +++--- lambda/proxy.ts | 2 +- lambda/schema.ts | 22 ++++++++++------------ package-lock.json | 22 ++++++++++++++++++++++ package.json | 2 ++ 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/lambda/parse-request-body.ts b/lambda/parse-request-body.ts index e4c9aa2..c048290 100644 --- a/lambda/parse-request-body.ts +++ b/lambda/parse-request-body.ts @@ -17,7 +17,7 @@ import { bodySchema, CONTENT_TYPES, headersSchema } from './schema'; export function parseRequestBody(body: string, headers: IncomingHttpHeaders) { const headersResult = headersSchema.parse(headers); - const contentType = headersResult['content-type'] || headersResult['Content-Type']; + const contentType = headersResult['content-type']; switch (contentType) { case CONTENT_TYPES.JSON: return JSON.parse(body); diff --git a/lambda/proxy.test.ts b/lambda/proxy.test.ts index 0170911..ed0fb6a 100644 --- a/lambda/proxy.test.ts +++ b/lambda/proxy.test.ts @@ -123,9 +123,9 @@ describe('proxy', () => { const event: APIGatewayProxyWithLambdaAuthorizerEvent = { ...baseEvent, headers: { - ...baseEvent.headers, - 'content-type': undefined, - 'Content-Type': 'application/json' + Accept: '*/*', + 'Content-Type': 'application/json', + Host: 'some-api.us-west-2.amazonaws.com' }, body: JSON.stringify(VALID_PUSH_PAYLOAD), pathParameters: { diff --git a/lambda/proxy.ts b/lambda/proxy.ts index b44c33e..7d1092f 100644 --- a/lambda/proxy.ts +++ b/lambda/proxy.ts @@ -61,6 +61,6 @@ export async function handler(event: APIGatewayProxyWithLambdaAuthorizerEvent { - return headers['content-type'] || headers['Content-Type']; - }, - { - message: 'Missing Content-Type header' +export const headersSchema = z.preprocess( + obj => { + if (obj && typeof obj == 'object') { + return mapKeys(obj, (_, key) => key.toLowerCase()); } - ); + }, + z.object({ + 'content-type': z.nativeEnum(CONTENT_TYPES) + }) +); export const axiosErrorSchema = z.object({ response: z.object({ diff --git a/package-lock.json b/package-lock.json index 8bdec95..39bda1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "dependencies": { "@types/node": "20.1.1", "axios": "1.6.1", + "lodash.mapkeys": "4.6.0", "query-string": "7.1.3", "typescript": "5.2.2", "zod": "3.22.4" @@ -17,6 +18,7 @@ "@swc/jest": "0.2.29", "@types/aws-lambda": "8.10.107", "@types/jest": "29.5.8", + "@types/lodash.mapkeys": "4.6.9", "jest": "29.7.0", "prettier": "3.1.0" } @@ -1563,6 +1565,21 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/lodash": { + "version": "4.14.201", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.201.tgz", + "integrity": "sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==", + "dev": true + }, + "node_modules/@types/lodash.mapkeys": { + "version": "4.6.9", + "resolved": "https://registry.npmjs.org/@types/lodash.mapkeys/-/lodash.mapkeys-4.6.9.tgz", + "integrity": "sha512-6/ERBCabeDI656LsV+oopLjdnJ/x1PCAE6kkkssH8e4i0K7Pw307noxHCbUc6cAVfTo9vx0Z+k3QZwy1IrUZcA==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/node": { "version": "20.1.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.1.tgz", @@ -3633,6 +3650,11 @@ "node": ">=8" } }, + "node_modules/lodash.mapkeys": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapkeys/-/lodash.mapkeys-4.6.0.tgz", + "integrity": "sha512-0Al+hxpYvONWtg+ZqHpa/GaVzxuN3V7Xeo2p+bY06EaK/n+Y9R7nBePPN2o1LxmL0TWQSwP8LYZ008/hc9JzhA==" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", diff --git a/package.json b/package.json index 5d16e51..b0a4a65 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "dependencies": { "@types/node": "20.1.1", "axios": "1.6.1", + "lodash.mapkeys": "4.6.0", "query-string": "7.1.3", "typescript": "5.2.2", "zod": "3.22.4" @@ -19,6 +20,7 @@ "@swc/jest": "0.2.29", "@types/aws-lambda": "8.10.107", "@types/jest": "29.5.8", + "@types/lodash.mapkeys": "4.6.9", "jest": "29.7.0", "prettier": "3.1.0" },