Skip to content

feat: add zstd content-encoding decompression support#6836

Open
StilesCrisis wants to merge 3 commits into
cloudflare:mainfrom
StilesCrisis:fix/zstd-content-encoding-decode
Open

feat: add zstd content-encoding decompression support#6836
StilesCrisis wants to merge 3 commits into
cloudflare:mainfrom
StilesCrisis:fix/zstd-content-encoding-decode

Conversation

@StilesCrisis

@StilesCrisis StilesCrisis commented Jun 21, 2026

Copy link
Copy Markdown

Before this PR, responses with Content-Encoding: zstd were passed through as raw compressed bytes — workerd had no zstd decompression support. Workers calling .text(), .json(), etc. on such responses received garbled data.

  • Add ZstdAsyncInputStream streaming decompressor in system-streams.c++ and readable-source.c++, modeled after the existing gzip/brotli implementations
  • Wire "zstd" into getContentEncoding() behind a new zstd_content_encoding compat flag (enabled 2026-06-21), matching the brotli_content_encoding pattern
  • Add zstd @3 to the StreamEncoding capnp enum

Before this change, a Service Worker using Cache.addAll() would silently fail when zstd compression was used server-side. The client would receive unrecognizable data and put zero-byte files into cache.

🤖 Generated with Claude Code

johnstiles-google and others added 3 commits June 21, 2026 14:39
…ncoding header

When a fetch() subrequest returns Content-Encoding: zstd, workerd now:
1. Decompresses the body transparently via a new ZstdAsyncInputStream class
2. Strips the Content-Encoding header from the Response so downstream code
   (e.g. Cache API) doesn't re-interpret the already-decoded body as zstd

This mirrors the existing gzip and brotli auto-decode behavior. Adds ZSTD to
the StreamEncoding capnp enum, implements ZstdAsyncInputStream using the zstd
streaming API in both system-streams.c++ and readable-source.c++, and adds
KJ_FAIL_REQUIRE for the unsupported zstd output compression path.

Fixes: cloudflare#5112

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds 4 readable-source tests and 2 writable-sink tests mirroring the
existing gzip test suite:
- Zstd encoded stream (readAllBytes)
- Zstd encoded stream (pumpTo)
- Zstd encoded stream (pumpTo same encoding passthrough)
- Zstd encoded stream (pumpTo different encoding → gzip)
- Zstd-encoding sink (throws for unsupported output compression)
- Zstd-encoding sink (identity passthrough via disownEncodingResponsibility)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cases

- Add zstd_content_encoding compat flag (enabled 2026-06-21) to match the
  brotli_content_encoding pattern; workers on old compat dates are unaffected
- Fix DevTools network inspector to decompress zstd response bodies using a
  new ZstdDecompressor in ResponseStreamWrapper, matching gzip/brotli handling
- Fix empty-body ZSTD output: endImpl() now rejects ZSTD encoding even when
  no write() was called, consistent with the non-empty-body error path
- Replace KJ_ASSERT with KJ_FAIL_REQUIRE in ensureIdentityEncoding() else-
  branches so unknown future RPC encoding values throw catchable errors instead
  of aborting in debug or silently corrupting in release builds

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@StilesCrisis StilesCrisis requested review from a team as code owners June 21, 2026 19:18
@github-actions

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@StilesCrisis StilesCrisis changed the title fix: decompress zstd-encoded HTTP response bodies (closes #5112) feat: add zstd content-encoding decompression support Jun 21, 2026
@StilesCrisis

Copy link
Copy Markdown
Author

Closing in favour of two focused PRs: one for the core zstd implementation and one for hardening fixes from code review.

@StilesCrisis

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

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.

2 participants