Skip to content

fix(lambda-http): keep every value of a repeated request header - #1184

Open
hoangchunghien wants to merge 1 commit into
aws:mainfrom
hoangchunghien:fix/keep-multi-value-request-headers
Open

hoangchunghien wants to merge 1 commit into
aws:mainfrom
hoangchunghien:fix/keep-multi-value-request-headers

Conversation

@hoangchunghien

Copy link
Copy Markdown

Problem

A request header that appears more than once reaches the handler with only its last value when the event comes from API Gateway REST (v1), an ALB with multi-value headers enabled, or an API Gateway WebSocket.

These events carry a repeated header in both maps: headers holds the last value and multiValueHeaders holds all of them. lambda-http/src/request.rs builds the request headers like this:

let mut headers = ag.multi_value_headers;
headers.extend(ag.headers);

HeaderMap::extend replaces the values of keys that are already present, so the single-value copy overwrites the complete list. The same two lines appear in into_proxy_request, into_alb_request and into_websocket_request.

Fix

A small merge_headers helper keeps the multi-value entries, and takes a single-value entry only for a name the multi-value map does not have. Events that send only one of the two maps behave exactly as before.

Tests

Two fixtures copy the existing multi-value ones and add a header present in both maps ("X-Repeated": "second" and ["first", "second"]). Two tests assert that both values arrive:

  • keeps_every_value_of_a_header_repeated_in_apigw_multi_value_headers
  • keeps_every_value_of_a_header_repeated_in_alb_multi_value_headers

On main (7f89224) both fail with left: ["second"], right: ["first", "second"].

cargo test -p lambda_http --all-features            # all pass, including the 2 new tests
cargo clippy --workspace --all-features -- -D warnings
cargo +nightly fmt --all -- --check

(lambda-integration-tests needs TEST_ENDPOINT and SECRET_TOKEN, so I did not run it.)

I also checked it end to end. I found this through aws-lambda-web-adapter, which uses lambda_http, running in the Lambda Runtime Interface Emulator in front of an app that echoes its request headers. A REST API event with x-m: 1 and x-m: 2 reached the app as ['2'] with lambda_http 1.3.0, and as ['1', '2'] with this branch patched in. The same held for an ALB event.

API Gateway REST, ALB and WebSocket events carry a repeated header in both
maps: `headers` holds only its last value and `multiValueHeaders` holds all
of them. The request conversion extended the multi-value map with the
single-value one, and HeaderMap::extend replaces existing keys, so the
handler saw only the last value.

Merge so that a single-value header is used only when the multi-value map
does not already have that name.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant