local date = require "date" local cycle_aware_deep_copy = require("kong.tools.table").cycle_aware_deep_copy describe("[AWS Lambda] aws-gateway input", function() local mock_request local old_ngx local aws_serialize local function reload_module() -- make sure to reload the module package.loaded["kong.observability.tracing.request_id"] = nil package.loaded["kong.plugins.aws-lambda.request-util"] = nil aws_serialize = require "kong.plugins.aws-lambda.request-util".aws_serializer end setup(function() old_ngx = ngx local body_data _G.ngx = setmetatable({ req = { get_headers = function() return cycle_aware_deep_copy(mock_request.headers) end, get_uri_args = function() return cycle_aware_deep_copy(mock_request.query) end, read_body = function() body_data = mock_request.body end, get_body_data = function() return body_data end, http_version = function() return mock_request.http_version end, start_time = function() return mock_request.start_time end, }, log = function() end, get_phase = function() -- luacheck: ignore return "access" end, encode_base64 = old_ngx.encode_base64 }, { -- look up any unknown key in the mock request, eg. .var and .ctx tables __index = function(self, key) return mock_request and mock_request[key] end, }) end) teardown(function() -- make sure to drop the mocks package.loaded["kong.plugins.aws-lambda.request-util"] = nil ngx = old_ngx -- luacheck: ignore end) it("serializes a request regex", function() mock_request = { http_version = "1.1", start_time = 1662436514, headers = { ["single-header"] = "hello world", ["multi-header"] = { "first", "second" }, ["user-agent"] = "curl/7.54.0", }, query = { ["single-query"] = "hello world", ["multi-query"] = { "first", "second" }, boolean = true, }, body = "text", var = { request_method = "GET", upstream_uri = "/123/strip/more?boolean=;multi-query=first;single-query=hello%20world;multi-query=second", kong_request_id = "1234567890", host = "abc.myhost.test", remote_addr = "123.123.123.123" }, ctx = { router_matches = { uri_captures = { "123", [0] = "/123/strip/more", version = "123" }, uri = "/(?\\d+)/strip" }, }, } reload_module() local out = aws_serialize() assert.same({ version = "1.0", httpMethod = "GET", path = "/123/strip/more", resource = "/(?\\d+)/strip", pathParameters = { version = "123", }, isBase64Encoded = true, body = ngx.encode_base64("text"), headers = { ["multi-header"] = "first", ["single-header"] = "hello world", ["user-agent"] = "curl/7.54.0", }, multiValueHeaders = { ["multi-header"] = { "first", "second" }, ["single-header"] = { "hello world" }, ["user-agent"] = { "curl/7.54.0" }, }, queryStringParameters = { boolean = true, ["multi-query"] = "first", ["single-query"] = "hello world", }, multiValueQueryStringParameters = { boolean = { true} , ["multi-query"] = { "first", "second" }, ["single-query"] = { "hello world" }, }, requestContext = { path = "/123/strip/more", protocol = "HTTP/1.1", httpMethod = "GET", domainName = "abc.myhost.test", domainPrefix = "abc", identity = { sourceIp = "123.123.123.123", userAgent = "curl/7.54.0" }, requestId = "1234567890", requestTime = date(1662436514):fmt("%d/%b/%Y:%H:%M:%S %z"), requestTimeEpoch = 1662436514 * 1000, resourcePath = "/123/strip/more", } }, out) end) it("serializes a request no-regex", function() mock_request = { http_version = "1.0", start_time = 1662436514, headers = { ["single-header"] = "hello world", ["multi-header"] = { "first", "second" }, ["user-agent"] = "curl/7.54.0", }, query = { ["single-query"] = "hello world", ["multi-query"] = { "first", "second" }, boolean = true, }, body = "text", var = { request_method = "GET", upstream_uri = "/plain/strip/more?boolean=;multi-query=first;single-query=hello%20world;multi-query=second", kong_request_id = "1234567890", host = "def.myhost.test", remote_addr = "123.123.123.123" }, ctx = { router_matches = { uri = "/plain/strip" }, }, } reload_module() local out = aws_serialize() assert.same({ version = "1.0", httpMethod = "GET", path = "/plain/strip/more", resource = "/plain/strip", pathParameters = {}, isBase64Encoded = true, body = ngx.encode_base64("text"), headers = { ["multi-header"] = "first", ["single-header"] = "hello world", ["user-agent"] = "curl/7.54.0", }, multiValueHeaders = { ["multi-header"] = { "first", "second" }, ["single-header"] = { "hello world" }, ["user-agent"] = { "curl/7.54.0" }, }, queryStringParameters = { boolean = true, ["multi-query"] = "first", ["single-query"] = "hello world", }, multiValueQueryStringParameters = { boolean = { true} , ["multi-query"] = { "first", "second" }, ["single-query"] = { "hello world" }, }, requestContext = { path = "/plain/strip/more", protocol = "HTTP/1.0", httpMethod = "GET", domainName = "def.myhost.test", domainPrefix = "def", identity = { sourceIp = "123.123.123.123", userAgent = "curl/7.54.0" }, requestId = "1234567890", requestTime = date(1662436514):fmt("%d/%b/%Y:%H:%M:%S %z"), requestTimeEpoch = 1662436514 * 1000, resourcePath = "/plain/strip/more", } }, out) end) do local td = { { description = "none", ct = nil, body_in = "text", body_out = ngx.encode_base64("text"), base64 = true, }, { description = "application/json", ct = "application/json", body_in = [[{ "text": "some text" }]], body_out = ngx.encode_base64([[{ "text": "some text" }]]), base64 = true, }, { description = "unknown", ct = "some-unknown-type-description", body_in = "text", body_out = ngx.encode_base64("text"), base64 = true, }, } for _, tdata in ipairs(td) do it("serializes a request with body type: " .. tdata.description, function() mock_request = { http_version = "1.0", start_time = 1662436514, body = tdata.body_in, headers = { ["Content-Type"] = tdata.ct, ["user-agent"] = "curl/7.54.0", }, query = {}, var = { request_method = "GET", upstream_uri = "/plain/strip/more", http_content_type = tdata.ct, kong_request_id = "1234567890", host = "def.myhost.test", remote_addr = "123.123.123.123" }, ctx = { router_matches = { uri = "/plain/strip" }, }, } reload_module() local out = aws_serialize() assert.same({ version = "1.0", body = tdata.body_out, headers = { ["Content-Type"] = tdata.ct, ["user-agent"] = "curl/7.54.0", }, multiValueHeaders = { ["Content-Type"] = tdata.ct and { tdata.ct } or nil, ["user-agent"] = { "curl/7.54.0" }, }, httpMethod = "GET", queryStringParameters = {}, multiValueQueryStringParameters = {}, pathParameters = {}, resource = "/plain/strip", path = "/plain/strip/more", isBase64Encoded = tdata.base64, requestContext = { path = "/plain/strip/more", protocol = "HTTP/1.0", httpMethod = "GET", domainName = "def.myhost.test", domainPrefix = "def", identity = { sourceIp = "123.123.123.123", userAgent = "curl/7.54.0" }, requestId = "1234567890", requestTime = date(1662436514):fmt("%d/%b/%Y:%H:%M:%S %z"), requestTimeEpoch = 1662436514 * 1000, resourcePath = "/plain/strip/more", } }, out) end) end end end)