Compress middleware: matchAcceptEncoding uses substring match and ignores q=0
Author: queeliusCreated Mar 25, 2026Updated Apr 10, 2026
Description
The matchAcceptEncoding function in middleware/compress.go uses strings.Contains to match encoding names in the Accept-Encoding header. This has two problems:
1. Substring matching produces false positives
func matchAcceptEncoding(accepted []string, encoding string) bool {
for _, v := range accepted {
if strings.Contains(v, encoding) { // substring match, not exact
return true
}
}
return false
}For example:
Accept-Encoding: brincorrectly matches encodingb(since"br"contains"b")Accept-Encoding: bgzipincorrectly matches encodinggzip
2. Quality value q=0 is ignored
Per RFC 9110 Section 12.5.3, a quality value of q=0 means the encoding is not acceptable. But strings.Contains("gzip;q=0", "gzip") returns true, so the middleware will compress with gzip even when the client explicitly rejects it.
Reproduction
// These all incorrectly return true:
matchAcceptEncoding([]string{"gzip;q=0"}, "gzip") // should be false (q=0 = not acceptable)
matchAcceptEncoding([]string{"br"}, "b") // should be false (not exact match)
matchAcceptEncoding([]string{"bgzip"}, "gzip") // should be false (not exact match)Fix
Parse the encoding name properly by splitting on ; to separate quality parameters, trimming whitespace, performing exact string comparison, and rejecting q=0.
Source: go-chi/chi