forked from nytimes/gziphandler
-
Notifications
You must be signed in to change notification settings - Fork 7
/
accepts.go
77 lines (71 loc) · 1.94 KB
/
accepts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package httpcompression
import (
"math"
"strconv"
"strings"
)
const (
// defaultQValue is the default qvalue to assign to an encoding if no explicit qvalue is set.
// This is actually kind of ambiguous in RFC 2616, so hopefully it's correct.
// The examples seem to indicate that it is.
defaultQValue = 1.0
)
// acceptedCompression returns the list of common compression scheme supported by client and server.
func acceptedCompression(accept codings, comps comps) []string {
var s []string
// pick smallest N to do O(N) iterations
if len(accept) < len(comps) {
for k, v := range accept {
if v > 0 && comps[k].comp != nil {
s = append(s, k)
}
}
} else {
for k, v := range comps {
if v.comp != nil && accept[k] > 0 {
s = append(s, k)
}
}
}
return s
}
// parseEncodings attempts to parse a list of codings, per RFC 2616, as might
// appear in an Accept-Encoding header. It returns a map of content-codings to
// quality values.
// Errors encountered during parsing the codings are ignored.
//
// See: http://tools.ietf.org/html/rfc2616#section-14.3.
func parseEncodings(vv []string) codings {
c := make(codings)
for _, v := range vv {
for _, sv := range strings.Split(v, ",") {
coding, qvalue := parseCoding(sv)
if coding == "" {
continue
}
c[coding] = qvalue
}
}
return c
}
// parseCoding parses a single conding (content-coding with an optional qvalue),
// as might appear in an Accept-Encoding header. It attempts to forgive minor
// formatting errors.
func parseCoding(s string) (coding string, qvalue float64) {
qvalue = defaultQValue
p := strings.IndexRune(s, ';')
if p != -1 {
if part := strings.Replace(s[p+1:], " ", "", -1); strings.HasPrefix(part, "q=") {
qvalue, _ = strconv.ParseFloat(part[2:], 64)
if qvalue < 0.0 || math.IsNaN(qvalue) {
qvalue = 0.0
} else if qvalue > 1.0 {
qvalue = 1.0
}
}
} else {
p = len(s)
}
coding = strings.ToLower(strings.TrimSpace(s[:p]))
return
}