feat: add zstd content-encoding decompression support#6836
feat: add zstd content-encoding decompression support#6836StilesCrisis wants to merge 5 commits into
Conversation
…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>
|
I have read the CLA Document and I hereby sign the CLA 1 out of 2 committers have signed the CLA. |
|
Closing in favour of two focused PRs: one for the core zstd implementation and one for hardening fixes from code review. |
|
I have read the CLA Document and I hereby sign the CLA |
|
Friendly ping? This resolves a real bug and should be simple to review |
Before this PR, responses with
Content-Encoding: zstdwere passed through as raw compressed bytes — workerd had no zstd decompression support. Workers calling.text(),.json(), etc. on such responses received garbled data.ZstdAsyncInputStreamstreaming decompressor insystem-streams.c++andreadable-source.c++, modeled after the existing gzip/brotli implementations"zstd"intogetContentEncoding()behind a newzstd_content_encodingcompat flag (enabled 2026-06-21), matching thebrotli_content_encodingpatternzstd @3to theStreamEncodingcapnp enumBefore 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