diff --git a/src/events/alb/HttpServer.js b/src/events/alb/HttpServer.js index 5d25d168e..47c3b497e 100644 --- a/src/events/alb/HttpServer.js +++ b/src/events/alb/HttpServer.js @@ -292,10 +292,11 @@ export default class HttpServer { } createRoutes(functionKey, albEvent) { - let method = "ANY" + let methods = ["ANY"] if ((albEvent.conditions.method || []).length > 0) { - method = albEvent.conditions.method[0].toUpperCase() + methods = albEvent.conditions.method.map((m) => m.toUpperCase()) } + methods = methods.includes("ANY") ? ["ANY"] : methods const path = albEvent.conditions.path[0] const hapiPath = generateAlbHapiPath(path, this.#options, this.#serverless) @@ -304,51 +305,53 @@ export default class HttpServer { const { host, albPort, httpsProtocol } = this.#options const server = `${httpsProtocol ? "https" : "http"}://${host}:${albPort}` - this.#terminalInfo.push({ - invokePath: `/2015-03-31/functions/${functionKey}/invocations`, - method, - path: hapiPath, - server, - stage: this.#options.noPrependStageInUrl ? null : stage, - }) + methods.forEach((method) => { + this.#terminalInfo.push({ + invokePath: `/2015-03-31/functions/${functionKey}/invocations`, + method, + path: hapiPath, + server, + stage: this.#options.noPrependStageInUrl ? null : stage, + }) - const hapiMethod = method === "ANY" ? "*" : method - const hapiOptions = { - response: { - emptyStatusCode: 200, - }, - } + const hapiMethod = method === "ANY" ? "*" : method + const hapiOptions = { + response: { + emptyStatusCode: 200, + }, + } - // skip HEAD routes as hapi will fail with 'Method name not allowed: HEAD ...' - // for more details, check https://github.com/dherault/serverless-offline/issues/204 - if (hapiMethod === "HEAD") { - log.notice( - "HEAD method event detected. Skipping HAPI server route mapping", - ) + // skip HEAD routes as hapi will fail with 'Method name not allowed: HEAD ...' + // for more details, check https://github.com/dherault/serverless-offline/issues/204 + if (hapiMethod === "HEAD") { + log.notice( + "HEAD method event detected. Skipping HAPI server route mapping", + ) - return - } + return + } - if (hapiMethod !== "HEAD" && hapiMethod !== "GET") { - // maxBytes: Increase request size from 1MB default limit to 10MB. - // Cf AWS API GW payload limits. - hapiOptions.payload = { - maxBytes: 1024 * 1024 * 10, - parse: false, + if (hapiMethod !== "HEAD" && hapiMethod !== "GET") { + // maxBytes: Increase request size from 1MB default limit to 10MB. + // Cf AWS API GW payload limits. + hapiOptions.payload = { + maxBytes: 1024 * 1024 * 10, + parse: false, + } } - } - const hapiHandler = this.#createHapiHandler({ - functionKey, - method, - stage, - }) + const hapiHandler = this.#createHapiHandler({ + functionKey, + method, + stage, + }) - this.#server.route({ - handler: hapiHandler, - method: hapiMethod, - options: hapiOptions, - path: hapiPath, + this.#server.route({ + handler: hapiHandler, + method: hapiMethod, + options: hapiOptions, + path: hapiPath, + }) }) } diff --git a/tests/integration/alb-handler/handlerPayload.test.js b/tests/integration/alb-handler/handlerPayload.test.js index 71b0b5f03..6e3d907eb 100644 --- a/tests/integration/alb-handler/handlerPayload.test.js +++ b/tests/integration/alb-handler/handlerPayload.test.js @@ -309,6 +309,20 @@ describe("ALB handler payload tests with prepend off", function desc() { path: "/test-no-method-conditions", status: 200, }, + { + description: "test multiple-method handler GET", + expected: "GET", + method: "GET", + path: "/test-multiple-methods", + status: 200, + }, + { + description: "test multiple-method handler POST", + expected: "POST", + method: "POST", + path: "/test-multiple-methods", + status: 200, + }, ].forEach(({ description, expected, path, status, method }) => { it(description, async () => { const url = new URL(path, BASE_URL) diff --git a/tests/integration/alb-handler/serverless.yml b/tests/integration/alb-handler/serverless.yml index eb5b59bdb..33fb48586 100644 --- a/tests/integration/alb-handler/serverless.yml +++ b/tests/integration/alb-handler/serverless.yml @@ -224,6 +224,17 @@ functions: path: /test-query-parameters handler: src/handler.TestQueryParameters + TestMultipleMethods: + events: + - alb: + listenerArn: arn:aws:elasticloadbalancing:us-east-1:12345:listener/app/my-load-balancer/50dc6c495c0c9188/50dc6c495c0c9188 + priority: 1 + conditions: + method: + - GET + - POST + path: /test-multiple-methods + handler: src/handler.TestMultipleMethods TestNoMethodCondition: events: - alb: diff --git a/tests/integration/alb-handler/src/handler.js b/tests/integration/alb-handler/src/handler.js index 64e6350b0..c8dc37d35 100644 --- a/tests/integration/alb-handler/src/handler.js +++ b/tests/integration/alb-handler/src/handler.js @@ -190,6 +190,13 @@ export const TestQueryParameters = (event, context, callback) => { }) } +export const TestMultipleMethods = (event, context, callback) => { + callback(null, { + body: stringify(event.httpMethod), + statusCode: 200, + }) +} + export const TestNoMethodConditions = (event, context, callback) => { callback(null, { body: stringify(event.httpMethod),