traefik/pkg/middlewares/compress/acceptencoding_test.go
Romain 496f00c7c2
Revert compress middleware algorithms priority to v2 behavior
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2025-03-28 11:30:05 +01:00

275 lines
7.5 KiB
Go

package compress
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
)
func Test_getCompressionEncoding(t *testing.T) {
testCases := []struct {
desc string
acceptEncoding []string
defaultEncoding string
supportedEncodings []string
expected string
}{
{
desc: "Empty Accept-Encoding",
acceptEncoding: []string{""},
expected: identityName,
},
{
desc: "gzip > br (no weight)",
acceptEncoding: []string{"gzip, br"},
expected: gzipName,
},
{
desc: "gzip > br > zstd (no weight)",
acceptEncoding: []string{"gzip, br, zstd"},
expected: gzipName,
},
{
desc: "known compression encoding (no weight)",
acceptEncoding: []string{"compress, gzip"},
expected: gzipName,
},
{
desc: "unknown compression encoding (no weight), no encoding",
acceptEncoding: []string{"compress, rar"},
expected: notAcceptable,
},
{
desc: "wildcard returns the default compression encoding",
acceptEncoding: []string{"*"},
expected: gzipName,
},
{
desc: "wildcard returns the custom default compression encoding",
acceptEncoding: []string{"*"},
defaultEncoding: brotliName,
expected: brotliName,
},
{
desc: "follows weight",
acceptEncoding: []string{"br;q=0.8, gzip;q=1.0, *;q=0.1"},
expected: gzipName,
},
{
desc: "identity with higher weight is preferred",
acceptEncoding: []string{"br;q=0.8, identity;q=1.0"},
expected: identityName,
},
{
desc: "identity with equal weight is not preferred",
acceptEncoding: []string{"br;q=0.8, identity;q=0.8"},
expected: brotliName,
},
{
desc: "ignore unknown compression encoding",
acceptEncoding: []string{"compress;q=1.0, gzip;q=0.5"},
expected: gzipName,
},
{
desc: "fallback on non-zero compression encoding",
acceptEncoding: []string{"compress;q=1.0, gzip, identity;q=0"},
expected: gzipName,
},
{
desc: "not acceptable (identity)",
acceptEncoding: []string{"compress;q=1.0, identity;q=0"},
expected: notAcceptable,
},
{
desc: "not acceptable (wildcard)",
acceptEncoding: []string{"compress;q=1.0, *;q=0"},
expected: notAcceptable,
},
{
desc: "non-zero is higher than 0",
acceptEncoding: []string{"gzip, *;q=0"},
expected: gzipName,
},
{
desc: "zstd forbidden, brotli first",
acceptEncoding: []string{"zstd, gzip, br"},
supportedEncodings: []string{brotliName, gzipName},
expected: brotliName,
},
{
desc: "follows weight, ignores forbidden encoding",
acceptEncoding: []string{"br;q=0.8, gzip;q=1.0, *;q=0.1"},
supportedEncodings: []string{zstdName, brotliName},
expected: brotliName,
},
{
desc: "mixed weight",
acceptEncoding: []string{"gzip, br;q=0.9"},
supportedEncodings: []string{gzipName, brotliName},
expected: gzipName,
},
{
desc: "Zero weights, no compression",
acceptEncoding: []string{"br;q=0, gzip;q=0, zstd;q=0"},
expected: notAcceptable,
},
{
desc: "Zero weights, default encoding, no compression",
acceptEncoding: []string{"br;q=0, gzip;q=0, zstd;q=0"},
defaultEncoding: "br",
expected: notAcceptable,
},
{
desc: "Same weight, first supported encoding",
acceptEncoding: []string{"br;q=1.0, gzip;q=1.0, zstd;q=1.0"},
expected: gzipName,
},
{
desc: "Same weight, first supported encoding, order has no effect",
acceptEncoding: []string{"br;q=1.0, zstd;q=1.0, gzip;q=1.0"},
expected: gzipName,
},
{
desc: "Same weight, first supported encoding, defaultEncoding has no effect",
acceptEncoding: []string{"br;q=1.0, zstd;q=1.0, gzip;q=1.0"},
defaultEncoding: "br",
expected: gzipName,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
if test.supportedEncodings == nil {
test.supportedEncodings = defaultSupportedEncodings
}
conf := dynamic.Compress{
Encodings: test.supportedEncodings,
DefaultEncoding: test.defaultEncoding,
}
h, err := New(context.Background(), nil, conf, "test")
require.NoError(t, err)
c, ok := h.(*compress)
require.True(t, ok)
encoding := c.getCompressionEncoding(test.acceptEncoding)
assert.Equal(t, test.expected, encoding)
})
}
}
func Test_parseAcceptEncoding(t *testing.T) {
testCases := []struct {
desc string
values []string
supportedEncodings []string
expected []Encoding
assertWeight assert.BoolAssertionFunc
}{
{
desc: "weight",
values: []string{"br;q=1.0, zstd;q=0.9, gzip;q=0.8, *;q=0.1"},
expected: []Encoding{
{Type: brotliName, Weight: 1},
{Type: zstdName, Weight: 0.9},
{Type: gzipName, Weight: 0.8},
{Type: wildcardName, Weight: 0.1},
},
assertWeight: assert.True,
},
{
desc: "weight with supported encodings",
values: []string{"br;q=1.0, zstd;q=0.9, gzip;q=0.8, *;q=0.1"},
supportedEncodings: []string{brotliName, gzipName},
expected: []Encoding{
{Type: brotliName, Weight: 1},
{Type: gzipName, Weight: 0.8},
{Type: wildcardName, Weight: 0.1},
},
assertWeight: assert.True,
},
{
desc: "mixed",
values: []string{"zstd,gzip, br;q=1.0, *;q=0"},
expected: []Encoding{
{Type: zstdName, Weight: 1},
{Type: gzipName, Weight: 1},
{Type: brotliName, Weight: 1},
},
assertWeight: assert.True,
},
{
desc: "mixed with supported encodings",
values: []string{"zstd,gzip, br;q=1.0, *;q=0"},
supportedEncodings: []string{zstdName},
expected: []Encoding{
{Type: zstdName, Weight: 1},
},
assertWeight: assert.True,
},
{
desc: "no weight",
values: []string{"zstd, gzip, br, *"},
expected: []Encoding{
{Type: zstdName, Weight: 1},
{Type: gzipName, Weight: 1},
{Type: brotliName, Weight: 1},
{Type: wildcardName, Weight: 1},
},
assertWeight: assert.False,
},
{
desc: "no weight with supported encodings",
values: []string{"zstd, gzip, br, *"},
supportedEncodings: []string{"gzip"},
expected: []Encoding{
{Type: gzipName, Weight: 1},
{Type: wildcardName, Weight: 1},
},
assertWeight: assert.False,
},
{
desc: "weight and identity",
values: []string{"gzip;q=1.0, identity; q=0.5, *;q=0"},
expected: []Encoding{
{Type: gzipName, Weight: 1},
{Type: identityName, Weight: 0.5},
},
assertWeight: assert.True,
},
{
desc: "weight and identity",
values: []string{"gzip;q=1.0, identity; q=0.5, *;q=0"},
supportedEncodings: []string{"br"},
expected: []Encoding{
{Type: identityName, Weight: 0.5},
},
assertWeight: assert.True,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
if test.supportedEncodings == nil {
test.supportedEncodings = defaultSupportedEncodings
}
supportedEncodings := buildSupportedEncodings(test.supportedEncodings)
aes := parseAcceptableEncodings(test.values, supportedEncodings)
assert.Equal(t, test.expected, aes)
})
}
}