Repository navigation
Conversation
|
@alshdavid-machine rebase this |
Only apply brotli compression, or serve a pre-compressed sibling, when the client accepts that coding, and send Vary: Accept-Encoding so caches do not reuse the wrong variant. Fixes #22.
cb61d83 to
eb5d490
Compare
|
In reply to #60 (comment) Rebased
PR #60 now sits on current main with no conflicts. |
| } | ||
|
|
||
| /// Pick the most preferred supported coding from an `Accept-Encoding` header. | ||
| pub fn negotiate(accept_encoding: Option<&str>) -> Option<Encoding> { |
There was a problem hiding this comment.
@alshdavid-machine why are these in the same file as the brotli function?
There was a problem hiding this comment.
They were together because commit eb5d490 moved the old mod.rs body into a single compress.rs verbatim — it carried the HTTP content-negotiation concern (Encoding, negotiate, quality) along with the actual compression function.
Split them so each file owns one concern:
src/platform/compress/compress.rs— justbrotli.src/platform/compress/encoding.rs—Encoding,negotiate,quality.mod.rsre-exports both; the public API (compress::brotli,compress::negotiate,compress::Encoding) is unchanged, sohandler.rscallers are untouched.
cargo check, clippy -D warnings, cargo test (38 passed) and cargo xfmt all clean. Pushed to agent/auto-flash/223da754fb6d as ad93ff2.
There was a problem hiding this comment.
@alshdavid-machine read-only. What is the purpose of this file?
There was a problem hiding this comment.
src/platform/compress/encoding.rs defines the content-encoding negotiation for the server — the logic that decides whether to compress a response with brotli or gzip based on the client's Accept-Encoding header.
Encodingenum (Brotli,Gzip) withname()mapping to the wire tokensbr/gzip.negotiate(Option<&str>)picks the best supported coding: it takes the header, evaluates each supported encoding's quality viaquality(), drops anything withq=0, and returns the highest-preference match (brotli wins ties, since it's listed first in the[Brotli, Gzip]array).quality()parsesAccept-Encodinginto tokens and params, readsq=(defaulting to1.0), and handles the*wildcard as a fallback.
Consumed by src/cmd/serve/handler.rs, which calls compress::negotiate(...) and sets Content-Encoding / Vary on responses. Tests live in encoding_test.rs.
Read-only request — no code changed, nothing committed or pushed.
There was a problem hiding this comment.
Despite offering the ability to negotiate the use of gzip, it appears only brotli is supported for actual compression.
Is there a mechanism to compress with gzip?
There was a problem hiding this comment.
No — nothing produces gzip at request time. The only gzip path is pre-compressed sidecar files.
- JIT (
--compress):src/platform/compress/brotli.rsis the entire compressor, brotli only. Every compression site insrc/cmd/serve/handler.rsgates onencoding == Some(compress::Encoding::Brotli)(lines 359, 403, 518). WhennegotiatereturnsGzip, none of those branches match, so the client gets the uncompressed body and noContent-Encoding. - Sidecars (
--compressoff):handler.rs:441-455looks for a<file>.br/<file>.gzsibling and, if it exists, serves it withContent-Encoding: gzipandVary: Accept-Encoding. This is the only placeEncoding::Gzipis actually honoured — and it is guarded by!config.compress, so it never runs when JIT compression is on.
So negotiation advertises gzip as supported while JIT can't fulfil it. Closing the gap would need a gzip encoder plus a Gzip arm at those three sites; no code changed for this question.
Summary
Accept-Encodinginstead of always claimingbr.--compress, including transpiled SCSS/TS output) now only applies brotli when the client accepts it; otherwise the response is sent uncompressed..brover.gzconsistent with the header's quality values.Vary: Accept-Encodingso shared caches keep separate entries.Testing
cargo test --workspacecargo clippy --all-targets --workspace -- -D warningscargo xfmt --checkFixes #22