From 13cf1167761218a5453874c9d6616cbf6794a3f6 Mon Sep 17 00:00:00 2001 From: Keery Nie Date: Thu, 5 Sep 2024 15:28:55 +0800 Subject: [PATCH] fix(aws-lambda): add null handling for multiValueHeaders (#13533) A small PR for adding a null handling code for the multiValueHeaders field. Also contains a small refactor to put isBase64Encode check into the validate function to keep consistency with other fields FTI-6168 (cherry picked from commit 50c57c87dc473ce1014c98ff3b07edbef6fc9529) --- ...fix-aws-lambda-multi-value-header-null.yml | 3 ++ kong/plugins/aws-lambda/request-util.lua | 10 +++-- .../27-aws-lambda/99-access_spec.lua | 38 +++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 changelog/unreleased/kong/fix-aws-lambda-multi-value-header-null.yml diff --git a/changelog/unreleased/kong/fix-aws-lambda-multi-value-header-null.yml b/changelog/unreleased/kong/fix-aws-lambda-multi-value-header-null.yml new file mode 100644 index 000000000000..253db7bbcfde --- /dev/null +++ b/changelog/unreleased/kong/fix-aws-lambda-multi-value-header-null.yml @@ -0,0 +1,3 @@ +message: "**AWS-Lambda**: Fixed an issue in proxy integration mode that caused internal server error when the `multiValueHeaders` is null." +type: bugfix +scope: Plugin diff --git a/kong/plugins/aws-lambda/request-util.lua b/kong/plugins/aws-lambda/request-util.lua index 478f8c619e89..9e761afc1959 100644 --- a/kong/plugins/aws-lambda/request-util.lua +++ b/kong/plugins/aws-lambda/request-util.lua @@ -1,6 +1,7 @@ local kong = kong local ngx_encode_base64 = ngx.encode_base64 local ngx_decode_base64 = ngx.decode_base64 +local null = ngx.null local cjson = require "cjson.safe" local date = require("date") @@ -89,6 +90,10 @@ local function validate_custom_response(response) return nil, "body must be a string" end + if response.isBase64Encoded ~= nil and type(response.isBase64Encoded) ~= "boolean" then + return nil, "isBase64Encoded must be a boolean" + end + return true end @@ -118,13 +123,10 @@ local function extract_proxy_response(content) local isBase64Encoded = serialized_content.isBase64Encoded if isBase64Encoded == true then body = ngx_decode_base64(body) - - elseif isBase64Encoded ~= false and isBase64Encoded ~= nil then - return nil, "isBase64Encoded must be a boolean" end local multiValueHeaders = serialized_content.multiValueHeaders - if multiValueHeaders then + if multiValueHeaders and multiValueHeaders ~= null then for header, values in pairs(multiValueHeaders) do headers[header] = values end diff --git a/spec/03-plugins/27-aws-lambda/99-access_spec.lua b/spec/03-plugins/27-aws-lambda/99-access_spec.lua index 76b79c64c665..f5a66b7933fb 100644 --- a/spec/03-plugins/27-aws-lambda/99-access_spec.lua +++ b/spec/03-plugins/27-aws-lambda/99-access_spec.lua @@ -194,6 +194,12 @@ for _, strategy in helpers.each_strategy() do service = null, } + local route29 = bp.routes:insert { + hosts = { "lambda29.test" }, + protocols = { "http", "https" }, + service = null, + } + bp.plugins:insert { name = "aws-lambda", route = { id = route1.id }, @@ -580,6 +586,19 @@ for _, strategy in helpers.each_strategy() do } } + bp.plugins:insert { + name = "aws-lambda", + route = { id = route29.id }, + config = { + port = 10001, + aws_key = "mock-key", + aws_secret = "mock-secret", + aws_region = "us-east-1", + function_name = "functionWithNullMultiValueHeaders", + is_proxy_integration = true, + } + } + fixtures.dns_mock:A({ name = "custom.lambda.endpoint", address = "127.0.0.1", @@ -1154,6 +1173,25 @@ for _, strategy in helpers.each_strategy() do assert.equal("Bad Gateway", b.message) end) + it("do not throw error when 'multiValueHeaders' is JSON null", function () + local res = assert(proxy_client:send { + method = "POST", + path = "/post", + headers = { + ["Host"] = "lambda11.test", + ["Content-Type"] = "application/json", + }, + body = { + statusCode = 201, + body = "test", + multiValueHeaders = cjson.null, + } + }) + + local body = assert.res_status(201, res) + assert.same(body, "test") + end) + it("returns HTTP 502 with when response from lambda is not valid JSON", function() local res = assert(proxy_client:send { method = "POST",