Use correct default weight in Accept-Encoding
This commit is contained in:
parent
a762cce430
commit
d339bfc8d2
2 changed files with 31 additions and 59 deletions
|
@ -1,6 +1,7 @@
|
|||
package compress
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -19,7 +20,7 @@ const (
|
|||
|
||||
type Encoding struct {
|
||||
Type string
|
||||
Weight *float64
|
||||
Weight float64
|
||||
}
|
||||
|
||||
func getCompressionType(acceptEncoding []string, defaultType string) string {
|
||||
|
@ -37,11 +38,11 @@ func getCompressionType(acceptEncoding []string, defaultType string) string {
|
|||
|
||||
encoding := encodings[0]
|
||||
|
||||
if encoding.Type == identityName && encoding.Weight != nil && *encoding.Weight == 0 {
|
||||
if encoding.Type == identityName && encoding.Weight == 0 {
|
||||
return notAcceptable
|
||||
}
|
||||
|
||||
if encoding.Type == wildcardName && encoding.Weight != nil && *encoding.Weight == 0 {
|
||||
if encoding.Type == wildcardName && encoding.Weight == 0 {
|
||||
return notAcceptable
|
||||
}
|
||||
|
||||
|
@ -83,11 +84,13 @@ func parseAcceptEncoding(acceptEncoding []string) ([]Encoding, bool) {
|
|||
continue
|
||||
}
|
||||
|
||||
var weight *float64
|
||||
// If no "q" parameter is present, the default weight is 1.
|
||||
// https://www.rfc-editor.org/rfc/rfc9110.html#name-quality-values
|
||||
weight := 1.0
|
||||
if len(parsed) > 1 && strings.HasPrefix(parsed[1], "q=") {
|
||||
w, _ := strconv.ParseFloat(strings.TrimPrefix(parsed[1], "q="), 64)
|
||||
|
||||
weight = &w
|
||||
weight = w
|
||||
hasWeight = true
|
||||
}
|
||||
|
||||
|
@ -98,41 +101,9 @@ func parseAcceptEncoding(acceptEncoding []string) ([]Encoding, bool) {
|
|||
}
|
||||
}
|
||||
|
||||
slices.SortFunc(encodings, compareEncoding)
|
||||
slices.SortFunc(encodings, func(a, b Encoding) int {
|
||||
return cmp.Compare(b.Weight, a.Weight)
|
||||
})
|
||||
|
||||
return encodings, hasWeight
|
||||
}
|
||||
|
||||
func compareEncoding(a, b Encoding) int {
|
||||
lhs, rhs := a.Weight, b.Weight
|
||||
|
||||
if lhs == nil && rhs == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
if lhs == nil && *rhs == 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
if lhs == nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
if rhs == nil && *lhs == 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
if rhs == nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
if *lhs < *rhs {
|
||||
return 1
|
||||
}
|
||||
|
||||
if *lhs > *rhs {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -74,6 +74,11 @@ func Test_getCompressionType(t *testing.T) {
|
|||
values: []string{"gzip, *;q=0"},
|
||||
expected: gzipName,
|
||||
},
|
||||
{
|
||||
desc: "mixed weight",
|
||||
values: []string{"gzip, br;q=0.9"},
|
||||
expected: gzipName,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
@ -98,10 +103,10 @@ func Test_parseAcceptEncoding(t *testing.T) {
|
|||
desc: "weight",
|
||||
values: []string{"br;q=1.0, zstd;q=0.9, gzip;q=0.8, *;q=0.1"},
|
||||
expected: []Encoding{
|
||||
{Type: brotliName, Weight: ptr[float64](1)},
|
||||
{Type: zstdName, Weight: ptr(0.9)},
|
||||
{Type: gzipName, Weight: ptr(0.8)},
|
||||
{Type: wildcardName, Weight: ptr(0.1)},
|
||||
{Type: brotliName, Weight: 1},
|
||||
{Type: zstdName, Weight: 0.9},
|
||||
{Type: gzipName, Weight: 0.8},
|
||||
{Type: wildcardName, Weight: 0.1},
|
||||
},
|
||||
assertWeight: assert.True,
|
||||
},
|
||||
|
@ -109,10 +114,10 @@ func Test_parseAcceptEncoding(t *testing.T) {
|
|||
desc: "mixed",
|
||||
values: []string{"zstd,gzip, br;q=1.0, *;q=0"},
|
||||
expected: []Encoding{
|
||||
{Type: brotliName, Weight: ptr[float64](1)},
|
||||
{Type: zstdName},
|
||||
{Type: gzipName},
|
||||
{Type: wildcardName, Weight: ptr[float64](0)},
|
||||
{Type: zstdName, Weight: 1},
|
||||
{Type: gzipName, Weight: 1},
|
||||
{Type: brotliName, Weight: 1},
|
||||
{Type: wildcardName, Weight: 0},
|
||||
},
|
||||
assertWeight: assert.True,
|
||||
},
|
||||
|
@ -120,10 +125,10 @@ func Test_parseAcceptEncoding(t *testing.T) {
|
|||
desc: "no weight",
|
||||
values: []string{"zstd, gzip, br, *"},
|
||||
expected: []Encoding{
|
||||
{Type: zstdName},
|
||||
{Type: gzipName},
|
||||
{Type: brotliName},
|
||||
{Type: wildcardName},
|
||||
{Type: zstdName, Weight: 1},
|
||||
{Type: gzipName, Weight: 1},
|
||||
{Type: brotliName, Weight: 1},
|
||||
{Type: wildcardName, Weight: 1},
|
||||
},
|
||||
assertWeight: assert.False,
|
||||
},
|
||||
|
@ -131,9 +136,9 @@ func Test_parseAcceptEncoding(t *testing.T) {
|
|||
desc: "weight and identity",
|
||||
values: []string{"gzip;q=1.0, identity; q=0.5, *;q=0"},
|
||||
expected: []Encoding{
|
||||
{Type: gzipName, Weight: ptr[float64](1)},
|
||||
{Type: identityName, Weight: ptr(0.5)},
|
||||
{Type: wildcardName, Weight: ptr[float64](0)},
|
||||
{Type: gzipName, Weight: 1},
|
||||
{Type: identityName, Weight: 0.5},
|
||||
{Type: wildcardName, Weight: 0},
|
||||
},
|
||||
assertWeight: assert.True,
|
||||
},
|
||||
|
@ -150,7 +155,3 @@ func Test_parseAcceptEncoding(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func ptr[T any](t T) *T {
|
||||
return &t
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue