Three inconsistencies between what the headers promised and what went
out on the socket:
- headers_render() announced "Content-Encoding: chunked" on every
streaming response the client had not asked to compress. chunked is a
transfer coding, not a content coding. Apache rewrote the response and
it went unnoticed; nginx forwards the header as it stands, and a
browser that meets a content coding it does not know refuses the whole
body. Transfer-Encoding: chunked, right below, already says it.
- the deflate stream was built without stating the window, and the
filter then emits raw deflate, while Content-Encoding: deflate
promises the zlib wrapper of RFC 1950. Whoever asked for deflate got
bytes that could not be inflated as announced.
- get_encoding() compared the tokens of Accept-Encoding as they came out
of explode(), with their leading space and their quality attached.
"gzip, deflate, br" only ever matched its first token, and a coding
refused with q=0 was taken as accepted.
Checked on the daemon socket, reading the raw stream and inflating it:
gzip and deflate both come out whole across several chunks, every chunk
self contained, the blocks paired and nothing duplicated; with no
Accept-Encoding no Content-Encoding is sent at all.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014M1jiEq9cHdE5SE5j6vFuE