github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/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 basicAuthCredentialsTest struct { 406 username, password string 407 } 408 409 var getBasicAuthTests = []struct { 410 username, password string 411 ok bool 412 }{ 413 {"Aladdin", "open sesame", true}, 414 {"Aladdin", "open:sesame", true}, 415 {"", "", true}, 416 } 417 418 func TestGetBasicAuth(t *testing.T) { 419 for _, tt := range getBasicAuthTests { 420 r, _ := NewRequest("GET", "http://example.com/", nil) 421 r.SetBasicAuth(tt.username, tt.password) 422 username, password, ok := r.BasicAuth() 423 if ok != tt.ok || username != tt.username || password != tt.password { 424 t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest{username, password, ok}, 425 getBasicAuthTest{tt.username, tt.password, tt.ok}) 426 } 427 } 428 // Unauthenticated request. 429 r, _ := NewRequest("GET", "http://example.com/", nil) 430 username, password, ok := r.BasicAuth() 431 if ok { 432 t.Errorf("expected false from BasicAuth when the request is unauthenticated") 433 } 434 want := basicAuthCredentialsTest{"", ""} 435 if username != want.username || password != want.password { 436 t.Errorf("expected credentials: %#v when the request is unauthenticated, got %#v", 437 want, basicAuthCredentialsTest{username, password}) 438 } 439 } 440 441 var parseBasicAuthTests = []struct { 442 header, username, password string 443 ok bool 444 }{ 445 {"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "Aladdin", "open sesame", true}, 446 {"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open:sesame")), "Aladdin", "open:sesame", true}, 447 {"Basic " + base64.StdEncoding.EncodeToString([]byte(":")), "", "", true}, 448 {"Basic" + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "", "", false}, 449 {base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "", "", false}, 450 {"Basic ", "", "", false}, 451 {"Basic Aladdin:open sesame", "", "", false}, 452 {`Digest username="Aladdin"`, "", "", false}, 453 } 454 455 func TestParseBasicAuth(t *testing.T) { 456 for _, tt := range parseBasicAuthTests { 457 r, _ := NewRequest("GET", "http://example.com/", nil) 458 r.Header.Set("Authorization", tt.header) 459 username, password, ok := r.BasicAuth() 460 if ok != tt.ok || username != tt.username || password != tt.password { 461 t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest{username, password, ok}, 462 getBasicAuthTest{tt.username, tt.password, tt.ok}) 463 } 464 } 465 } 466 467 type logWrites struct { 468 t *testing.T 469 dst *[]string 470 } 471 472 func (l logWrites) WriteByte(c byte) error { 473 l.t.Fatalf("unexpected WriteByte call") 474 return nil 475 } 476 477 func (l logWrites) Write(p []byte) (n int, err error) { 478 *l.dst = append(*l.dst, string(p)) 479 return len(p), nil 480 } 481 482 func TestRequestWriteBufferedWriter(t *testing.T) { 483 got := []string{} 484 req, _ := NewRequest("GET", "http://foo.com/", nil) 485 req.Write(logWrites{t, &got}) 486 want := []string{ 487 "GET / HTTP/1.1\r\n", 488 "Host: foo.com\r\n", 489 "User-Agent: " + DefaultUserAgent + "\r\n", 490 "\r\n", 491 } 492 if !reflect.DeepEqual(got, want) { 493 t.Errorf("Writes = %q\n Want = %q", got, want) 494 } 495 } 496 497 func testMissingFile(t *testing.T, req *Request) { 498 f, fh, err := req.FormFile("missing") 499 if f != nil { 500 t.Errorf("FormFile file = %v, want nil", f) 501 } 502 if fh != nil { 503 t.Errorf("FormFile file header = %q, want nil", fh) 504 } 505 if err != ErrMissingFile { 506 t.Errorf("FormFile err = %q, want ErrMissingFile", err) 507 } 508 } 509 510 func newTestMultipartRequest(t *testing.T) *Request { 511 b := strings.NewReader(strings.Replace(message, "\n", "\r\n", -1)) 512 req, err := NewRequest("POST", "/", b) 513 if err != nil { 514 t.Fatal("NewRequest:", err) 515 } 516 ctype := fmt.Sprintf(`multipart/form-data; boundary="%s"`, boundary) 517 req.Header.Set("Content-type", ctype) 518 return req 519 } 520 521 func validateTestMultipartContents(t *testing.T, req *Request, allMem bool) { 522 if g, e := req.FormValue("texta"), textaValue; g != e { 523 t.Errorf("texta value = %q, want %q", g, e) 524 } 525 if g, e := req.FormValue("textb"), textbValue; g != e { 526 t.Errorf("textb value = %q, want %q", g, e) 527 } 528 if g := req.FormValue("missing"); g != "" { 529 t.Errorf("missing value = %q, want empty string", g) 530 } 531 532 assertMem := func(n string, fd multipart.File) { 533 if _, ok := fd.(*os.File); ok { 534 t.Error(n, " is *os.File, should not be") 535 } 536 } 537 fda := testMultipartFile(t, req, "filea", "filea.txt", fileaContents) 538 defer fda.Close() 539 assertMem("filea", fda) 540 fdb := testMultipartFile(t, req, "fileb", "fileb.txt", filebContents) 541 defer fdb.Close() 542 if allMem { 543 assertMem("fileb", fdb) 544 } else { 545 if _, ok := fdb.(*os.File); !ok { 546 t.Errorf("fileb has unexpected underlying type %T", fdb) 547 } 548 } 549 550 testMissingFile(t, req) 551 } 552 553 func testMultipartFile(t *testing.T, req *Request, key, expectFilename, expectContent string) multipart.File { 554 f, fh, err := req.FormFile(key) 555 if err != nil { 556 t.Fatalf("FormFile(%q): %q", key, err) 557 } 558 if fh.Filename != expectFilename { 559 t.Errorf("filename = %q, want %q", fh.Filename, expectFilename) 560 } 561 var b bytes.Buffer 562 _, err = io.Copy(&b, f) 563 if err != nil { 564 t.Fatal("copying contents:", err) 565 } 566 if g := b.String(); g != expectContent { 567 t.Errorf("contents = %q, want %q", g, expectContent) 568 } 569 return f 570 } 571 572 const ( 573 fileaContents = "This is a test file." 574 filebContents = "Another test file." 575 textaValue = "foo" 576 textbValue = "bar" 577 boundary = `MyBoundary` 578 ) 579 580 const message = ` 581 --MyBoundary 582 Content-Disposition: form-data; name="filea"; filename="filea.txt" 583 Content-Type: text/plain 584 585 ` + fileaContents + ` 586 --MyBoundary 587 Content-Disposition: form-data; name="fileb"; filename="fileb.txt" 588 Content-Type: text/plain 589 590 ` + filebContents + ` 591 --MyBoundary 592 Content-Disposition: form-data; name="texta" 593 594 ` + textaValue + ` 595 --MyBoundary 596 Content-Disposition: form-data; name="textb" 597 598 ` + textbValue + ` 599 --MyBoundary-- 600 ` 601 602 func benchmarkReadRequest(b *testing.B, request string) { 603 request = request + "\n" // final \n 604 request = strings.Replace(request, "\n", "\r\n", -1) // expand \n to \r\n 605 b.SetBytes(int64(len(request))) 606 r := bufio.NewReader(&infiniteReader{buf: []byte(request)}) 607 b.ReportAllocs() 608 b.ResetTimer() 609 for i := 0; i < b.N; i++ { 610 _, err := ReadRequest(r) 611 if err != nil { 612 b.Fatalf("failed to read request: %v", err) 613 } 614 } 615 } 616 617 // infiniteReader satisfies Read requests as if the contents of buf 618 // loop indefinitely. 619 type infiniteReader struct { 620 buf []byte 621 offset int 622 } 623 624 func (r *infiniteReader) Read(b []byte) (int, error) { 625 n := copy(b, r.buf[r.offset:]) 626 r.offset = (r.offset + n) % len(r.buf) 627 return n, nil 628 } 629 630 func BenchmarkReadRequestChrome(b *testing.B) { 631 // https://github.com/felixge/node-http-perf/blob/master/fixtures/get.http 632 benchmarkReadRequest(b, `GET / HTTP/1.1 633 Host: localhost:8080 634 Connection: keep-alive 635 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 636 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 637 Accept-Encoding: gzip,deflate,sdch 638 Accept-Language: en-US,en;q=0.8 639 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 640 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 641 `) 642 } 643 644 func BenchmarkReadRequestCurl(b *testing.B) { 645 // curl http://localhost:8080/ 646 benchmarkReadRequest(b, `GET / HTTP/1.1 647 User-Agent: curl/7.27.0 648 Host: localhost:8080 649 Accept: */* 650 `) 651 } 652 653 func BenchmarkReadRequestApachebench(b *testing.B) { 654 // ab -n 1 -c 1 http://localhost:8080/ 655 benchmarkReadRequest(b, `GET / HTTP/1.0 656 Host: localhost:8080 657 User-Agent: ApacheBench/2.3 658 Accept: */* 659 `) 660 } 661 662 func BenchmarkReadRequestSiege(b *testing.B) { 663 // siege -r 1 -c 1 http://localhost:8080/ 664 benchmarkReadRequest(b, `GET / HTTP/1.1 665 Host: localhost:8080 666 Accept: */* 667 Accept-Encoding: gzip 668 User-Agent: JoeDog/1.00 [en] (X11; I; Siege 2.70) 669 Connection: keep-alive 670 `) 671 } 672 673 func BenchmarkReadRequestWrk(b *testing.B) { 674 // wrk -t 1 -r 1 -c 1 http://localhost:8080/ 675 benchmarkReadRequest(b, `GET / HTTP/1.1 676 Host: localhost:8080 677 `) 678 }