Skip to content

CompressionFilter compresses with an encoding the client sent with q=0 in Accept-Encoding #668

Open

Description

@0z5a

CompressionFilterUtils::determineCompressionType (the check CompressionFilterFactory::onRequest uses through getFilterParams) chooses the first gzip or zstd token in Accept-Encoding and ignores its qvalue. A request that says "not gzip" therefore gets a gzip response:

Accept-Encoding Chosen Content-Encoding RFC2616::acceptsEncoding for that coding
gzip gzip true
gzip;q=0 gzip false
zstd; q=0.0 zstd false
zstd;q=0, gzip zstd false (gzip would be fine)

(enableZstd = true. The output is from the repro below on main @ e0cef2c.)

RFC 9110 §12.5.3 says a listed content coding "is acceptable unless it is accompanied by a qvalue of 0", and §12.4.2 defines a qvalue of 0 as "not acceptable". proxygen's own RFC2616::acceptsEncoding already returns false for q=0 (AcceptEncodingTest.QValues in lib/http/test/RFC2616Test.cpp). Only the codec selection in lib/utils/CompressionFilterUtils.h (the find_if in determineCompressionType) skips the check. parseQvalues already returns the qvalue in TokenQPair::second.

Repro (public API only):

CompressionFilterUtils::FactoryOptions opts;
opts.enableZstd = true;
opts.compressibleContentTypes = std::make_shared<std::set<std::string>>(
    std::set<std::string>{"text/html"});
HTTPMessage req;
req.setURL("/index.html");
req.getHeaders().set(HTTP_HEADER_ACCEPT_ENCODING, "gzip;q=0");
auto params = CompressionFilterUtils::getFilterParams(req, opts);
// params->headerEncoding == "gzip"; expected: no FilterParams (folly::none)

Suggested fix: in the find_if predicate, skip tokens whose qvalue is <= 0. This is a four-line change, including a comment. The existing tests are unchanged, including GzipWithQuality (gzip; q=5.0). Picking the highest-q coding instead of the first acceptable one is a separate question, and this fix does not touch it.

Environment: x86_64 Linux, GCC 13.3, proxygen built with getdeps.py build proxygen. The code involved is unchanged on main @ 48f1ccc.

A fix with a regression test is ready. Could this issue be assigned to me? I can then open a pull request.

This report was drafted with Claude Code (claude-opus-5-5); the reproducer output above is from the runs described.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions