Skip to content

fix(ext/fetch): keep content-encoding and content-length on decompressed responses#35124

Merged
bartlomieju merged 3 commits into
mainfrom
fix/fetch-content-encoding
Jun 13, 2026
Merged

fix(ext/fetch): keep content-encoding and content-length on decompressed responses#35124
bartlomieju merged 3 commits into
mainfrom
fix/fetch-content-encoding

Conversation

@bartlomieju

Copy link
Copy Markdown
Member

When fetch transparently decompressed a gzip or brotli response body, the
client also removed the content-encoding, content-length, and
transfer-encoding headers from the response. Per the fetch spec, handling
content codings only decodes the body and leaves the header list as
received, which is what browsers and Node.js (undici) do. Code that
inspects response headers (for example to detect that a server compressed
the response) behaved differently in Deno than everywhere else.

The headers are now preserved as received from the server. Since the kept
content-length describes the encoded body rather than the decoded stream,
the CLI download progress bar no longer uses it as a total when a
content-encoding header is present. Existing tests asserting the stripping
behavior were updated to assert the preserved headers instead.

Fixes #20548

…essed responses

CI hung in 'http server compresses and flushes each chunk of a streamed
resource' on every platform: with content-encoding now preserved on
decompressed fetch responses, proxying a Response straight into
respondWith()/Deno.serve forwarded content-encoding, content-length and
transfer-encoding describing the original wire body together with the
already-decoded body. The server then skipped its own compression
(content-encoding present), so clients received plain bytes labeled as
compressed and the test's DecompressionStream never produced output.

Keep the headers visible on the Response per the fetch spec, but mark
responses whose body was transparently decompressed (extensions marker
in Rust, bodyDecoded on the inner response in JS) and strip the three
wire-framing headers at re-serialization boundaries: Deno.serve, the
legacy serveHttp respondWith, and Cache API storage.

Adds a regression test proxying a decompressed fetch response through
Deno.serve, verified to fail without this change.
@bartlomieju
bartlomieju enabled auto-merge (squash) June 13, 2026 07:32
@bartlomieju
bartlomieju merged commit 197dfca into main Jun 13, 2026
136 checks passed
@bartlomieju
bartlomieju deleted the fix/fetch-content-encoding branch June 13, 2026 07:58
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.

content-encoding is removed from response

1 participant