LEFT | RIGHT |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package textproto | 5 package textproto |
6 | 6 |
7 import ( | 7 import ( |
8 "bufio" | 8 "bufio" |
9 "bytes" | 9 "bytes" |
10 "io" | 10 "io" |
11 "reflect" | 11 "reflect" |
12 "strings" | 12 "strings" |
13 "testing" | 13 "testing" |
14 ) | 14 ) |
15 | 15 |
16 type canonicalHeaderKeyTest struct { | 16 type canonicalHeaderKeyTest struct { |
17 in, out string | 17 in, out string |
18 } | 18 } |
19 | 19 |
20 var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{ | 20 var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{ |
21 {"a-b-c", "A-B-C"}, | 21 {"a-b-c", "A-B-C"}, |
22 {"a-1-c", "A-1-C"}, | 22 {"a-1-c", "A-1-C"}, |
23 {"User-Agent", "User-Agent"}, | 23 {"User-Agent", "User-Agent"}, |
24 {"uSER-aGENT", "User-Agent"}, | 24 {"uSER-aGENT", "User-Agent"}, |
25 {"user-agent", "User-Agent"}, | 25 {"user-agent", "User-Agent"}, |
26 {"USER-AGENT", "User-Agent"}, | 26 {"USER-AGENT", "User-Agent"}, |
| 27 // what if some UTF-8 gets in by mistake? It is passed unchanged, even |
| 28 // if the resulting key ends up with some non-capitals in it. This |
| 29 // is correct because CanonicalMIMEHeaderKey is meant for ASCII only. |
| 30 {"üser-agenT", "üser-Agent"}, |
27 } | 31 } |
28 | 32 |
29 func TestCanonicalMIMEHeaderKey(t *testing.T) { | 33 func TestCanonicalMIMEHeaderKey(t *testing.T) { |
30 for _, tt := range canonicalHeaderKeyTests { | 34 for _, tt := range canonicalHeaderKeyTests { |
31 if s := CanonicalMIMEHeaderKey(tt.in); s != tt.out { | 35 if s := CanonicalMIMEHeaderKey(tt.in); s != tt.out { |
32 t.Errorf("CanonicalMIMEHeaderKey(%q) = %q, want %q", tt.
in, s, tt.out) | 36 t.Errorf("CanonicalMIMEHeaderKey(%q) = %q, want %q", tt.
in, s, tt.out) |
33 } | 37 } |
34 } | 38 } |
35 } | 39 } |
36 | 40 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 } | 238 } |
235 if code != tt.wantCode { | 239 if code != tt.wantCode { |
236 t.Errorf("#%d: code=%d, want %d", i, code, tt.wantCode) | 240 t.Errorf("#%d: code=%d, want %d", i, code, tt.wantCode) |
237 } | 241 } |
238 if msg != tt.wantMsg { | 242 if msg != tt.wantMsg { |
239 t.Errorf("#%d: msg=%q, want %q", i, msg, tt.wantMsg) | 243 t.Errorf("#%d: msg=%q, want %q", i, msg, tt.wantMsg) |
240 } | 244 } |
241 } | 245 } |
242 } | 246 } |
243 | 247 |
| 248 func TestCommonHeaders(t *testing.T) { |
| 249 // need to disable the commonHeaders-based optimization |
| 250 // during this check, or we'd not be testing anything |
| 251 oldch := commonHeaders |
| 252 commonHeaders = []string{} |
| 253 defer func() { commonHeaders = oldch }() |
| 254 |
| 255 last := "" |
| 256 for _, h := range oldch { |
| 257 if last > h { |
| 258 t.Errorf("%v is out of order", h) |
| 259 } |
| 260 if last == h { |
| 261 t.Errorf("%v is duplicated", h) |
| 262 } |
| 263 if canon := CanonicalMIMEHeaderKey(h); h != canon { |
| 264 t.Errorf("%v is not canonical", h) |
| 265 } |
| 266 last = h |
| 267 } |
| 268 } |
| 269 |
244 var clientHeaders = strings.Replace(`Host: golang.org | 270 var clientHeaders = strings.Replace(`Host: golang.org |
245 Connection: keep-alive | 271 Connection: keep-alive |
246 Cache-Control: max-age=0 | 272 Cache-Control: max-age=0 |
247 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,i
mage/png,*/*;q=0.5 | 273 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,i
mage/png,*/*;q=0.5 |
248 User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.3 (KHTML,
like Gecko) Chrome/6.0.472.63 Safari/534.3 | 274 User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.3 (KHTML,
like Gecko) Chrome/6.0.472.63 Safari/534.3 |
249 Accept-Encoding: gzip,deflate,sdch | 275 Accept-Encoding: gzip,deflate,sdch |
250 Accept-Language: en-US,en;q=0.8,fr-CH;q=0.6 | 276 Accept-Language: en-US,en;q=0.8,fr-CH;q=0.6 |
251 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 | 277 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 |
252 Cookie: __utma=000000000.0000000000.0000000000.0000000000.0000000000.00; __utmb=
000000000.0.00.0000000000; __utmc=000000000; __utmz=000000000.0000000000.00.0.ut
mcsr=code.google.com|utmccn=(referral)|utmcmd=referral|utmcct=/p/go/issues/detai
l | 278 COOKIE: __utma=000000000.0000000000.0000000000.0000000000.0000000000.00; __utmb=
000000000.0.00.0000000000; __utmc=000000000; __utmz=000000000.0000000000.00.0.ut
mcsr=code.google.com|utmccn=(referral)|utmcmd=referral|utmcct=/p/go/issues/detai
l |
253 Non-Interned: test | 279 Non-Interned: test |
254 | 280 |
255 `, "\n", "\r\n", -1) | 281 `, "\n", "\r\n", -1) |
256 | 282 |
257 var serverHeaders = strings.Replace(`Content-Type: text/html; charset=utf-8 | 283 var serverHeaders = strings.Replace(`Content-Type: text/html; charset=utf-8 |
258 Content-Encoding: gzip | 284 Content-Encoding: gzip |
259 Date: Thu, 27 Sep 2012 09:03:33 GMT | 285 Date: Thu, 27 Sep 2012 09:03:33 GMT |
260 Server: Google Frontend | 286 Server: Google Frontend |
261 Cache-Control: private | 287 Cache-Control: private |
262 Content-Length: 2298 | 288 Content-Length: 2298 |
263 Via: 1.1 proxy.example.com:80 (XXX/n.n.n-nnn) | 289 VIA: 1.1 proxy.example.com:80 (XXX/n.n.n-nnn) |
264 Connection: Close | 290 Connection: Close |
265 Non-Interned: test | 291 Non-Interned: test |
266 | 292 |
267 `, "\n", "\r\n", -1) | 293 `, "\n", "\r\n", -1) |
268 | 294 |
269 func BenchmarkReadMIMEHeader(b *testing.B) { | 295 func BenchmarkReadMIMEHeader(b *testing.B) { |
270 var buf bytes.Buffer | 296 var buf bytes.Buffer |
271 br := bufio.NewReader(&buf) | 297 br := bufio.NewReader(&buf) |
272 r := NewReader(br) | 298 r := NewReader(br) |
273 for i := 0; i < b.N; i++ { | 299 for i := 0; i < b.N; i++ { |
274 var want int | 300 var want int |
| 301 var find string |
275 if (i & 1) == 1 { | 302 if (i & 1) == 1 { |
276 buf.WriteString(clientHeaders) | 303 buf.WriteString(clientHeaders) |
277 want = 10 | 304 want = 10 |
| 305 find = "Cookie" |
278 } else { | 306 } else { |
279 buf.WriteString(serverHeaders) | 307 buf.WriteString(serverHeaders) |
280 want = 9 | 308 want = 9 |
| 309 find = "Via" |
281 } | 310 } |
282 h, err := r.ReadMIMEHeader() | 311 h, err := r.ReadMIMEHeader() |
283 if err != nil { | 312 if err != nil { |
284 b.Fatal(err) | 313 b.Fatal(err) |
285 } | 314 } |
286 if len(h) != want { | 315 if len(h) != want { |
287 b.Fatalf("wrong number of headers: got %d, want %d", len
(h), want) | 316 b.Fatalf("wrong number of headers: got %d, want %d", len
(h), want) |
288 } | 317 } |
289 » } | 318 » » if _, ok := h[find]; !ok { |
290 } | 319 » » » b.Fatalf("did not find key %s", find) |
| 320 » » } |
| 321 » } |
| 322 } |
| 323 |
| 324 func BenchmarkUncommon(b *testing.B) { |
| 325 » var buf bytes.Buffer |
| 326 » br := bufio.NewReader(&buf) |
| 327 » r := NewReader(br) |
| 328 » for i := 0; i < b.N; i++ { |
| 329 » » buf.WriteString("uncommon-header-for-benchmark: foo\r\n\r\n") |
| 330 » » h, err := r.ReadMIMEHeader() |
| 331 » » if err != nil { |
| 332 » » » b.Fatal(err) |
| 333 » » } |
| 334 » » if _, ok := h["Uncommon-Header-For-Benchmark"]; !ok { |
| 335 » » » b.Fatal("Missing result header.") |
| 336 » » } |
| 337 » } |
| 338 } |
LEFT | RIGHT |