Skip to content

Bug: Precompressed and dynamic compression choose gzip over br/zstd when browser sends default Accept-Encoding order #709

@edehan

Description

@edehan

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions