Follow-up to #884 and stacksjs/stacks#2462. On 12e3789, the response helper returns an unencoded 200 body for Accept-Encoding: gzip, identity;q=0 when the body is below the compression threshold. The parser's public null result also conflates permitted identity with no acceptable representation.
Reproduction from the repository root:
import { applyResponseCompression } from './packages/bun-router/src/response/compression'
const request = new Request('http://localhost/', {
headers: { 'accept-encoding': 'gzip, identity;q=0' },
})
const response = await applyResponseCompression(new Response('small', {
headers: { 'content-type': 'text/plain', 'content-length': '5' },
}), request)
console.log(response.status, response.headers.get('content-encoding'), await response.text())
// 200 null smallRFC 9110 section 12.5.3 excludes identity when explicitly refused or through *;q=0 without a more specific identity entry: https://www.rfc-editor.org/rfc/rfc9110.html#section-12.5.3.
Implement the missing unencoded-response behavior at the existing response compression boundary:
- Preserve whether identity is acceptable separately from the selected gzip/deflate coding, while keeping the public
negotiateEncodingreturn type compatible. - Compress known-small and unknown-small text responses when identity is refused and a supported coding is acceptable. Size is a heuristic, not permission to send refused content.
- Return an empty 406 when no available representation is acceptable, including types deliberately excluded from compression and range responses. Do not consume or buffer an excluded stream; cancel an abandoned body.
- Preserve bodyless responses, already-encoded responses, and explicit compression-disable behavior. Those remain owned by their existing caller contracts in this bounded helper change. The broader Stacks pipeline issue remains open.
- Preserve security headers, cookies and request IDs on a 406, but remove obsolete representation metadata and prevent caching an empty replacement using the original response's cache policy.
- Cover wildcard precedence, malformed qualities, exact tokens, synchronous common paths, decoded bytes, and real native/generic HTTP dispatch.
- Measure the normal short-body path against the existing source and keep its no-body-materialization behavior.
This is part of making performance comparisons contract-correct. No benchmark configuration changes or installed-dependency patches.