From 86e7cdfe344f263406d7493522a47f6dc6128937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ngh=C4=A9a=20Nguy=E1=BB=85n=20Ng=E1=BB=8Dc?= Date: Sat, 9 May 2026 11:37:35 +0700 Subject: [PATCH] feat(events): add MultiValueHeaders to LambdaFunctionURLResponse AWS Lambda Function URLs can return multiple values for the same header key (e.g. multiple Set-Cookie headers). Without MultiValueHeaders, callers had to work around the single-value Headers map and could not set more than one cookie in a single response. Adds MultiValueHeaders map[string][]string with omitempty, matching the shape already present on APIGatewayProxyResponse and APIGatewayV2HTTPResponse, and adds a round-trip marshaling test with a multi-cookie fixture. Fixes #556 --- events/lambda_function_urls.go | 11 +++++----- events/lambda_function_urls_test.go | 21 +++++++++++++++++++ ...bda-urls-response-multi-value-headers.json | 12 +++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 events/testdata/lambda-urls-response-multi-value-headers.json diff --git a/events/lambda_function_urls.go b/events/lambda_function_urls.go index 1d5ac6ff..d5bb5e95 100644 --- a/events/lambda_function_urls.go +++ b/events/lambda_function_urls.go @@ -61,11 +61,12 @@ type LambdaFunctionURLRequestContextHTTPDescription struct { // LambdaFunctionURLResponse configures the HTTP response to be returned by Lambda Function URL for the request. type LambdaFunctionURLResponse struct { - StatusCode int `json:"statusCode"` - Headers map[string]string `json:"headers"` - Body string `json:"body"` - IsBase64Encoded bool `json:"isBase64Encoded"` - Cookies []string `json:"cookies"` + StatusCode int `json:"statusCode"` + Headers map[string]string `json:"headers"` + MultiValueHeaders map[string][]string `json:"multiValueHeaders,omitempty"` + Body string `json:"body"` + IsBase64Encoded bool `json:"isBase64Encoded"` + Cookies []string `json:"cookies"` } // LambdaFunctionURLStreamingResponse models the response to a Lambda Function URL when InvokeMode is RESPONSE_STREAM. diff --git a/events/lambda_function_urls_test.go b/events/lambda_function_urls_test.go index cbc15f45..cdb3b08d 100644 --- a/events/lambda_function_urls_test.go +++ b/events/lambda_function_urls_test.go @@ -60,6 +60,27 @@ func TestLambdaFunctionURLRequestMarshaling(t *testing.T) { assert.JSONEq(t, string(inputJSON), string(outputJSON)) } +func TestLambdaFunctionURLResponseMultiValueHeadersMarshaling(t *testing.T) { + inputJSON, err := ioutil.ReadFile("./testdata/lambda-urls-response-multi-value-headers.json") + if err != nil { + t.Errorf("could not open test file. details: %v", err) + } + + var inputEvent LambdaFunctionURLResponse + if err := json.Unmarshal(inputJSON, &inputEvent); err != nil { + t.Errorf("could not unmarshal event. details: %v", err) + } + + require.Equal(t, []string{"a=1; Path=/", "b=2; Path=/"}, inputEvent.MultiValueHeaders["Set-Cookie"]) + + outputJSON, err := json.Marshal(inputEvent) + if err != nil { + t.Errorf("could not marshal event. details: %v", err) + } + + assert.JSONEq(t, string(inputJSON), string(outputJSON)) +} + func TestLambdaFunctionURLStreamingResponseMarshaling(t *testing.T) { for _, test := range []struct { name string diff --git a/events/testdata/lambda-urls-response-multi-value-headers.json b/events/testdata/lambda-urls-response-multi-value-headers.json new file mode 100644 index 00000000..2d9b7a96 --- /dev/null +++ b/events/testdata/lambda-urls-response-multi-value-headers.json @@ -0,0 +1,12 @@ +{ + "statusCode": 200, + "headers": { + "Content-Type": "application/json" + }, + "multiValueHeaders": { + "Set-Cookie": ["a=1; Path=/", "b=2; Path=/"] + }, + "body": "", + "cookies": [], + "isBase64Encoded": false +}