fix(aws-lambda): combine ALB multi-value headers per RFC 9110#4902
Open
rokasta12 wants to merge 1 commit into
Open
fix(aws-lambda): combine ALB multi-value headers per RFC 9110#4902rokasta12 wants to merge 1 commit into
rokasta12 wants to merge 1 commit into
Conversation
`ALBProcessor.getHeaders` joined every multi-valued header with `'; '`, but RFC 9110 §5.3 specifies `, ` as the separator for combining field-line values. The previous behavior turned a request with two `Accept` values into the single non-conformant value `text/html; application/json`, which downstream content negotiation treats as one media range with a parameter rather than two distinct ranges. The same misjoin affected `Cache-Control`, `Forwarded`, `If-None-Match`, `Accept-Language`, etc. Now the loop appends each value individually, so the WHATWG Headers combine them with `, ` automatically. The Cookie header keeps its existing `'; '` join because RFC 6265 §5.4 requires that separator for cookies inside a single Cookie request header.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
`ALBProcessor.getHeaders` (`src/adapter/aws-lambda/handler.ts:511-518`) joined every multi-valued header with `'; '`:
```ts
if (event.multiValueHeaders) {
for (const [key, values] of Object.entries(event.multiValueHeaders)) {
if (values && Array.isArray(values)) {
const sanitizedValue = sanitizeHeaderValue(values.join('; '))
headers.set(key, sanitizedValue)
}
}
}
```
RFC 9110 §5.3 requires `, ` as the separator when combining field-line values; `; ` is only correct for the `Cookie` request header (RFC 6265 §5.4) and a handful of structured headers using parameters.
A real client sending:
```
Accept: text/html
Accept: application/json
```
is delivered to ALB as `multiValueHeaders: { accept: ['text/html', 'application/json'] }` and reaches the Hono handler as the single value `text/html; application/json`. Content-negotiation libraries (and Hono's own `c.req.header('accept')` consumers) interpret that as one media range with a parameter, not two distinct ranges. The same flaw affects `Cache-Control`, `Forwarded`, `If-None-Match`, `Accept-Language`, `Vary`, `Link`, etc.
Fix
Append each value individually so the WHATWG `Headers` combine them with `, ` automatically. Special-case `cookie` (case-insensitive) to keep the `; ` join, matching the existing test expectation and RFC 6265.
```ts
if (key.toLowerCase() === 'cookie') {
headers.set(key, sanitizeHeaderValue(values.join('; ')))
} else {
for (const value of values) {
headers.append(key, sanitizeHeaderValue(value))
}
}
```
Test
Added two tests under `EventProcessor.createRequest > ALBProcessor multi-value header handling`:
Non-cookie multi-value — sends two `Accept` values plus two `Cache-Control` values via `multiValueHeaders`, asserts `request.headers.get('accept')` returns `'text/html, application/json'` and `cache-control` returns `'no-cache, no-store'`. Fails on `main` (returns `'text/html; application/json'`); passes with the fix.
Cookie still uses `; ` — confirms the special case continues to behave correctly per RFC 6265.