fix(frontend): strip hop-by-hop headers from proxied responses too
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,21 @@ const HOP_BY_HOP_HEADERS = [
|
||||
'upgrade'
|
||||
];
|
||||
|
||||
/**
|
||||
* Return a copy of `src` with the hop-by-hop headers removed. Applied to
|
||||
* BOTH the proxied request and the proxied response: per RFC 7230 §6.1 a
|
||||
* proxy must not forward connection-scoped headers in either direction.
|
||||
* On the response side this also drops the upstream `content-length` /
|
||||
* `transfer-encoding`, which the runtime recomputes for the re-streamed
|
||||
* body — forwarding the upstream values risks a framing mismatch.
|
||||
* Exported for unit-test coverage.
|
||||
*/
|
||||
export function stripHopByHopHeaders(src: Headers): Headers {
|
||||
const out = new Headers(src);
|
||||
for (const h of HOP_BY_HOP_HEADERS) out.delete(h);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cap each proxied request at 5 minutes. The bound exists to surface
|
||||
* a wedged backend (stuck on a slow DB query, deadlocked, etc.) as a
|
||||
@@ -74,8 +89,7 @@ export const handle: Handle = async ({ event, resolve }) => {
|
||||
if (event.url.pathname.startsWith('/api/')) {
|
||||
const target = `${BACKEND_URL}${event.url.pathname}${event.url.search}`;
|
||||
|
||||
const headers = new Headers(event.request.headers);
|
||||
for (const h of HOP_BY_HOP_HEADERS) headers.delete(h);
|
||||
const headers = stripHopByHopHeaders(event.request.headers);
|
||||
|
||||
// AbortController times the upstream fetch out so a backend
|
||||
// wedged on a slow DB query doesn't keep the browser request
|
||||
@@ -148,7 +162,10 @@ export const handle: Handle = async ({ event, resolve }) => {
|
||||
return new Response(upstream.body, {
|
||||
status: upstream.status,
|
||||
statusText: upstream.statusText,
|
||||
headers: upstream.headers
|
||||
// Strip hop-by-hop headers on the way back too — the upstream's
|
||||
// transfer-encoding / content-length / connection headers must
|
||||
// not ride along on the re-streamed response.
|
||||
headers: stripHopByHopHeaders(upstream.headers)
|
||||
});
|
||||
}
|
||||
return resolve(event);
|
||||
|
||||
Reference in New Issue
Block a user