-
Notifications
You must be signed in to change notification settings - Fork 1
/
negotiator.go
99 lines (81 loc) · 2.45 KB
/
negotiator.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package negotiator
import (
"net/http"
"strings"
)
const (
headerAccept = "Accept"
headerAcceptLanguage = "Accept-Language"
headerAcceptEncoding = "Accept-Encoding"
headerAcceptCharset = "Accept-Charset"
)
type spec struct {
val string
q float64
}
// Specs represents []Spec.
type specs []spec
// Len is to impelement sort.Interface for Specs.
func (ss specs) Len() int {
return len(ss)
}
// Swap is to impelement sort.Interface for Specs.
func (ss specs) Swap(i, j int) {
ss[i], ss[j] = ss[j], ss[i]
}
// Less is to impelement sort.Interface for Specs.
func (ss specs) Less(i, j int) bool {
if ss[i].q > ss[j].q {
return true
}
if ss[i].q == ss[j].q {
if ss[i].val == "*" || strings.HasSuffix(ss[i].val, "/*") {
return true
}
if ss[j].val == "*" || strings.HasSuffix(ss[j].val, "/*") {
return false
}
return i < j
}
return false
}
func (ss specs) hasVal(val string) bool {
for _, spec := range ss {
if spec.val == val {
return true
}
}
return false
}
// Negotiator repensents the HTTP negotiator.
type Negotiator struct {
header http.Header
}
// New creates an instance of Negotiator.
func New(header http.Header) *Negotiator {
return &Negotiator{header}
}
// Type returns the most preferred content type from the HTTP Accept header.
// If nothing accepted, then empty string is returned.
func (n *Negotiator) Type(offers ...string) (bestOffer string) {
parser := newHeaderParser(n.header, true)
return parser.selectOffer(offers, parser.parse(headerAccept))
}
// Language returns the most preferred language from the HTTP Accept-Language
// header. If nothing accepted, then empty string is returned.
func (n *Negotiator) Language(offers ...string) (bestOffer string) {
parser := newHeaderParser(n.header, false)
return parser.selectOffer(offers, parser.parse(headerAcceptLanguage))
}
// Encoding returns the most preferred encoding from the HTTP Accept-Encoding
// header. If nothing accepted, then empty string is returned.
func (n *Negotiator) Encoding(offers ...string) (bestOffer string) {
parser := newHeaderParser(n.header, false)
return parser.selectOffer(offers, parser.parse(headerAcceptEncoding))
}
// Charset returns the most preferred charset from the HTTP Accept-Charset
// header. If nothing accepted, then empty string is returned.
func (n *Negotiator) Charset(offers ...string) (bestOffer string) {
parser := newHeaderParser(n.header, false)
return parser.selectOffer(offers, parser.parse(headerAcceptCharset))
}