Skip to content

Commit 5c39590

Browse files
committed
request, header and test case improve
1 parent facc65f commit 5c39590

File tree

4 files changed

+195
-81
lines changed

4 files changed

+195
-81
lines changed

header.go

+20-18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package ahttp
66

77
import (
88
"mime"
9+
"net/http"
910
"path/filepath"
1011
"sort"
1112
"strconv"
@@ -31,6 +32,7 @@ const (
3132
HeaderIfModifiedSince = "If-Modified-Since"
3233
HeaderLocation = "Location"
3334
HeaderLastModified = "Last-Modified"
35+
HeaderMethod = "Method"
3436
HeaderReferer = "Referer"
3537
HeaderServer = "Server"
3638
HeaderSetCookie = "Set-Cookie"
@@ -65,7 +67,7 @@ type (
6567
}
6668

6769
// AcceptSpecs is list of values parsed from header and sorted by
68-
// quality factor
70+
// quality factor.
6971
AcceptSpecs []AcceptSpec
7072
)
7173

@@ -75,10 +77,10 @@ type (
7577

7678
// NegotiateContentType negotiates the response `Content-Type` from the given HTTP
7779
// `Accept` header. The resolve order is- 1) URL extension 2) Accept header
78-
// Most quailfied one based quality factor otherwise default is HTML
79-
func (r *Request) NegotiateContentType() *ContentType {
80+
// Most quailfied one based quality factor otherwise default is HTML.
81+
func NegotiateContentType(req *http.Request) *ContentType {
8082
// 1) URL extension
81-
ext := filepath.Ext(r.URL.Path)
83+
ext := filepath.Ext(req.URL.Path)
8284
switch ext {
8385
case ".html", ".htm", ".json", ".js", ".xml", ".txt":
8486
mimeType := mime.TypeByExtension(ext)
@@ -92,7 +94,7 @@ func (r *Request) NegotiateContentType() *ContentType {
9294
}
9395

9496
// 2) From Accept header
95-
spec := r.ParseAccept(HeaderAccept).MostQualified()
97+
spec := ParseAccept(req, HeaderAccept).MostQualified()
9698
if spec == nil {
9799
return htmlContentType()
98100
}
@@ -108,23 +110,23 @@ func (r *Request) NegotiateContentType() *ContentType {
108110
}
109111

110112
// NegotiateLocale negotiates the `Accept-Language` from the given HTTP
111-
// request. Most quailfied one based quality factor
112-
func (r *Request) NegotiateLocale() *Locale {
113-
return ToLocale(r.ParseAccept(HeaderAcceptLanguage).MostQualified())
113+
// request. Most quailfied one based on quality factor.
114+
func NegotiateLocale(req *http.Request) *Locale {
115+
return ToLocale(ParseAccept(req, HeaderAcceptLanguage).MostQualified())
114116
}
115117

116118
// NegotiateEncoding negotiates the `Accept-Encoding` from the given HTTP
117-
// request. Most quailfied one based quality factor
118-
func (r *Request) NegotiateEncoding() *AcceptSpec {
119-
return r.ParseAccept(HeaderAcceptEncoding).MostQualified()
119+
// request. Most quailfied one based on quality factor.
120+
func NegotiateEncoding(req *http.Request) *AcceptSpec {
121+
return ParseAccept(req, HeaderAcceptEncoding).MostQualified()
120122
}
121123

122124
// ParseContentType resolves the request `Content-Type` from the given HTTP
123125
// request via header `Content-Type`. Partial implementation of
124126
// https://tools.ietf.org/html/rfc1521#section-4 i.e. parsing only
125-
// type, subtype, parameters based on RFC
126-
func (r *Request) ParseContentType() *ContentType {
127-
contentType := r.Header.Get(HeaderContentType)
127+
// type, subtype, parameters based on RFC.
128+
func ParseContentType(req *http.Request) *ContentType {
129+
contentType := req.Header.Get(HeaderContentType)
128130

129131
if ess.IsStrEmpty(contentType) {
130132
return htmlContentType()
@@ -161,8 +163,8 @@ func (r *Request) ParseContentType() *ContentType {
161163
//
162164
// Known issues with WebKit and IE
163165
// http://www.newmediacampaigns.com/blog/browser-rest-http-accept-headers
164-
func (r *Request) ParseAccept(hdrKey string) AcceptSpecs {
165-
hdrValue := r.Header.Get(hdrKey)
166+
func ParseAccept(req *http.Request, hdrKey string) AcceptSpecs {
167+
hdrValue := req.Header.Get(hdrKey)
166168
var specs AcceptSpecs
167169

168170
for _, hv := range strings.Split(hdrValue, ",") {
@@ -241,7 +243,7 @@ func ToLocale(a *AcceptSpec) *Locale {
241243
// Locale methods
242244
//___________________________________
243245

244-
// String is stringer interface
246+
// String is stringer interface.
245247
func (l *Locale) String() string {
246248
return l.Raw
247249
}
@@ -298,7 +300,7 @@ func (a AcceptSpec) GetParam(key string, defaultValue string) string {
298300
}
299301

300302
// MostQualified returns the most quailfied accept spec, since `AcceptSpec` is
301-
// sorted by quaity factor. First position is the most quailfied otherwise `nil`
303+
// sorted by quaity factor. First position is the most quailfied otherwise `nil`.
302304
func (specs AcceptSpecs) MostQualified() *AcceptSpec {
303305
if len(specs) > 0 {
304306
return &specs[0]

header_test.go

+60-55
Original file line numberDiff line numberDiff line change
@@ -13,51 +13,51 @@ import (
1313
)
1414

1515
func TestParseAcceptHeaderLanguage(t *testing.T) {
16-
req1 := createRequest(HeaderAcceptLanguage, "en-us;q=0.0,en;q=0.7, da, en-gb;q=0.8")
17-
specs := req1.ParseAccept(HeaderAcceptLanguage)
16+
req1 := createRawHTTPRequest(HeaderAcceptLanguage, "en-us;q=0.0,en;q=0.7, da, en-gb;q=0.8")
17+
specs := ParseAccept(req1, HeaderAcceptLanguage)
1818
assert.Equal(t, "da", specs.MostQualified().Value)
1919
assert.Equal(t, 4, len(specs))
2020
assert.Equal(t, specs[1].Value, "en-gb")
2121
assert.Equal(t, specs[1].Q, float32(0.8))
2222
assert.Equal(t, specs[2].Value, "en")
2323
assert.Equal(t, specs[2].Q, float32(0.7))
2424

25-
req2 := createRequest(HeaderAcceptLanguage, "en-gb;leve=1;q=0.8, da, en;level=2;q=0.7, en-us;q=gg")
26-
specs = req2.ParseAccept(HeaderAcceptLanguage)
25+
req2 := createRawHTTPRequest(HeaderAcceptLanguage, "en-gb;leve=1;q=0.8, da, en;level=2;q=0.7, en-us;q=gg")
26+
specs = ParseAccept(req2, HeaderAcceptLanguage)
2727
assert.Equal(t, "da", specs.MostQualified().Value)
2828
assert.Equal(t, 4, len(specs))
2929
assert.Equal(t, specs[1].Value, "en-gb")
3030
assert.Equal(t, specs[1].Q, float32(0.8))
3131
assert.Equal(t, specs[2].Value, "en")
3232
assert.Equal(t, specs[2].Q, float32(0.7))
3333

34-
req3 := createRequest(HeaderAcceptLanguage, "zh, en-us; q=0.8, en; q=0.6")
35-
specs = req3.ParseAccept(HeaderAcceptLanguage)
34+
req3 := createRawHTTPRequest(HeaderAcceptLanguage, "zh, en-us; q=0.8, en; q=0.6")
35+
specs = ParseAccept(req3, HeaderAcceptLanguage)
3636
assert.Equal(t, "zh", specs.MostQualified().Value)
3737
assert.Equal(t, 3, len(specs))
3838
assert.Equal(t, specs[1].Value, "en-us")
3939
assert.Equal(t, specs[1].Q, float32(0.8))
4040
assert.Equal(t, specs[2].Value, "en")
4141
assert.Equal(t, specs[2].Q, float32(0.6))
4242

43-
req4 := createRequest(HeaderAcceptLanguage, "en-gb;q=0.8, da, en;level=2;q=0.7, en-us;leve=1;q=gg")
44-
specs = req4.ParseAccept(HeaderAcceptLanguage)
43+
req4 := createRawHTTPRequest(HeaderAcceptLanguage, "en-gb;q=0.8, da, en;level=2;q=0.7, en-us;leve=1;q=gg")
44+
specs = ParseAccept(req4, HeaderAcceptLanguage)
4545
assert.Equal(t, "da", specs.MostQualified().Value)
4646
assert.Equal(t, 4, len(specs))
4747
assert.Equal(t, specs[1].Value, "en-gb")
4848
assert.Equal(t, specs[1].Q, float32(0.8))
4949
assert.Equal(t, specs[2].Value, "en")
5050
assert.Equal(t, specs[2].Q, float32(0.7))
5151

52-
req5 := createRequest(HeaderAcceptLanguage, "zh, en-us; q=wrong, en; q=0.6")
53-
specs = req5.ParseAccept(HeaderAcceptLanguage)
52+
req5 := createRawHTTPRequest(HeaderAcceptLanguage, "zh, en-us; q=wrong, en; q=0.6")
53+
specs = ParseAccept(req5, HeaderAcceptLanguage)
5454
assert.Equal(t, "zh", specs.MostQualified().Value)
5555
assert.Equal(t, 3, len(specs))
5656
assert.Equal(t, specs[1].Value, "en")
5757
assert.Equal(t, specs[1].Q, float32(0.6))
5858

59-
req6 := createRequest(HeaderAcceptLanguage, "es-mx, es, en")
60-
specs = req6.ParseAccept(HeaderAcceptLanguage)
59+
req6 := createRawHTTPRequest(HeaderAcceptLanguage, "es-mx, es, en")
60+
specs = ParseAccept(req6, HeaderAcceptLanguage)
6161
assert.Equal(t, "es-mx", specs.MostQualified().Value)
6262
assert.Equal(t, 3, len(specs))
6363
assert.Equal(t, specs[1].Value, "es")
@@ -67,127 +67,132 @@ func TestParseAcceptHeaderLanguage(t *testing.T) {
6767
}
6868

6969
func TestNegotiateLocale(t *testing.T) {
70-
req1 := createRequest(HeaderAcceptLanguage, "es-mx, es, en")
71-
locale := req1.NegotiateLocale()
70+
req1 := createRawHTTPRequest(HeaderAcceptLanguage, "es-mx, es, en")
71+
locale := NegotiateLocale(req1)
7272
assert.Equal(t, "es-mx", locale.Raw)
7373
assert.Equal(t, "es", locale.Language)
7474
assert.Equal(t, "mx", locale.Region)
7575
assert.Equal(t, "es-mx", locale.String())
7676

77-
req2 := createRequest(HeaderAcceptLanguage, "es")
78-
locale = req2.NegotiateLocale()
77+
req2 := createRawHTTPRequest(HeaderAcceptLanguage, "es")
78+
locale = NegotiateLocale(req2)
7979
assert.Equal(t, "es", locale.Raw)
8080
assert.Equal(t, "es", locale.Language)
8181
assert.Equal(t, "", locale.Region)
8282
assert.Equal(t, "es", locale.String())
8383

84-
req3 := createRequest(HeaderAcceptLanguage, "")
85-
locale = req3.NegotiateLocale()
84+
req3 := createRawHTTPRequest(HeaderAcceptLanguage, "")
85+
locale = NegotiateLocale(req3)
8686
assert.Equal(t, true, locale == nil)
8787
}
8888

8989
func TestNegotiateContentType(t *testing.T) {
90-
req1 := createRequest(HeaderAccept, "audio/*; q=0.2, audio/basic")
91-
contentType := req1.NegotiateContentType()
90+
req1 := createRawHTTPRequest(HeaderAccept, "audio/*; q=0.2, audio/basic")
91+
contentType := NegotiateContentType(req1)
9292
assert.Equal(t, "audio/basic", contentType.String())
9393
assert.Equal(t, "audio/basic", contentType.Mime)
9494
assert.Equal(t, "", contentType.Version())
9595

96-
req2 := createRequest(HeaderAccept, "application/json;version=2")
97-
contentType = req2.NegotiateContentType()
96+
req2 := createRawHTTPRequest(HeaderAccept, "application/json;version=2")
97+
contentType = NegotiateContentType(req2)
9898
assert.Equal(t, "application/json;version=2", contentType.String())
9999
assert.Equal(t, "application/json", contentType.Mime)
100100
assert.Equal(t, "2", contentType.Version())
101101

102-
req3 := createRequest(HeaderAccept, "text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c")
103-
contentType = req3.NegotiateContentType()
102+
req3 := createRawHTTPRequest(HeaderAccept, "text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c")
103+
contentType = NegotiateContentType(req3)
104104
assert.Equal(t, "text/html", contentType.String())
105105
assert.Equal(t, "text/html", contentType.Mime)
106106
assert.Equal(t, "", contentType.Version())
107107

108-
req4 := createRequest(HeaderAccept, "")
109-
contentType = req4.NegotiateContentType()
108+
req4 := createRawHTTPRequest(HeaderAccept, "")
109+
contentType = NegotiateContentType(req4)
110110
assert.Equal(t, "text/html; charset=utf-8", contentType.String())
111111
assert.Equal(t, "text/html", contentType.Mime)
112112
assert.Equal(t, ".html", contentType.Exts[0])
113113
assert.Equal(t, "", contentType.Version())
114114

115-
req := createRequest(HeaderAccept, "application/json")
115+
req := createRawHTTPRequest(HeaderAccept, "application/json")
116116
req.URL, _ = url.Parse("http://localhost:8080/testpath.json")
117-
contentType = req.NegotiateContentType()
117+
// req.Path = req.Raw.URL.Path
118+
contentType = NegotiateContentType(req)
118119
assert.Equal(t, "application/json", contentType.Mime)
119120
assert.Equal(t, ".json", contentType.Exts[0])
120121

121-
req = createRequest(HeaderAccept, "application/json")
122+
req = createRawHTTPRequest(HeaderAccept, "application/json")
122123
req.URL, _ = url.Parse("http://localhost:8080/testpath.html")
123-
contentType = req.NegotiateContentType()
124+
// req.Path = req.Raw.URL.Path
125+
contentType = NegotiateContentType(req)
124126
assert.Equal(t, "text/html; charset=utf-8", contentType.Mime)
125127
assert.Equal(t, ".html", contentType.Exts[0])
126128

127-
req = createRequest(HeaderAccept, "application/json; version=2")
128-
spec := req.ParseAccept(HeaderAccept).MostQualified()
129+
req = createRawHTTPRequest(HeaderAccept, "application/json; version=2")
130+
spec := ParseAccept(req, HeaderAccept).MostQualified()
129131
assert.Equal(t, "2", spec.GetParam("version", "1"))
130132

131-
req = createRequest(HeaderAccept, "application/json")
132-
spec = req.ParseAccept(HeaderAccept).MostQualified()
133+
req = createRawHTTPRequest(HeaderAccept, "application/json")
134+
spec = ParseAccept(req, HeaderAccept).MostQualified()
133135
assert.Equal(t, "1", spec.GetParam("version", "1"))
134136

135-
req = createRequest(HeaderAccept, "application/json; version")
136-
spec = req.ParseAccept(HeaderAccept).MostQualified()
137+
req = createRawHTTPRequest(HeaderAccept, "application/json; version")
138+
spec = ParseAccept(req, HeaderAccept).MostQualified()
137139
assert.Equal(t, "", spec.GetParam("version", "1"))
138140
}
139141

140142
func TestNegotiateEncoding(t *testing.T) {
141-
req1 := createRequest(HeaderAcceptEncoding, "compress;q=0.5, gzip;q=1.0")
142-
encoding := req1.NegotiateEncoding()
143+
req1 := createRawHTTPRequest(HeaderAcceptEncoding, "compress;q=0.5, gzip;q=1.0")
144+
encoding := NegotiateEncoding(req1)
143145
assert.Equal(t, "gzip", encoding.Value)
144146
assert.Equal(t, "gzip;q=1.0", encoding.Raw)
145147

146-
req2 := createRequest(HeaderAcceptEncoding, "gzip;q=1.0, identity; q=0.5, *;q=0")
147-
encoding = req2.NegotiateEncoding()
148+
req2 := createRawHTTPRequest(HeaderAcceptEncoding, "gzip;q=1.0, identity; q=0.5, *;q=0")
149+
encoding = NegotiateEncoding(req2)
148150
assert.Equal(t, "gzip", encoding.Value)
149151
assert.Equal(t, "gzip;q=1.0", encoding.Raw)
150152

151-
req3 := createRequest(HeaderAcceptEncoding, "")
152-
encoding = req3.NegotiateEncoding()
153+
req3 := createRawHTTPRequest(HeaderAcceptEncoding, "")
154+
encoding = NegotiateEncoding(req3)
153155
assert.Equal(t, true, encoding == nil)
154156
}
155157

156158
func TestParseContentType(t *testing.T) {
157-
req1 := createRequest(HeaderContentType, "text/html; charset=utf-8")
158-
contentType := req1.ParseContentType()
159+
req1 := createRawHTTPRequest(HeaderContentType, "text/html; charset=utf-8")
160+
contentType := ParseContentType(req1)
159161
assert.Equal(t, "text/html", contentType.Mime)
160162
assert.Equal(t, "text/html; charset=utf-8", contentType.String())
161163
assert.Equal(t, "utf-8", contentType.Charset("iso-8859-1"))
162164

163-
req2 := createRequest(HeaderContentType, "text/html")
164-
contentType = req2.ParseContentType()
165+
req2 := createRawHTTPRequest(HeaderContentType, "text/html")
166+
contentType = ParseContentType(req2)
165167
assert.Equal(t, "text/html", contentType.Mime)
166168
assert.Equal(t, "text/html", contentType.String())
167169
assert.Equal(t, "iso-8859-1", contentType.Charset("iso-8859-1"))
168170

169-
req3 := createRequest(HeaderContentType, "application/json")
170-
contentType = req3.ParseContentType()
171+
req3 := createRawHTTPRequest(HeaderContentType, "application/json")
172+
contentType = ParseContentType(req3)
171173
assert.Equal(t, "application/json", contentType.Mime)
172174
assert.Equal(t, "application/json", contentType.String())
173175
assert.Equal(t, "", contentType.Charset(""))
174176

175-
req4 := createRequest(HeaderContentType, "")
176-
contentType = req4.ParseContentType()
177+
req4 := createRawHTTPRequest(HeaderContentType, "")
178+
contentType = ParseContentType(req4)
177179
assert.Equal(t, "text/html", contentType.Mime)
178180
assert.Equal(t, "text/html; charset=utf-8", contentType.String())
179181
assert.Equal(t, ".html", contentType.Exts[0])
180182

181-
req5 := createRequest(HeaderContentType, "text/html;charset")
182-
contentType = req5.ParseContentType()
183+
req5 := createRawHTTPRequest(HeaderContentType, "text/html;charset")
184+
contentType = ParseContentType(req5)
183185
assert.Equal(t, "text/html", contentType.Mime)
184186
assert.Equal(t, "text/html;charset", contentType.String())
185187
assert.Equal(t, "", contentType.Charset("iso-8859-1"))
186188
}
187189

188-
func createRequest(hdrKey, value string) *Request {
189-
return &Request{Request: createRawHTTPRequest(hdrKey, value)}
190-
}
190+
// func createRequest(hdrKey, value string) *Request {
191+
// req := &Request{Raw: createRawHTTPRequest(hdrKey, value)}
192+
// req.Path = req.Raw.URL.Path
193+
// req.Header = req.Raw.Header
194+
// return req
195+
// }
191196

192197
func createRawHTTPRequest(hdrKey, value string) *http.Request {
193198
hdr := http.Header{}

0 commit comments

Comments
 (0)