Expand description
Route-scoped response compression (DW-027, feature analysis 4.13).
One Compression policy per route drives two steps:
- Negotiation (
negotiate): the first algorithm of the policy’s preference order the request’sAccept-Encodingaccepts wins.q=0codings are treated as refusal;*accepts any. No acceptable overlap means no compression (identity is always permitted; the gateway never answers 406 over compression). - Encoding (
wrap_response): the response body is wrapped inCompressedBody, which compresses CHUNK-BY-CHUNK — every data frame is written through the codec and flushed, and whatever the codec produced is forwarded as the next frame. The gateway never buffers a whole body to compress it; the only buffering is the codec’s own bounded working set plus the not-yet-emitted output of the current chunk. Per-chunk flushing costs a little ratio and buys streaming correctness: a slow/trickling upstream (SSE) reaches the client per chunk instead of at end-of-stream. Content types that must not be delayed (e.g.text/event-stream) are the operator’s call viaexcluded_content_types.
Response eligibility (see decide): never a 1xx/204/304, never a
101 upgrade, never a body that already carries Content-Encoding,
never a zero length, never below min_size when the size is known
(declared Content-Length or the exact size of the gateway’s own
header-less bodies; unknown-length streams are always candidates).
Content-Length is dropped on compression (the encoded
length differs; framing switches to chunked/streamed), and
Content-Encoding: <token> plus Vary: Accept-Encoding (merged into
any existing Vary) are set. Vary is ALSO added to responses that
were candidates but skipped (too small, wrong content type, no
acceptable coding) so shared caches key them correctly alongside
their compressed siblings — the proxy handles that half.
The three codecs are Write-based streaming encoders (flate2 gzip, brotli, zstd) all draining into one shared output sink the wrapper reads compressed bytes back out of; each carries the per-algorithm level clamp (gzip 0-9, brotli 0-11, zstd 0-22; defaults 6/5/3 — zstd 3 and brotli 5 sit at the fast end of their useful range, the right bias for a per-route default on a hot proxy path).
Structs§
- Compressed
Body - Compressing wrapper over a
ProxyBody(DW-027). Streams: every inner data frame goes through the codec and comes back as (at most) one emitted frame of pending output; the codec is finished when the inner stream ends, and any trailing headers observed on the inner stream are re-emitted AFTER the compressed bytes (trailers ride after the body; compression does not touch them). - Compression
Plan - The negotiated coding for one response.
Functions§
- decide
- Decide whether THIS response gets compressed under the policy
(DW-027): status, existing encoding, known size, content type, and
negotiation all have to line up.
None= pass through (the caller still addsVary: Accept-Encodingfor cache correctness). - negotiate
- Negotiate the coding for one response (DW-027): the first policy
algorithm the request accepts wins;
None= serve identity. - wrap_
response - Apply a plan to a response (DW-027): header rewrite + body wrap.
Content-Lengthis removed (the encoded length differs); the encoding token andVary: Accept-Encodingare set.