Skip to content

Commit 6e14ea4

Browse files
committed
fix(acceptHeaders): handle multi-property accept- item properly
1 parent 2356190 commit 6e14ea4

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

src/acceptHeaders/acceptItem.go

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,55 +7,60 @@ import (
77

88
const qualitySign = ";q="
99
const defaultQuality = 1000
10-
const maxQualityDigits = 3
10+
const maxQualityDecimals = 3
1111

1212
type acceptItem struct {
1313
value string
1414
quality int
1515
}
1616

1717
func parseAcceptItem(input string) acceptItem {
18-
indexQSign := strings.Index(input, qualitySign)
19-
if indexQSign < 0 {
20-
return acceptItem{input, defaultQuality}
18+
value := input
19+
if semiColonIndex := strings.IndexByte(value, ';'); semiColonIndex >= 0 {
20+
value = value[:semiColonIndex]
2121
}
2222

23-
value := input[:indexQSign]
24-
strQuality := input[indexQSign+len(qualitySign):]
25-
if semiColonIndex := strings.IndexByte(strQuality, ';'); semiColonIndex >= 0 {
26-
strQuality = strQuality[:semiColonIndex]
23+
rest := input[len(value):]
24+
qSignIndex := strings.Index(rest, qualitySign)
25+
if qSignIndex < 0 {
26+
return acceptItem{value, defaultQuality}
27+
}
28+
29+
rest = rest[qSignIndex+len(qualitySign):]
30+
if semiColonIndex := strings.IndexByte(rest, ';'); semiColonIndex >= 0 {
31+
rest = rest[:semiColonIndex]
2732
}
28-
strQualityLen := len(strQuality)
33+
qLen := len(rest)
2934

30-
if strQualityLen == 0 {
35+
if qLen == 0 {
3136
return acceptItem{value, defaultQuality}
3237
}
33-
if strQualityLen > 1 && strQuality[1] != '.' {
38+
if qLen > 1 && rest[1] != '.' {
3439
return acceptItem{value, defaultQuality}
3540
}
3641

3742
// "q=1" or q is an invalid value
38-
if strQuality[0] != '0' {
43+
if rest[0] != '0' {
3944
return acceptItem{value, defaultQuality}
4045
}
4146

4247
// "q=0."
43-
if strQualityLen <= 2 {
48+
if qLen <= 2 {
4449
return acceptItem{value, 0}
4550
}
4651

47-
strRest := strQuality[2:]
48-
strRestLen := len(strRest)
49-
if strRestLen > maxQualityDigits {
50-
strRestLen = maxQualityDigits
51-
strRest = strRest[:strRestLen]
52+
rest = rest[2:]
53+
qDecimalLen := len(rest)
54+
if qDecimalLen > maxQualityDecimals {
55+
qDecimalLen = maxQualityDecimals
56+
rest = rest[:qDecimalLen]
5257
}
5358

54-
quality, err := strconv.Atoi(strRest)
59+
quality, err := strconv.Atoi(rest)
5560
if err != nil {
5661
quality = defaultQuality
5762
} else {
58-
missingDigits := maxQualityDigits - strRestLen
63+
missingDigits := maxQualityDecimals - qDecimalLen
5964
for i := 0; i < missingDigits; i++ {
6065
quality *= 10
6166
}

src/acceptHeaders/acceptItem_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ func TestParseAcceptItem(t *testing.T) {
1515
t.Error(output.quality)
1616
}
1717

18+
input = "en-US;level=3"
19+
output = parseAcceptItem(input)
20+
if output.value != "en-US" {
21+
t.Error(output.value)
22+
}
23+
if output.quality != 1000 {
24+
t.Error(output.quality)
25+
}
26+
1827
input = "en-US;q=1"
1928
output = parseAcceptItem(input)
2029
if output.value != "en-US" {
@@ -51,6 +60,15 @@ func TestParseAcceptItem(t *testing.T) {
5160
t.Error(output.quality)
5261
}
5362

63+
input = "en-US;v=7;q=0.66"
64+
output = parseAcceptItem(input)
65+
if output.value != "en-US" {
66+
t.Error(output.value)
67+
}
68+
if output.quality != 660 {
69+
t.Error(output.quality)
70+
}
71+
5472
input = "en-US;q=1.1"
5573
output = parseAcceptItem(input)
5674
if output.value != "en-US" {

src/acceptHeaders/accepts_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func TestParseAccepts2(t *testing.T) {
6262
}
6363

6464
func TestGetPreferredValue(t *testing.T) {
65-
acceptEncoding := "gzip;q=0.9, deflate"
65+
acceptEncoding := "gzip;v=b3;q=0.9, deflate"
6666
accepts := ParseAccepts(acceptEncoding)
6767

6868
var index int

0 commit comments

Comments
 (0)