github.com/zach-klippenstein/go@v0.0.0-20150108044943-fcfbeb3adf58/src/net/http/request_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package http_test 6 7 import ( 8 "bufio" 9 "bytes" 10 "encoding/base64" 11 "fmt" 12 "io" 13 "io/ioutil" 14 "mime/multipart" 15 . "net/http" 16 "net/http/httptest" 17 "net/url" 18 "os" 19 "reflect" 20 "regexp" 21 "strings" 22 "testing" 23 ) 24 25 func TestQuery(t *testing.T) { 26 req := &Request{Method: "GET"} 27 req.URL, _ = url.Parse("http://www.google.com/search?q=foo&q=bar") 28 if q := req.FormValue("q"); q != "foo" { 29 t.Errorf(`req.FormValue("q") = %q, want "foo"`, q) 30 } 31 } 32 33 func TestPostQuery(t *testing.T) { 34 req, _ := NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not", 35 strings.NewReader("z=post&both=y&prio=2&empty=")) 36 req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") 37 38 if q := req.FormValue("q"); q != "foo" { 39 t.Errorf(`req.FormValue("q") = %q, want "foo"`, q) 40 } 41 if z := req.FormValue("z"); z != "post" { 42 t.Errorf(`req.FormValue("z") = %q, want "post"`, z) 43 } 44 if bq, found := req.PostForm["q"]; found { 45 t.Errorf(`req.PostForm["q"] = %q, want no entry in map`, bq) 46 } 47 if bz := req.PostFormValue("z"); bz != "post" { 48 t.Errorf(`req.PostFormValue("z") = %q, want "post"`, bz) 49 } 50 if qs := req.Form["q"]; !reflect.DeepEqual(qs, []string{"foo", "bar"}) { 51 t.Errorf(`req.Form["q"] = %q, want ["foo", "bar"]`, qs) 52 } 53 if both := req.Form["both"]; !reflect.DeepEqual(both, []string{"y", "x"}) { 54 t.Errorf(`req.Form["both"] = %q, want ["y", "x"]`, both) 55 } 56 if prio := req.FormValue("prio"); prio != "2" { 57 t.Errorf(`req.FormValue("prio") = %q, want "2" (from body)`, prio) 58 } 59 if empty := req.FormValue("empty"); empty != "" { 60 t.Errorf(`req.FormValue("empty") = %q, want "" (from body)`, empty) 61 } 62 } 63 64 func TestPatchQuery(t *testing.T) { 65 req, _ := NewRequest("PATCH", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not", 66 strings.NewReader("z=post&both=y&prio=2&empty=")) 67 req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") 68 69 if q := req.FormValue("q"); q != "foo" { 70 t.Errorf(`req.FormValue("q") = %q, want "foo"`, q) 71 } 72 if z := req.FormValue("z"); z != "post" { 73 t.Errorf(`req.FormValue("z") = %q, want "post"`, z) 74 } 75 if bq, found := req.PostForm["q"]; found { 76 t.Errorf(`req.PostForm["q"] = %q, want no entry in map`, bq) 77 } 78 if bz := req.PostFormValue("z"); bz != "post" { 79 t.Errorf(`req.PostFormValue("z") = %q, want "post"`, bz) 80 } 81 if qs := req.Form["q"]; !reflect.DeepEqual(qs, []string{"foo", "bar"}) { 82 t.Errorf(`req.Form["q"] = %q, want ["foo", "bar"]`, qs) 83 } 84 if both := req.Form["both"]; !reflect.DeepEqual(both, []string{"y", "x"}) { 85 t.Errorf(`req.Form["both"] = %q, want ["y", "x"]`, both) 86 } 87 if prio := req.FormValue("prio"); prio != "2" { 88 t.Errorf(`req.FormValue("prio") = %q, want "2" (from body)`, prio) 89 } 90 if empty := req.FormValue("empty"); empty != "" { 91 t.Errorf(`req.FormValue("empty") = %q, want "" (from body)`, empty) 92 } 93 } 94 95 type stringMap map[string][]string 96 type parseContentTypeTest struct { 97 shouldError bool 98 contentType stringMap 99 } 100 101 var parseContentTypeTests = []parseContentTypeTest{ 102 {false, stringMap{"Content-Type": {"text/plain"}}}, 103 // Empty content type is legal - shoult be treated as 104 // application/octet-stream (RFC 2616, section 7.2.1) 105 {false, stringMap{}}, 106 {true, stringMap{"Content-Type": {"text/plain; boundary="}}}, 107 {false, stringMap{"Content-Type": {"application/unknown"}}}, 108 } 109 110 func TestParseFormUnknownContentType(t *testing.T) { 111 for i, test := range parseContentTypeTests { 112 req := &Request{ 113 Method: "POST", 114 Header: Header(test.contentType), 115 Body: ioutil.NopCloser(strings.NewReader("body")), 116 } 117 err := req.ParseForm() 118 switch { 119 case err == nil && test.shouldError: 120 t.Errorf("test %d should have returned error", i) 121 case err != nil && !test.shouldError: 122 t.Errorf("test %d should not have returned error, got %v", i, err) 123 } 124 } 125 } 126 127 func TestParseFormInitializeOnError(t *testing.T) { 128 nilBody, _ := NewRequest("POST", "http://www.google.com/search?q=foo", nil) 129 tests := []*Request{ 130 nilBody, 131 {Method: "GET", URL: nil}, 132 } 133 for i, req := range tests { 134 err := req.ParseForm() 135 if req.Form == nil { 136 t.Errorf("%d. Form not initialized, error %v", i, err) 137 } 138 if req.PostForm == nil { 139 t.Errorf("%d. PostForm not initialized, error %v", i, err) 140 } 141 } 142 } 143 144 func TestMultipartReader(t *testing.T) { 145 req := &Request{ 146 Method: "POST", 147 Header: Header{"Content-Type": {`multipart/form-data; boundary="foo123"`}}, 148 Body: ioutil.NopCloser(new(bytes.Buffer)), 149 } 150 multipart, err := req.MultipartReader() 151 if multipart == nil { 152 t.Errorf("expected multipart; error: %v", err) 153 } 154 155 req.Header = Header{"Content-Type": {"text/plain"}} 156 multipart, err = req.MultipartReader() 157 if multipart != nil { 158 t.Error("unexpected multipart for text/plain") 159 } 160 } 161 162 func TestParseMultipartForm(t *testing.T) { 163 req := &Request{ 164 Method: "POST", 165 Header: Header{"Content-Type": {`multipart/form-data; boundary="foo123"`}}, 166 Body: ioutil.NopCloser(new(bytes.Buffer)), 167 } 168 err := req.ParseMultipartForm(25) 169 if err == nil { 170 t.Error("expected multipart EOF, got nil") 171 } 172 173 req.Header = Header{"Content-Type": {"text/plain"}} 174 err = req.ParseMultipartForm(25) 175 if err != ErrNotMultipart { 176 t.Error("expected ErrNotMultipart for text/plain") 177 } 178 } 179 180 func TestRedirect(t *testing.T) { 181 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 182 switch r.URL.Path { 183 case "/": 184 w.Header().Set("Location", "/foo/") 185 w.WriteHeader(StatusSeeOther) 186 case "/foo/": 187 fmt.Fprintf(w, "foo") 188 default: 189 w.WriteHeader(StatusBadRequest) 190 } 191 })) 192 defer ts.Close() 193 194 var end = regexp.MustCompile("/foo/$") 195 r, err := Get(ts.URL) 196 if err != nil { 197 t.Fatal(err) 198 } 199 r.Body.Close() 200 url := r.Request.URL.String() 201 if r.StatusCode != 200 || !end.MatchString(url) { 202 t.Fatalf("Get got status %d at %q, want 200 matching /foo/$", r.StatusCode, url) 203 } 204 } 205 206 func TestSetBasicAuth(t *testing.T) { 207 r, _ := NewRequest("GET", "http://example.com/", nil) 208 r.SetBasicAuth("Aladdin", "open sesame") 209 if g, e := r.Header.Get("Authorization"), "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; g != e { 210 t.Errorf("got header %q, want %q", g, e) 211 } 212 } 213 214 func TestMultipartRequest(t *testing.T) { 215 // Test that we can read the values and files of a 216 // multipart request with FormValue and FormFile, 217 // and that ParseMultipartForm can be called multiple times. 218 req := newTestMultipartRequest(t) 219 if err := req.ParseMultipartForm(25); err != nil { 220 t.Fatal("ParseMultipartForm first call:", err) 221 } 222 defer req.MultipartForm.RemoveAll() 223 validateTestMultipartContents(t, req, false) 224 if err := req.ParseMultipartForm(25); err != nil { 225 t.Fatal("ParseMultipartForm second call:", err) 226 } 227 validateTestMultipartContents(t, req, false) 228 } 229 230 func TestMultipartRequestAuto(t *testing.T) { 231 // Test that FormValue and FormFile automatically invoke 232 // ParseMultipartForm and return the right values. 233 req := newTestMultipartRequest(t) 234 defer func() { 235 if req.MultipartForm != nil { 236 req.MultipartForm.RemoveAll() 237 } 238 }() 239 validateTestMultipartContents(t, req, true) 240 } 241 242 func TestMissingFileMultipartRequest(t *testing.T) { 243 // Test that FormFile returns an error if 244 // the named file is missing. 245 req := newTestMultipartRequest(t) 246 testMissingFile(t, req) 247 } 248 249 // Test that FormValue invokes ParseMultipartForm. 250 func TestFormValueCallsParseMultipartForm(t *testing.T) { 251 req, _ := NewRequest("POST", "http://www.google.com/", strings.NewReader("z=post")) 252 req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") 253 if req.Form != nil { 254 t.Fatal("Unexpected request Form, want nil") 255 } 256 req.FormValue("z") 257 if req.Form == nil { 258 t.Fatal("ParseMultipartForm not called by FormValue") 259 } 260 } 261 262 // Test that FormFile invokes ParseMultipartForm. 263 func TestFormFileCallsParseMultipartForm(t *testing.T) { 264 req := newTestMultipartRequest(t) 265 if req.Form != nil { 266 t.Fatal("Unexpected request Form, want nil") 267 } 268 req.FormFile("") 269 if req.Form == nil { 270 t.Fatal("ParseMultipartForm not called by FormFile") 271 } 272 } 273 274 // Test that ParseMultipartForm errors if called 275 // after MultipartReader on the same request. 276 func TestParseMultipartFormOrder(t *testing.T) { 277 req := newTestMultipartRequest(t) 278 if _, err := req.MultipartReader(); err != nil { 279 t.Fatalf("MultipartReader: %v", err) 280 } 281 if err := req.ParseMultipartForm(1024); err == nil { 282 t.Fatal("expected an error from ParseMultipartForm after call to MultipartReader") 283 } 284 } 285 286 // Test that MultipartReader errors if called 287 // after ParseMultipartForm on the same request. 288 func TestMultipartReaderOrder(t *testing.T) { 289 req := newTestMultipartRequest(t) 290 if err := req.ParseMultipartForm(25); err != nil { 291 t.Fatalf("ParseMultipartForm: %v", err) 292 } 293 defer req.MultipartForm.RemoveAll() 294 if _, err := req.MultipartReader(); err == nil { 295 t.Fatal("expected an error from MultipartReader after call to ParseMultipartForm") 296 } 297 } 298 299 // Test that FormFile errors if called after 300 // MultipartReader on the same request. 301 func TestFormFileOrder(t *testing.T) { 302 req := newTestMultipartRequest(t) 303 if _, err := req.MultipartReader(); err != nil { 304 t.Fatalf("MultipartReader: %v", err) 305 } 306 if _, _, err := req.FormFile(""); err == nil { 307 t.Fatal("expected an error from FormFile after call to MultipartReader") 308 } 309 } 310 311 var readRequestErrorTests = []struct { 312 in string 313 err error 314 }{ 315 {"GET / HTTP/1.1\r\nheader:foo\r\n\r\n", nil}, 316 {"GET / HTTP/1.1\r\nheader:foo\r\n", io.ErrUnexpectedEOF}, 317 {"", io.EOF}, 318 } 319 320 func TestReadRequestErrors(t *testing.T) { 321 for i, tt := range readRequestErrorTests { 322 _, err := ReadRequest(bufio.NewReader(strings.NewReader(tt.in))) 323 if err != tt.err { 324 t.Errorf("%d. got error = %v; want %v", i, err, tt.err) 325 } 326 } 327 } 328 329 func TestNewRequestHost(t *testing.T) { 330 req, err := NewRequest("GET", "http://localhost:1234/", nil) 331 if err != nil { 332 t.Fatal(err) 333 } 334 if req.Host != "localhost:1234" { 335 t.Errorf("Host = %q; want localhost:1234", req.Host) 336 } 337 } 338 339 func TestNewRequestContentLength(t *testing.T) { 340 readByte := func(r io.Reader) io.Reader { 341 var b [1]byte 342 r.Read(b[:]) 343 return r 344 } 345 tests := []struct { 346 r io.Reader 347 want int64 348 }{ 349 {bytes.NewReader([]byte("123")), 3}, 350 {bytes.NewBuffer([]byte("1234")), 4}, 351 {strings.NewReader("12345"), 5}, 352 // Not detected: 353 {struct{ io.Reader }{strings.NewReader("xyz")}, 0}, 354 {io.NewSectionReader(strings.NewReader("x"), 0, 6), 0}, 355 {readByte(io.NewSectionReader(strings.NewReader("xy"), 0, 6)), 0}, 356 } 357 for _, tt := range tests { 358 req, err := NewRequest("POST", "http://localhost/", tt.r) 359 if err != nil { 360 t.Fatal(err) 361 } 362 if req.ContentLength != tt.want { 363 t.Errorf("ContentLength(%T) = %d; want %d", tt.r, req.ContentLength, tt.want) 364 } 365 } 366 } 367 368 var parseHTTPVersionTests = []struct { 369 vers string 370 major, minor int 371 ok bool 372 }{ 373 {"HTTP/0.9", 0, 9, true}, 374 {"HTTP/1.0", 1, 0, true}, 375 {"HTTP/1.1", 1, 1, true}, 376 {"HTTP/3.14", 3, 14, true}, 377 378 {"HTTP", 0, 0, false}, 379 {"HTTP/one.one", 0, 0, false}, 380 {"HTTP/1.1/", 0, 0, false}, 381 {"HTTP/-1,0", 0, 0, false}, 382 {"HTTP/0,-1", 0, 0, false}, 383 {"HTTP/", 0, 0, false}, 384 {"HTTP/1,1", 0, 0, false}, 385 } 386 387 func TestParseHTTPVersion(t *testing.T) { 388 for _, tt := range parseHTTPVersionTests { 389 major, minor, ok := ParseHTTPVersion(tt.vers) 390 if ok != tt.ok || major != tt.major || minor != tt.minor { 391 type version struct { 392 major, minor int 393 ok bool 394 } 395 t.Errorf("failed to parse %q, expected: %#v, got %#v", tt.vers, version{tt.major, tt.minor, tt.ok}, version{major, minor, ok}) 396 } 397 } 398 } 399 400 type getBasicAuthTest struct { 401 username, password string 402 ok bool 403 } 404 405 type parseBasicAuthTest getBasicAuthTest 406 407 type basicAuthCredentialsTest struct { 408 username, password string 409 } 410 411 var getBasicAuthTests = []struct { 412 username, password string 413 ok bool 414 }{ 415 {"Aladdin", "open sesame", true}, 416 {"Aladdin", "open:sesame", true}, 417 {"", "", true}, 418 } 419 420 func TestGetBasicAuth(t *testing.T) { 421 for _, tt := range getBasicAuthTests { 422 r, _ := NewRequest("GET", "http://example.com/", nil) 423 r.SetBasicAuth(tt.username, tt.password) 424 username, password, ok := r.BasicAuth() 425 if ok != tt.ok || username != tt.username || password != tt.password { 426 t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest{username, password, ok}, 427 getBasicAuthTest{tt.username, tt.password, tt.ok}) 428 } 429 } 430 // Unauthenticated request. 431 r, _ := NewRequest("GET", "http://example.com/", nil) 432 username, password, ok := r.BasicAuth() 433 if ok { 434 t.Errorf("expected false from BasicAuth when the request is unauthenticated") 435 } 436 want := basicAuthCredentialsTest{"", ""} 437 if username != want.username || password != want.password { 438 t.Errorf("expected credentials: %#v when the request is unauthenticated, got %#v", 439 want, basicAuthCredentialsTest{username, password}) 440 } 441 } 442 443 var parseBasicAuthTests = []struct { 444 header, username, password string 445 ok bool 446 }{ 447 {"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "Aladdin", "open sesame", true}, 448 {"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open:sesame")), "Aladdin", "open:sesame", true}, 449 {"Basic " + base64.StdEncoding.EncodeToString([]byte(":")), "", "", true}, 450 {"Basic" + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "", "", false}, 451 {base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "", "", false}, 452 {"Basic ", "", "", false}, 453 {"Basic Aladdin:open sesame", "", "", false}, 454 {`Digest username="Aladdin"`, "", "", false}, 455 } 456 457 func TestParseBasicAuth(t *testing.T) { 458 for _, tt := range parseBasicAuthTests { 459 r, _ := NewRequest("GET", "http://example.com/", nil) 460 r.Header.Set("Authorization", tt.header) 461 username, password, ok := r.BasicAuth() 462 if ok != tt.ok || username != tt.username || password != tt.password { 463 t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest{username, password, ok}, 464 getBasicAuthTest{tt.username, tt.password, tt.ok}) 465 } 466 } 467 } 468 469 type logWrites struct { 470 t *testing.T 471 dst *[]string 472 } 473 474 func (l logWrites) WriteByte(c byte) error { 475 l.t.Fatalf("unexpected WriteByte call") 476 return nil 477 } 478 479 func (l logWrites) Write(p []byte) (n int, err error) { 480 *l.dst = append(*l.dst, string(p)) 481 return len(p), nil 482 } 483 484 func TestRequestWriteBufferedWriter(t *testing.T) { 485 got := []string{} 486 req, _ := NewRequest("GET", "http://foo.com/", nil) 487 req.Write(logWrites{t, &got}) 488 want := []string{ 489 "GET / HTTP/1.1\r\n", 490 "Host: foo.com\r\n", 491 "User-Agent: " + DefaultUserAgent + "\r\n", 492 "\r\n", 493 } 494 if !reflect.DeepEqual(got, want) { 495 t.Errorf("Writes = %q\n Want = %q", got, want) 496 } 497 } 498 499 func testMissingFile(t *testing.T, req *Request) { 500 f, fh, err := req.FormFile("missing") 501 if f != nil { 502 t.Errorf("FormFile file = %v, want nil", f) 503 } 504 if fh != nil { 505 t.Errorf("FormFile file header = %q, want nil", fh) 506 } 507 if err != ErrMissingFile { 508 t.Errorf("FormFile err = %q, want ErrMissingFile", err) 509 } 510 } 511 512 func newTestMultipartRequest(t *testing.T) *Request { 513 b := strings.NewReader(strings.Replace(message, "\n", "\r\n", -1)) 514 req, err := NewRequest("POST", "/", b) 515 if err != nil { 516 t.Fatal("NewRequest:", err) 517 } 518 ctype := fmt.Sprintf(`multipart/form-data; boundary="%s"`, boundary) 519 req.Header.Set("Content-type", ctype) 520 return req 521 } 522 523 func validateTestMultipartContents(t *testing.T, req *Request, allMem bool) { 524 if g, e := req.FormValue("texta"), textaValue; g != e { 525 t.Errorf("texta value = %q, want %q", g, e) 526 } 527 if g, e := req.FormValue("textb"), textbValue; g != e { 528 t.Errorf("textb value = %q, want %q", g, e) 529 } 530 if g := req.FormValue("missing"); g != "" { 531 t.Errorf("missing value = %q, want empty string", g) 532 } 533 534 assertMem := func(n string, fd multipart.File) { 535 if _, ok := fd.(*os.File); ok { 536 t.Error(n, " is *os.File, should not be") 537 } 538 } 539 fda := testMultipartFile(t, req, "filea", "filea.txt", fileaContents) 540 defer fda.Close() 541 assertMem("filea", fda) 542 fdb := testMultipartFile(t, req, "fileb", "fileb.txt", filebContents) 543 defer fdb.Close() 544 if allMem { 545 assertMem("fileb", fdb) 546 } else { 547 if _, ok := fdb.(*os.File); !ok { 548 t.Errorf("fileb has unexpected underlying type %T", fdb) 549 } 550 } 551 552 testMissingFile(t, req) 553 } 554 555 func testMultipartFile(t *testing.T, req *Request, key, expectFilename, expectContent string) multipart.File { 556 f, fh, err := req.FormFile(key) 557 if err != nil { 558 t.Fatalf("FormFile(%q): %q", key, err) 559 } 560 if fh.Filename != expectFilename { 561 t.Errorf("filename = %q, want %q", fh.Filename, expectFilename) 562 } 563 var b bytes.Buffer 564 _, err = io.Copy(&b, f) 565 if err != nil { 566 t.Fatal("copying contents:", err) 567 } 568 if g := b.String(); g != expectContent { 569 t.Errorf("contents = %q, want %q", g, expectContent) 570 } 571 return f 572 } 573 574 const ( 575 fileaContents = "This is a test file." 576 filebContents = "Another test file." 577 textaValue = "foo" 578 textbValue = "bar" 579 boundary = `MyBoundary` 580 ) 581 582 const message = ` 583 --MyBoundary 584 Content-Disposition: form-data; name="filea"; filename="filea.txt" 585 Content-Type: text/plain 586 587 ` + fileaContents + ` 588 --MyBoundary 589 Content-Disposition: form-data; name="fileb"; filename="fileb.txt" 590 Content-Type: text/plain 591 592 ` + filebContents + ` 593 --MyBoundary 594 Content-Disposition: form-data; name="texta" 595 596 ` + textaValue + ` 597 --MyBoundary 598 Content-Disposition: form-data; name="textb" 599 600 ` + textbValue + ` 601 --MyBoundary-- 602 ` 603 604 func benchmarkReadRequest(b *testing.B, request string) { 605 request = request + "\n" // final \n 606 request = strings.Replace(request, "\n", "\r\n", -1) // expand \n to \r\n 607 b.SetBytes(int64(len(request))) 608 r := bufio.NewReader(&infiniteReader{buf: []byte(request)}) 609 b.ReportAllocs() 610 b.ResetTimer() 611 for i := 0; i < b.N; i++ { 612 _, err := ReadRequest(r) 613 if err != nil { 614 b.Fatalf("failed to read request: %v", err) 615 } 616 } 617 } 618 619 // infiniteReader satisfies Read requests as if the contents of buf 620 // loop indefinitely. 621 type infiniteReader struct { 622 buf []byte 623 offset int 624 } 625 626 func (r *infiniteReader) Read(b []byte) (int, error) { 627 n := copy(b, r.buf[r.offset:]) 628 r.offset = (r.offset + n) % len(r.buf) 629 return n, nil 630 } 631 632 func BenchmarkReadRequestChrome(b *testing.B) { 633 // https://github.com/felixge/node-http-perf/blob/master/fixtures/get.http 634 benchmarkReadRequest(b, `GET / HTTP/1.1 635 Host: localhost:8080 636 Connection: keep-alive 637 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 638 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17 639 Accept-Encoding: gzip,deflate,sdch 640 Accept-Language: en-US,en;q=0.8 641 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 642 Cookie: __utma=1.1978842379.1323102373.1323102373.1323102373.1; EPi:NumberOfVisits=1,2012-02-28T13:42:18; CrmSession=5b707226b9563e1bc69084d07a107c98; plushContainerWidth=100%25; plushNoTopMenu=0; hudson_auto_refresh=false 643 `) 644 } 645 646 func BenchmarkReadRequestCurl(b *testing.B) { 647 // curl http://localhost:8080/ 648 benchmarkReadRequest(b, `GET / HTTP/1.1 649 User-Agent: curl/7.27.0 650 Host: localhost:8080 651 Accept: */* 652 `) 653 } 654 655 func BenchmarkReadRequestApachebench(b *testing.B) { 656 // ab -n 1 -c 1 http://localhost:8080/ 657 benchmarkReadRequest(b, `GET / HTTP/1.0 658 Host: localhost:8080 659 User-Agent: ApacheBench/2.3 660 Accept: */* 661 `) 662 } 663 664 func BenchmarkReadRequestSiege(b *testing.B) { 665 // siege -r 1 -c 1 http://localhost:8080/ 666 benchmarkReadRequest(b, `GET / HTTP/1.1 667 Host: localhost:8080 668 Accept: */* 669 Accept-Encoding: gzip 670 User-Agent: JoeDog/1.00 [en] (X11; I; Siege 2.70) 671 Connection: keep-alive 672 `) 673 } 674 675 func BenchmarkReadRequestWrk(b *testing.B) { 676 // wrk -t 1 -r 1 -c 1 http://localhost:8080/ 677 benchmarkReadRequest(b, `GET / HTTP/1.1 678 Host: localhost:8080 679 `) 680 }