Ferron currently appears to use the order of values in Accept-Encoding as the tie-breaker when selecting a precompressed or dynamically compressed response.
This makes modern browsers receive gzip instead of br/zstd, because Chrome/Chromium and Firefox commonly send:
Accept-Encoding: gzip, deflate, br, zstd
With all variants available, Ferron selects .gz first.
Environment
- Ferron: 2.7.0
- Branch checked: develop-2.x
- Observed browser defaults:
- Chromium 148: gzip, deflate, br, zstd
- Firefox 150: gzip, deflate, br, zstd
Reproduction
Prepare a static file with all precompressed variants:
mkdir -p /tmp/ferron-ae-test
cp README.md /tmp/ferron-ae-test/big.js
ferron-precompress /tmp/ferron-ae-test/big.js
Run Ferron:
ferron --config-string ':18081 {
root "/tmp/ferron-ae-test"
precompressed
}'
Test:
curl -sI -H "Accept-Encoding: gzip, deflate, br, zstd" \
http://localhost:18081/big.js | grep -i content-encoding
curl -sI -H "Accept-Encoding: br" \
http://localhost:18081/big.js | grep -i content-encoding
Actual:
content-encoding: gzip
content-encoding: br
Observed behavior
When all precompressed variants exist:
gzip, deflate, br, zstd -> gzip
br, gzip, deflate, zstd -> br
zstd, br, gzip, deflate -> zstd
gzip;q=0.1, br;q=1, zstd;q=0.9, deflate;q=0.2 -> br
Dynamic static compression without precompressed shows the same ordering behavior.
There also appears to be a related q=0 issue. For example, if .gz is missing but .br exists:
Accept-Encoding: gzip, br;q=0 -> br
br should not be selected when its qvalue is 0.
Expected behavior
Ferron should perform Accept-Encoding negotiation according to qvalues, not raw header order.
Expected behavior:
- Higher valid q values win.
- q=0 means the encoding is not acceptable.
- When multiple supported encodings have the same qvalue, Ferron should use its own server-side preference order.
- By default, when the client supports modern encodings with equal qvalues, Ferron should prefer modern compression over older encodings.
For example, with all variants available:
Accept-Encoding: gzip, deflate, br, zstd
Ferron should choose br or zstd according to its documented server-side preference, not gzip just because it appears first in the browser header.
This appears to affect at least:
- precompressed static file selection
- dynamic static compression
- the dcompress module
Ferron currently appears to use the order of values in
Accept-Encodingas the tie-breaker when selecting a precompressed or dynamically compressed response.This makes modern browsers receive
gzipinstead ofbr/zstd, because Chrome/Chromium and Firefox commonly send:Accept-Encoding: gzip, deflate, br, zstdWith all variants available, Ferron selects .gz first.
Environment
Reproduction
Prepare a static file with all precompressed variants:
Run Ferron:
Test:
Actual:
Observed behavior
When all precompressed variants exist:
Dynamic static compression without precompressed shows the same ordering behavior.
There also appears to be a related q=0 issue. For example, if .gz is missing but .br exists:
Accept-Encoding: gzip, br;q=0 -> brbr should not be selected when its qvalue is 0.
Expected behavior
Ferron should perform Accept-Encoding negotiation according to qvalues, not raw header order.
Expected behavior:
For example, with all variants available:
Accept-Encoding: gzip, deflate, br, zstdFerron should choose br or zstd according to its documented server-side preference, not gzip just because it appears first in the browser header.
This appears to affect at least: