github.com/d4l3k/go@v0.0.0-20151015000803-65fc379daeda/src/net/http/serve_test.go (about) 1 // Copyright 2010 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 // End-to-end serving tests 6 7 package http_test 8 9 import ( 10 "bufio" 11 "bytes" 12 "crypto/tls" 13 "errors" 14 "fmt" 15 "io" 16 "io/ioutil" 17 "log" 18 "math/rand" 19 "net" 20 . "net/http" 21 "net/http/httptest" 22 "net/http/httputil" 23 "net/http/internal" 24 "net/url" 25 "os" 26 "os/exec" 27 "reflect" 28 "runtime" 29 "strconv" 30 "strings" 31 "sync" 32 "sync/atomic" 33 "syscall" 34 "testing" 35 "time" 36 ) 37 38 type dummyAddr string 39 type oneConnListener struct { 40 conn net.Conn 41 } 42 43 func (l *oneConnListener) Accept() (c net.Conn, err error) { 44 c = l.conn 45 if c == nil { 46 err = io.EOF 47 return 48 } 49 err = nil 50 l.conn = nil 51 return 52 } 53 54 func (l *oneConnListener) Close() error { 55 return nil 56 } 57 58 func (l *oneConnListener) Addr() net.Addr { 59 return dummyAddr("test-address") 60 } 61 62 func (a dummyAddr) Network() string { 63 return string(a) 64 } 65 66 func (a dummyAddr) String() string { 67 return string(a) 68 } 69 70 type noopConn struct{} 71 72 func (noopConn) LocalAddr() net.Addr { return dummyAddr("local-addr") } 73 func (noopConn) RemoteAddr() net.Addr { return dummyAddr("remote-addr") } 74 func (noopConn) SetDeadline(t time.Time) error { return nil } 75 func (noopConn) SetReadDeadline(t time.Time) error { return nil } 76 func (noopConn) SetWriteDeadline(t time.Time) error { return nil } 77 78 type rwTestConn struct { 79 io.Reader 80 io.Writer 81 noopConn 82 83 closeFunc func() error // called if non-nil 84 closec chan bool // else, if non-nil, send value to it on close 85 } 86 87 func (c *rwTestConn) Close() error { 88 if c.closeFunc != nil { 89 return c.closeFunc() 90 } 91 select { 92 case c.closec <- true: 93 default: 94 } 95 return nil 96 } 97 98 type testConn struct { 99 readBuf bytes.Buffer 100 writeBuf bytes.Buffer 101 closec chan bool // if non-nil, send value to it on close 102 noopConn 103 } 104 105 func (c *testConn) Read(b []byte) (int, error) { 106 return c.readBuf.Read(b) 107 } 108 109 func (c *testConn) Write(b []byte) (int, error) { 110 return c.writeBuf.Write(b) 111 } 112 113 func (c *testConn) Close() error { 114 select { 115 case c.closec <- true: 116 default: 117 } 118 return nil 119 } 120 121 // reqBytes treats req as a request (with \n delimiters) and returns it with \r\n delimiters, 122 // ending in \r\n\r\n 123 func reqBytes(req string) []byte { 124 return []byte(strings.Replace(strings.TrimSpace(req), "\n", "\r\n", -1) + "\r\n\r\n") 125 } 126 127 type handlerTest struct { 128 handler Handler 129 } 130 131 func newHandlerTest(h Handler) handlerTest { 132 return handlerTest{h} 133 } 134 135 func (ht handlerTest) rawResponse(req string) string { 136 reqb := reqBytes(req) 137 var output bytes.Buffer 138 conn := &rwTestConn{ 139 Reader: bytes.NewReader(reqb), 140 Writer: &output, 141 closec: make(chan bool, 1), 142 } 143 ln := &oneConnListener{conn: conn} 144 go Serve(ln, ht.handler) 145 <-conn.closec 146 return output.String() 147 } 148 149 func TestConsumingBodyOnNextConn(t *testing.T) { 150 defer afterTest(t) 151 conn := new(testConn) 152 for i := 0; i < 2; i++ { 153 conn.readBuf.Write([]byte( 154 "POST / HTTP/1.1\r\n" + 155 "Host: test\r\n" + 156 "Content-Length: 11\r\n" + 157 "\r\n" + 158 "foo=1&bar=1")) 159 } 160 161 reqNum := 0 162 ch := make(chan *Request) 163 servech := make(chan error) 164 listener := &oneConnListener{conn} 165 handler := func(res ResponseWriter, req *Request) { 166 reqNum++ 167 ch <- req 168 } 169 170 go func() { 171 servech <- Serve(listener, HandlerFunc(handler)) 172 }() 173 174 var req *Request 175 req = <-ch 176 if req == nil { 177 t.Fatal("Got nil first request.") 178 } 179 if req.Method != "POST" { 180 t.Errorf("For request #1's method, got %q; expected %q", 181 req.Method, "POST") 182 } 183 184 req = <-ch 185 if req == nil { 186 t.Fatal("Got nil first request.") 187 } 188 if req.Method != "POST" { 189 t.Errorf("For request #2's method, got %q; expected %q", 190 req.Method, "POST") 191 } 192 193 if serveerr := <-servech; serveerr != io.EOF { 194 t.Errorf("Serve returned %q; expected EOF", serveerr) 195 } 196 } 197 198 type stringHandler string 199 200 func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) { 201 w.Header().Set("Result", string(s)) 202 } 203 204 var handlers = []struct { 205 pattern string 206 msg string 207 }{ 208 {"/", "Default"}, 209 {"/someDir/", "someDir"}, 210 {"/#/", "hash"}, 211 {"someHost.com/someDir/", "someHost.com/someDir"}, 212 } 213 214 var vtests = []struct { 215 url string 216 expected string 217 }{ 218 {"http://localhost/someDir/apage", "someDir"}, 219 {"http://localhost/%23/apage", "hash"}, 220 {"http://localhost/otherDir/apage", "Default"}, 221 {"http://someHost.com/someDir/apage", "someHost.com/someDir"}, 222 {"http://otherHost.com/someDir/apage", "someDir"}, 223 {"http://otherHost.com/aDir/apage", "Default"}, 224 // redirections for trees 225 {"http://localhost/someDir", "/someDir/"}, 226 {"http://localhost/%23", "/%23/"}, 227 {"http://someHost.com/someDir", "/someDir/"}, 228 } 229 230 func TestHostHandlers(t *testing.T) { 231 defer afterTest(t) 232 mux := NewServeMux() 233 for _, h := range handlers { 234 mux.Handle(h.pattern, stringHandler(h.msg)) 235 } 236 ts := httptest.NewServer(mux) 237 defer ts.Close() 238 239 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 240 if err != nil { 241 t.Fatal(err) 242 } 243 defer conn.Close() 244 cc := httputil.NewClientConn(conn, nil) 245 for _, vt := range vtests { 246 var r *Response 247 var req Request 248 if req.URL, err = url.Parse(vt.url); err != nil { 249 t.Errorf("cannot parse url: %v", err) 250 continue 251 } 252 if err := cc.Write(&req); err != nil { 253 t.Errorf("writing request: %v", err) 254 continue 255 } 256 r, err := cc.Read(&req) 257 if err != nil { 258 t.Errorf("reading response: %v", err) 259 continue 260 } 261 switch r.StatusCode { 262 case StatusOK: 263 s := r.Header.Get("Result") 264 if s != vt.expected { 265 t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected) 266 } 267 case StatusMovedPermanently: 268 s := r.Header.Get("Location") 269 if s != vt.expected { 270 t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected) 271 } 272 default: 273 t.Errorf("Get(%q) unhandled status code %d", vt.url, r.StatusCode) 274 } 275 } 276 } 277 278 var serveMuxRegister = []struct { 279 pattern string 280 h Handler 281 }{ 282 {"/dir/", serve(200)}, 283 {"/search", serve(201)}, 284 {"codesearch.google.com/search", serve(202)}, 285 {"codesearch.google.com/", serve(203)}, 286 {"example.com/", HandlerFunc(checkQueryStringHandler)}, 287 } 288 289 // serve returns a handler that sends a response with the given code. 290 func serve(code int) HandlerFunc { 291 return func(w ResponseWriter, r *Request) { 292 w.WriteHeader(code) 293 } 294 } 295 296 // checkQueryStringHandler checks if r.URL.RawQuery has the same value 297 // as the URL excluding the scheme and the query string and sends 200 298 // response code if it is, 500 otherwise. 299 func checkQueryStringHandler(w ResponseWriter, r *Request) { 300 u := *r.URL 301 u.Scheme = "http" 302 u.Host = r.Host 303 u.RawQuery = "" 304 if "http://"+r.URL.RawQuery == u.String() { 305 w.WriteHeader(200) 306 } else { 307 w.WriteHeader(500) 308 } 309 } 310 311 var serveMuxTests = []struct { 312 method string 313 host string 314 path string 315 code int 316 pattern string 317 }{ 318 {"GET", "google.com", "/", 404, ""}, 319 {"GET", "google.com", "/dir", 301, "/dir/"}, 320 {"GET", "google.com", "/dir/", 200, "/dir/"}, 321 {"GET", "google.com", "/dir/file", 200, "/dir/"}, 322 {"GET", "google.com", "/search", 201, "/search"}, 323 {"GET", "google.com", "/search/", 404, ""}, 324 {"GET", "google.com", "/search/foo", 404, ""}, 325 {"GET", "codesearch.google.com", "/search", 202, "codesearch.google.com/search"}, 326 {"GET", "codesearch.google.com", "/search/", 203, "codesearch.google.com/"}, 327 {"GET", "codesearch.google.com", "/search/foo", 203, "codesearch.google.com/"}, 328 {"GET", "codesearch.google.com", "/", 203, "codesearch.google.com/"}, 329 {"GET", "images.google.com", "/search", 201, "/search"}, 330 {"GET", "images.google.com", "/search/", 404, ""}, 331 {"GET", "images.google.com", "/search/foo", 404, ""}, 332 {"GET", "google.com", "/../search", 301, "/search"}, 333 {"GET", "google.com", "/dir/..", 301, ""}, 334 {"GET", "google.com", "/dir/..", 301, ""}, 335 {"GET", "google.com", "/dir/./file", 301, "/dir/"}, 336 337 // The /foo -> /foo/ redirect applies to CONNECT requests 338 // but the path canonicalization does not. 339 {"CONNECT", "google.com", "/dir", 301, "/dir/"}, 340 {"CONNECT", "google.com", "/../search", 404, ""}, 341 {"CONNECT", "google.com", "/dir/..", 200, "/dir/"}, 342 {"CONNECT", "google.com", "/dir/..", 200, "/dir/"}, 343 {"CONNECT", "google.com", "/dir/./file", 200, "/dir/"}, 344 } 345 346 func TestServeMuxHandler(t *testing.T) { 347 mux := NewServeMux() 348 for _, e := range serveMuxRegister { 349 mux.Handle(e.pattern, e.h) 350 } 351 352 for _, tt := range serveMuxTests { 353 r := &Request{ 354 Method: tt.method, 355 Host: tt.host, 356 URL: &url.URL{ 357 Path: tt.path, 358 }, 359 } 360 h, pattern := mux.Handler(r) 361 rr := httptest.NewRecorder() 362 h.ServeHTTP(rr, r) 363 if pattern != tt.pattern || rr.Code != tt.code { 364 t.Errorf("%s %s %s = %d, %q, want %d, %q", tt.method, tt.host, tt.path, rr.Code, pattern, tt.code, tt.pattern) 365 } 366 } 367 } 368 369 var serveMuxTests2 = []struct { 370 method string 371 host string 372 url string 373 code int 374 redirOk bool 375 }{ 376 {"GET", "google.com", "/", 404, false}, 377 {"GET", "example.com", "/test/?example.com/test/", 200, false}, 378 {"GET", "example.com", "test/?example.com/test/", 200, true}, 379 } 380 381 // TestServeMuxHandlerRedirects tests that automatic redirects generated by 382 // mux.Handler() shouldn't clear the request's query string. 383 func TestServeMuxHandlerRedirects(t *testing.T) { 384 mux := NewServeMux() 385 for _, e := range serveMuxRegister { 386 mux.Handle(e.pattern, e.h) 387 } 388 389 for _, tt := range serveMuxTests2 { 390 tries := 1 391 turl := tt.url 392 for tries > 0 { 393 u, e := url.Parse(turl) 394 if e != nil { 395 t.Fatal(e) 396 } 397 r := &Request{ 398 Method: tt.method, 399 Host: tt.host, 400 URL: u, 401 } 402 h, _ := mux.Handler(r) 403 rr := httptest.NewRecorder() 404 h.ServeHTTP(rr, r) 405 if rr.Code != 301 { 406 if rr.Code != tt.code { 407 t.Errorf("%s %s %s = %d, want %d", tt.method, tt.host, tt.url, rr.Code, tt.code) 408 } 409 break 410 } 411 if !tt.redirOk { 412 t.Errorf("%s %s %s, unexpected redirect", tt.method, tt.host, tt.url) 413 break 414 } 415 turl = rr.HeaderMap.Get("Location") 416 tries-- 417 } 418 if tries < 0 { 419 t.Errorf("%s %s %s, too many redirects", tt.method, tt.host, tt.url) 420 } 421 } 422 } 423 424 // Tests for https://golang.org/issue/900 425 func TestMuxRedirectLeadingSlashes(t *testing.T) { 426 paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"} 427 for _, path := range paths { 428 req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n"))) 429 if err != nil { 430 t.Errorf("%s", err) 431 } 432 mux := NewServeMux() 433 resp := httptest.NewRecorder() 434 435 mux.ServeHTTP(resp, req) 436 437 if loc, expected := resp.Header().Get("Location"), "/foo.txt"; loc != expected { 438 t.Errorf("Expected Location header set to %q; got %q", expected, loc) 439 return 440 } 441 442 if code, expected := resp.Code, StatusMovedPermanently; code != expected { 443 t.Errorf("Expected response code of StatusMovedPermanently; got %d", code) 444 return 445 } 446 } 447 } 448 449 func TestServerTimeouts(t *testing.T) { 450 if runtime.GOOS == "plan9" { 451 t.Skip("skipping test; see https://golang.org/issue/7237") 452 } 453 defer afterTest(t) 454 reqNum := 0 455 ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) { 456 reqNum++ 457 fmt.Fprintf(res, "req=%d", reqNum) 458 })) 459 ts.Config.ReadTimeout = 250 * time.Millisecond 460 ts.Config.WriteTimeout = 250 * time.Millisecond 461 ts.Start() 462 defer ts.Close() 463 464 // Hit the HTTP server successfully. 465 tr := &Transport{DisableKeepAlives: true} // they interfere with this test 466 defer tr.CloseIdleConnections() 467 c := &Client{Transport: tr} 468 r, err := c.Get(ts.URL) 469 if err != nil { 470 t.Fatalf("http Get #1: %v", err) 471 } 472 got, _ := ioutil.ReadAll(r.Body) 473 expected := "req=1" 474 if string(got) != expected { 475 t.Errorf("Unexpected response for request #1; got %q; expected %q", 476 string(got), expected) 477 } 478 479 // Slow client that should timeout. 480 t1 := time.Now() 481 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 482 if err != nil { 483 t.Fatalf("Dial: %v", err) 484 } 485 buf := make([]byte, 1) 486 n, err := conn.Read(buf) 487 latency := time.Since(t1) 488 if n != 0 || err != io.EOF { 489 t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF) 490 } 491 if latency < 200*time.Millisecond /* fudge from 250 ms above */ { 492 t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond) 493 } 494 495 // Hit the HTTP server successfully again, verifying that the 496 // previous slow connection didn't run our handler. (that we 497 // get "req=2", not "req=3") 498 r, err = Get(ts.URL) 499 if err != nil { 500 t.Fatalf("http Get #2: %v", err) 501 } 502 got, _ = ioutil.ReadAll(r.Body) 503 expected = "req=2" 504 if string(got) != expected { 505 t.Errorf("Get #2 got %q, want %q", string(got), expected) 506 } 507 508 if !testing.Short() { 509 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 510 if err != nil { 511 t.Fatalf("Dial: %v", err) 512 } 513 defer conn.Close() 514 go io.Copy(ioutil.Discard, conn) 515 for i := 0; i < 5; i++ { 516 _, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")) 517 if err != nil { 518 t.Fatalf("on write %d: %v", i, err) 519 } 520 time.Sleep(ts.Config.ReadTimeout / 2) 521 } 522 } 523 } 524 525 // golang.org/issue/4741 -- setting only a write timeout that triggers 526 // shouldn't cause a handler to block forever on reads (next HTTP 527 // request) that will never happen. 528 func TestOnlyWriteTimeout(t *testing.T) { 529 if runtime.GOOS == "plan9" { 530 t.Skip("skipping test; see https://golang.org/issue/7237") 531 } 532 defer afterTest(t) 533 var conn net.Conn 534 var afterTimeoutErrc = make(chan error, 1) 535 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, req *Request) { 536 buf := make([]byte, 512<<10) 537 _, err := w.Write(buf) 538 if err != nil { 539 t.Errorf("handler Write error: %v", err) 540 return 541 } 542 conn.SetWriteDeadline(time.Now().Add(-30 * time.Second)) 543 _, err = w.Write(buf) 544 afterTimeoutErrc <- err 545 })) 546 ts.Listener = trackLastConnListener{ts.Listener, &conn} 547 ts.Start() 548 defer ts.Close() 549 550 tr := &Transport{DisableKeepAlives: false} 551 defer tr.CloseIdleConnections() 552 c := &Client{Transport: tr} 553 554 errc := make(chan error) 555 go func() { 556 res, err := c.Get(ts.URL) 557 if err != nil { 558 errc <- err 559 return 560 } 561 _, err = io.Copy(ioutil.Discard, res.Body) 562 errc <- err 563 }() 564 select { 565 case err := <-errc: 566 if err == nil { 567 t.Errorf("expected an error from Get request") 568 } 569 case <-time.After(5 * time.Second): 570 t.Fatal("timeout waiting for Get error") 571 } 572 if err := <-afterTimeoutErrc; err == nil { 573 t.Error("expected write error after timeout") 574 } 575 } 576 577 // trackLastConnListener tracks the last net.Conn that was accepted. 578 type trackLastConnListener struct { 579 net.Listener 580 last *net.Conn // destination 581 } 582 583 func (l trackLastConnListener) Accept() (c net.Conn, err error) { 584 c, err = l.Listener.Accept() 585 *l.last = c 586 return 587 } 588 589 // TestIdentityResponse verifies that a handler can unset 590 func TestIdentityResponse(t *testing.T) { 591 defer afterTest(t) 592 handler := HandlerFunc(func(rw ResponseWriter, req *Request) { 593 rw.Header().Set("Content-Length", "3") 594 rw.Header().Set("Transfer-Encoding", req.FormValue("te")) 595 switch { 596 case req.FormValue("overwrite") == "1": 597 _, err := rw.Write([]byte("foo TOO LONG")) 598 if err != ErrContentLength { 599 t.Errorf("expected ErrContentLength; got %v", err) 600 } 601 case req.FormValue("underwrite") == "1": 602 rw.Header().Set("Content-Length", "500") 603 rw.Write([]byte("too short")) 604 default: 605 rw.Write([]byte("foo")) 606 } 607 }) 608 609 ts := httptest.NewServer(handler) 610 defer ts.Close() 611 612 // Note: this relies on the assumption (which is true) that 613 // Get sends HTTP/1.1 or greater requests. Otherwise the 614 // server wouldn't have the choice to send back chunked 615 // responses. 616 for _, te := range []string{"", "identity"} { 617 url := ts.URL + "/?te=" + te 618 res, err := Get(url) 619 if err != nil { 620 t.Fatalf("error with Get of %s: %v", url, err) 621 } 622 if cl, expected := res.ContentLength, int64(3); cl != expected { 623 t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl) 624 } 625 if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected { 626 t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl) 627 } 628 if tl, expected := len(res.TransferEncoding), 0; tl != expected { 629 t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)", 630 url, expected, tl, res.TransferEncoding) 631 } 632 res.Body.Close() 633 } 634 635 // Verify that ErrContentLength is returned 636 url := ts.URL + "/?overwrite=1" 637 res, err := Get(url) 638 if err != nil { 639 t.Fatalf("error with Get of %s: %v", url, err) 640 } 641 res.Body.Close() 642 643 // Verify that the connection is closed when the declared Content-Length 644 // is larger than what the handler wrote. 645 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 646 if err != nil { 647 t.Fatalf("error dialing: %v", err) 648 } 649 _, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n")) 650 if err != nil { 651 t.Fatalf("error writing: %v", err) 652 } 653 654 // The ReadAll will hang for a failing test, so use a Timer to 655 // fail explicitly. 656 goTimeout(t, 2*time.Second, func() { 657 got, _ := ioutil.ReadAll(conn) 658 expectedSuffix := "\r\n\r\ntoo short" 659 if !strings.HasSuffix(string(got), expectedSuffix) { 660 t.Errorf("Expected output to end with %q; got response body %q", 661 expectedSuffix, string(got)) 662 } 663 }) 664 } 665 666 func testTCPConnectionCloses(t *testing.T, req string, h Handler) { 667 defer afterTest(t) 668 s := httptest.NewServer(h) 669 defer s.Close() 670 671 conn, err := net.Dial("tcp", s.Listener.Addr().String()) 672 if err != nil { 673 t.Fatal("dial error:", err) 674 } 675 defer conn.Close() 676 677 _, err = fmt.Fprint(conn, req) 678 if err != nil { 679 t.Fatal("print error:", err) 680 } 681 682 r := bufio.NewReader(conn) 683 res, err := ReadResponse(r, &Request{Method: "GET"}) 684 if err != nil { 685 t.Fatal("ReadResponse error:", err) 686 } 687 688 didReadAll := make(chan bool, 1) 689 go func() { 690 select { 691 case <-time.After(5 * time.Second): 692 t.Error("body not closed after 5s") 693 return 694 case <-didReadAll: 695 } 696 }() 697 698 _, err = ioutil.ReadAll(r) 699 if err != nil { 700 t.Fatal("read error:", err) 701 } 702 didReadAll <- true 703 704 if !res.Close { 705 t.Errorf("Response.Close = false; want true") 706 } 707 } 708 709 // TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive. 710 func TestServeHTTP10Close(t *testing.T) { 711 testTCPConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 712 ServeFile(w, r, "testdata/file") 713 })) 714 } 715 716 // TestClientCanClose verifies that clients can also force a connection to close. 717 func TestClientCanClose(t *testing.T) { 718 testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nConnection: close\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 719 // Nothing. 720 })) 721 } 722 723 // TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close, 724 // even for HTTP/1.1 requests. 725 func TestHandlersCanSetConnectionClose11(t *testing.T) { 726 testTCPConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 727 w.Header().Set("Connection", "close") 728 })) 729 } 730 731 func TestHandlersCanSetConnectionClose10(t *testing.T) { 732 testTCPConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 733 w.Header().Set("Connection", "close") 734 })) 735 } 736 737 func TestSetsRemoteAddr(t *testing.T) { 738 defer afterTest(t) 739 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 740 fmt.Fprintf(w, "%s", r.RemoteAddr) 741 })) 742 defer ts.Close() 743 744 res, err := Get(ts.URL) 745 if err != nil { 746 t.Fatalf("Get error: %v", err) 747 } 748 body, err := ioutil.ReadAll(res.Body) 749 if err != nil { 750 t.Fatalf("ReadAll error: %v", err) 751 } 752 ip := string(body) 753 if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") { 754 t.Fatalf("Expected local addr; got %q", ip) 755 } 756 } 757 758 type blockingRemoteAddrListener struct { 759 net.Listener 760 conns chan<- net.Conn 761 } 762 763 func (l *blockingRemoteAddrListener) Accept() (net.Conn, error) { 764 c, err := l.Listener.Accept() 765 if err != nil { 766 return nil, err 767 } 768 brac := &blockingRemoteAddrConn{ 769 Conn: c, 770 addrs: make(chan net.Addr, 1), 771 } 772 l.conns <- brac 773 return brac, nil 774 } 775 776 type blockingRemoteAddrConn struct { 777 net.Conn 778 addrs chan net.Addr 779 } 780 781 func (c *blockingRemoteAddrConn) RemoteAddr() net.Addr { 782 return <-c.addrs 783 } 784 785 // Issue 12943 786 func TestServerAllowsBlockingRemoteAddr(t *testing.T) { 787 defer afterTest(t) 788 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 789 fmt.Fprintf(w, "RA:%s", r.RemoteAddr) 790 })) 791 conns := make(chan net.Conn) 792 ts.Listener = &blockingRemoteAddrListener{ 793 Listener: ts.Listener, 794 conns: conns, 795 } 796 ts.Start() 797 defer ts.Close() 798 799 tr := &Transport{DisableKeepAlives: true} 800 defer tr.CloseIdleConnections() 801 c := &Client{Transport: tr, Timeout: time.Second} 802 803 fetch := func(response chan string) { 804 resp, err := c.Get(ts.URL) 805 if err != nil { 806 t.Error(err) 807 response <- "" 808 return 809 } 810 defer resp.Body.Close() 811 body, err := ioutil.ReadAll(resp.Body) 812 if err != nil { 813 t.Error(err) 814 response <- "" 815 return 816 } 817 response <- string(body) 818 } 819 820 // Start a request. The server will block on getting conn.RemoteAddr. 821 response1c := make(chan string, 1) 822 go fetch(response1c) 823 824 // Wait for the server to accept it; grab the connection. 825 conn1 := <-conns 826 827 // Start another request and grab its connection 828 response2c := make(chan string, 1) 829 go fetch(response2c) 830 var conn2 net.Conn 831 832 select { 833 case conn2 = <-conns: 834 case <-time.After(time.Second): 835 t.Fatal("Second Accept didn't happen") 836 } 837 838 // Send a response on connection 2. 839 conn2.(*blockingRemoteAddrConn).addrs <- &net.TCPAddr{ 840 IP: net.ParseIP("12.12.12.12"), Port: 12} 841 842 // ... and see it 843 response2 := <-response2c 844 if g, e := response2, "RA:12.12.12.12:12"; g != e { 845 t.Fatalf("response 2 addr = %q; want %q", g, e) 846 } 847 848 // Finish the first response. 849 conn1.(*blockingRemoteAddrConn).addrs <- &net.TCPAddr{ 850 IP: net.ParseIP("21.21.21.21"), Port: 21} 851 852 // ... and see it 853 response1 := <-response1c 854 if g, e := response1, "RA:21.21.21.21:21"; g != e { 855 t.Fatalf("response 1 addr = %q; want %q", g, e) 856 } 857 } 858 859 func TestChunkedResponseHeaders(t *testing.T) { 860 defer afterTest(t) 861 log.SetOutput(ioutil.Discard) // is noisy otherwise 862 defer log.SetOutput(os.Stderr) 863 864 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 865 w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted 866 w.(Flusher).Flush() 867 fmt.Fprintf(w, "I am a chunked response.") 868 })) 869 defer ts.Close() 870 871 res, err := Get(ts.URL) 872 if err != nil { 873 t.Fatalf("Get error: %v", err) 874 } 875 defer res.Body.Close() 876 if g, e := res.ContentLength, int64(-1); g != e { 877 t.Errorf("expected ContentLength of %d; got %d", e, g) 878 } 879 if g, e := res.TransferEncoding, []string{"chunked"}; !reflect.DeepEqual(g, e) { 880 t.Errorf("expected TransferEncoding of %v; got %v", e, g) 881 } 882 if _, haveCL := res.Header["Content-Length"]; haveCL { 883 t.Errorf("Unexpected Content-Length") 884 } 885 } 886 887 func TestIdentityResponseHeaders(t *testing.T) { 888 defer afterTest(t) 889 log.SetOutput(ioutil.Discard) // is noisy otherwise 890 defer log.SetOutput(os.Stderr) 891 892 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 893 w.Header().Set("Transfer-Encoding", "identity") 894 w.(Flusher).Flush() 895 fmt.Fprintf(w, "I am an identity response.") 896 })) 897 defer ts.Close() 898 899 res, err := Get(ts.URL) 900 if err != nil { 901 t.Fatalf("Get error: %v", err) 902 } 903 defer res.Body.Close() 904 905 if g, e := res.TransferEncoding, []string(nil); !reflect.DeepEqual(g, e) { 906 t.Errorf("expected TransferEncoding of %v; got %v", e, g) 907 } 908 if _, haveCL := res.Header["Content-Length"]; haveCL { 909 t.Errorf("Unexpected Content-Length") 910 } 911 if !res.Close { 912 t.Errorf("expected Connection: close; got %v", res.Close) 913 } 914 } 915 916 // Test304Responses verifies that 304s don't declare that they're 917 // chunking in their response headers and aren't allowed to produce 918 // output. 919 func Test304Responses(t *testing.T) { 920 defer afterTest(t) 921 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 922 w.WriteHeader(StatusNotModified) 923 _, err := w.Write([]byte("illegal body")) 924 if err != ErrBodyNotAllowed { 925 t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err) 926 } 927 })) 928 defer ts.Close() 929 res, err := Get(ts.URL) 930 if err != nil { 931 t.Error(err) 932 } 933 if len(res.TransferEncoding) > 0 { 934 t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding) 935 } 936 body, err := ioutil.ReadAll(res.Body) 937 if err != nil { 938 t.Error(err) 939 } 940 if len(body) > 0 { 941 t.Errorf("got unexpected body %q", string(body)) 942 } 943 } 944 945 // TestHeadResponses verifies that all MIME type sniffing and Content-Length 946 // counting of GET requests also happens on HEAD requests. 947 func TestHeadResponses(t *testing.T) { 948 defer afterTest(t) 949 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 950 _, err := w.Write([]byte("<html>")) 951 if err != nil { 952 t.Errorf("ResponseWriter.Write: %v", err) 953 } 954 955 // Also exercise the ReaderFrom path 956 _, err = io.Copy(w, strings.NewReader("789a")) 957 if err != nil { 958 t.Errorf("Copy(ResponseWriter, ...): %v", err) 959 } 960 })) 961 defer ts.Close() 962 res, err := Head(ts.URL) 963 if err != nil { 964 t.Error(err) 965 } 966 if len(res.TransferEncoding) > 0 { 967 t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding) 968 } 969 if ct := res.Header.Get("Content-Type"); ct != "text/html; charset=utf-8" { 970 t.Errorf("Content-Type: %q; want text/html; charset=utf-8", ct) 971 } 972 if v := res.ContentLength; v != 10 { 973 t.Errorf("Content-Length: %d; want 10", v) 974 } 975 body, err := ioutil.ReadAll(res.Body) 976 if err != nil { 977 t.Error(err) 978 } 979 if len(body) > 0 { 980 t.Errorf("got unexpected body %q", string(body)) 981 } 982 } 983 984 func TestTLSHandshakeTimeout(t *testing.T) { 985 if runtime.GOOS == "plan9" { 986 t.Skip("skipping test; see https://golang.org/issue/7237") 987 } 988 defer afterTest(t) 989 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 990 errc := make(chanWriter, 10) // but only expecting 1 991 ts.Config.ReadTimeout = 250 * time.Millisecond 992 ts.Config.ErrorLog = log.New(errc, "", 0) 993 ts.StartTLS() 994 defer ts.Close() 995 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 996 if err != nil { 997 t.Fatalf("Dial: %v", err) 998 } 999 defer conn.Close() 1000 goTimeout(t, 10*time.Second, func() { 1001 var buf [1]byte 1002 n, err := conn.Read(buf[:]) 1003 if err == nil || n != 0 { 1004 t.Errorf("Read = %d, %v; want an error and no bytes", n, err) 1005 } 1006 }) 1007 select { 1008 case v := <-errc: 1009 if !strings.Contains(v, "timeout") && !strings.Contains(v, "TLS handshake") { 1010 t.Errorf("expected a TLS handshake timeout error; got %q", v) 1011 } 1012 case <-time.After(5 * time.Second): 1013 t.Errorf("timeout waiting for logged error") 1014 } 1015 } 1016 1017 func TestTLSServer(t *testing.T) { 1018 defer afterTest(t) 1019 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1020 if r.TLS != nil { 1021 w.Header().Set("X-TLS-Set", "true") 1022 if r.TLS.HandshakeComplete { 1023 w.Header().Set("X-TLS-HandshakeComplete", "true") 1024 } 1025 } 1026 })) 1027 ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) 1028 defer ts.Close() 1029 1030 // Connect an idle TCP connection to this server before we run 1031 // our real tests. This idle connection used to block forever 1032 // in the TLS handshake, preventing future connections from 1033 // being accepted. It may prevent future accidental blocking 1034 // in newConn. 1035 idleConn, err := net.Dial("tcp", ts.Listener.Addr().String()) 1036 if err != nil { 1037 t.Fatalf("Dial: %v", err) 1038 } 1039 defer idleConn.Close() 1040 goTimeout(t, 10*time.Second, func() { 1041 if !strings.HasPrefix(ts.URL, "https://") { 1042 t.Errorf("expected test TLS server to start with https://, got %q", ts.URL) 1043 return 1044 } 1045 noVerifyTransport := &Transport{ 1046 TLSClientConfig: &tls.Config{ 1047 InsecureSkipVerify: true, 1048 }, 1049 } 1050 client := &Client{Transport: noVerifyTransport} 1051 res, err := client.Get(ts.URL) 1052 if err != nil { 1053 t.Error(err) 1054 return 1055 } 1056 if res == nil { 1057 t.Errorf("got nil Response") 1058 return 1059 } 1060 defer res.Body.Close() 1061 if res.Header.Get("X-TLS-Set") != "true" { 1062 t.Errorf("expected X-TLS-Set response header") 1063 return 1064 } 1065 if res.Header.Get("X-TLS-HandshakeComplete") != "true" { 1066 t.Errorf("expected X-TLS-HandshakeComplete header") 1067 } 1068 }) 1069 } 1070 1071 func TestAutomaticHTTP2(t *testing.T) { 1072 ln, err := net.Listen("tcp", ":0") 1073 if err != nil { 1074 t.Fatal(err) 1075 } 1076 ln.Close() // immediately (not a defer!) 1077 var s Server 1078 if err := s.Serve(ln); err == nil { 1079 t.Fatal("expected an error") 1080 } 1081 on := s.TLSNextProto["h2"] != nil 1082 if !on { 1083 t.Errorf("http2 wasn't automatically enabled") 1084 } 1085 } 1086 1087 type serverExpectTest struct { 1088 contentLength int // of request body 1089 chunked bool 1090 expectation string // e.g. "100-continue" 1091 readBody bool // whether handler should read the body (if false, sends StatusUnauthorized) 1092 expectedResponse string // expected substring in first line of http response 1093 } 1094 1095 func expectTest(contentLength int, expectation string, readBody bool, expectedResponse string) serverExpectTest { 1096 return serverExpectTest{ 1097 contentLength: contentLength, 1098 expectation: expectation, 1099 readBody: readBody, 1100 expectedResponse: expectedResponse, 1101 } 1102 } 1103 1104 var serverExpectTests = []serverExpectTest{ 1105 // Normal 100-continues, case-insensitive. 1106 expectTest(100, "100-continue", true, "100 Continue"), 1107 expectTest(100, "100-cOntInUE", true, "100 Continue"), 1108 1109 // No 100-continue. 1110 expectTest(100, "", true, "200 OK"), 1111 1112 // 100-continue but requesting client to deny us, 1113 // so it never reads the body. 1114 expectTest(100, "100-continue", false, "401 Unauthorized"), 1115 // Likewise without 100-continue: 1116 expectTest(100, "", false, "401 Unauthorized"), 1117 1118 // Non-standard expectations are failures 1119 expectTest(0, "a-pony", false, "417 Expectation Failed"), 1120 1121 // Expect-100 requested but no body (is apparently okay: Issue 7625) 1122 expectTest(0, "100-continue", true, "200 OK"), 1123 // Expect-100 requested but handler doesn't read the body 1124 expectTest(0, "100-continue", false, "401 Unauthorized"), 1125 // Expect-100 continue with no body, but a chunked body. 1126 { 1127 expectation: "100-continue", 1128 readBody: true, 1129 chunked: true, 1130 expectedResponse: "100 Continue", 1131 }, 1132 } 1133 1134 // Tests that the server responds to the "Expect" request header 1135 // correctly. 1136 func TestServerExpect(t *testing.T) { 1137 defer afterTest(t) 1138 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1139 // Note using r.FormValue("readbody") because for POST 1140 // requests that would read from r.Body, which we only 1141 // conditionally want to do. 1142 if strings.Contains(r.URL.RawQuery, "readbody=true") { 1143 ioutil.ReadAll(r.Body) 1144 w.Write([]byte("Hi")) 1145 } else { 1146 w.WriteHeader(StatusUnauthorized) 1147 } 1148 })) 1149 defer ts.Close() 1150 1151 runTest := func(test serverExpectTest) { 1152 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 1153 if err != nil { 1154 t.Fatalf("Dial: %v", err) 1155 } 1156 defer conn.Close() 1157 1158 // Only send the body immediately if we're acting like an HTTP client 1159 // that doesn't send 100-continue expectations. 1160 writeBody := test.contentLength != 0 && strings.ToLower(test.expectation) != "100-continue" 1161 1162 go func() { 1163 contentLen := fmt.Sprintf("Content-Length: %d", test.contentLength) 1164 if test.chunked { 1165 contentLen = "Transfer-Encoding: chunked" 1166 } 1167 _, err := fmt.Fprintf(conn, "POST /?readbody=%v HTTP/1.1\r\n"+ 1168 "Connection: close\r\n"+ 1169 "%s\r\n"+ 1170 "Expect: %s\r\nHost: foo\r\n\r\n", 1171 test.readBody, contentLen, test.expectation) 1172 if err != nil { 1173 t.Errorf("On test %#v, error writing request headers: %v", test, err) 1174 return 1175 } 1176 if writeBody { 1177 var targ io.WriteCloser = struct { 1178 io.Writer 1179 io.Closer 1180 }{ 1181 conn, 1182 ioutil.NopCloser(nil), 1183 } 1184 if test.chunked { 1185 targ = httputil.NewChunkedWriter(conn) 1186 } 1187 body := strings.Repeat("A", test.contentLength) 1188 _, err = fmt.Fprint(targ, body) 1189 if err == nil { 1190 err = targ.Close() 1191 } 1192 if err != nil { 1193 if !test.readBody { 1194 // Server likely already hung up on us. 1195 // See larger comment below. 1196 t.Logf("On test %#v, acceptable error writing request body: %v", test, err) 1197 return 1198 } 1199 t.Errorf("On test %#v, error writing request body: %v", test, err) 1200 } 1201 } 1202 }() 1203 bufr := bufio.NewReader(conn) 1204 line, err := bufr.ReadString('\n') 1205 if err != nil { 1206 if writeBody && !test.readBody { 1207 // This is an acceptable failure due to a possible TCP race: 1208 // We were still writing data and the server hung up on us. A TCP 1209 // implementation may send a RST if our request body data was known 1210 // to be lost, which may trigger our reads to fail. 1211 // See RFC 1122 page 88. 1212 t.Logf("On test %#v, acceptable error from ReadString: %v", test, err) 1213 return 1214 } 1215 t.Fatalf("On test %#v, ReadString: %v", test, err) 1216 } 1217 if !strings.Contains(line, test.expectedResponse) { 1218 t.Errorf("On test %#v, got first line = %q; want %q", test, line, test.expectedResponse) 1219 } 1220 } 1221 1222 for _, test := range serverExpectTests { 1223 runTest(test) 1224 } 1225 } 1226 1227 // Under a ~256KB (maxPostHandlerReadBytes) threshold, the server 1228 // should consume client request bodies that a handler didn't read. 1229 func TestServerUnreadRequestBodyLittle(t *testing.T) { 1230 defer afterTest(t) 1231 conn := new(testConn) 1232 body := strings.Repeat("x", 100<<10) 1233 conn.readBuf.Write([]byte(fmt.Sprintf( 1234 "POST / HTTP/1.1\r\n"+ 1235 "Host: test\r\n"+ 1236 "Content-Length: %d\r\n"+ 1237 "\r\n", len(body)))) 1238 conn.readBuf.Write([]byte(body)) 1239 1240 done := make(chan bool) 1241 1242 ls := &oneConnListener{conn} 1243 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 1244 defer close(done) 1245 if conn.readBuf.Len() < len(body)/2 { 1246 t.Errorf("on request, read buffer length is %d; expected about 100 KB", conn.readBuf.Len()) 1247 } 1248 rw.WriteHeader(200) 1249 rw.(Flusher).Flush() 1250 if g, e := conn.readBuf.Len(), 0; g != e { 1251 t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e) 1252 } 1253 if c := rw.Header().Get("Connection"); c != "" { 1254 t.Errorf(`Connection header = %q; want ""`, c) 1255 } 1256 })) 1257 <-done 1258 } 1259 1260 // Over a ~256KB (maxPostHandlerReadBytes) threshold, the server 1261 // should ignore client request bodies that a handler didn't read 1262 // and close the connection. 1263 func TestServerUnreadRequestBodyLarge(t *testing.T) { 1264 conn := new(testConn) 1265 body := strings.Repeat("x", 1<<20) 1266 conn.readBuf.Write([]byte(fmt.Sprintf( 1267 "POST / HTTP/1.1\r\n"+ 1268 "Host: test\r\n"+ 1269 "Content-Length: %d\r\n"+ 1270 "\r\n", len(body)))) 1271 conn.readBuf.Write([]byte(body)) 1272 conn.closec = make(chan bool, 1) 1273 1274 ls := &oneConnListener{conn} 1275 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 1276 if conn.readBuf.Len() < len(body)/2 { 1277 t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len()) 1278 } 1279 rw.WriteHeader(200) 1280 rw.(Flusher).Flush() 1281 if conn.readBuf.Len() < len(body)/2 { 1282 t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len()) 1283 } 1284 })) 1285 <-conn.closec 1286 1287 if res := conn.writeBuf.String(); !strings.Contains(res, "Connection: close") { 1288 t.Errorf("Expected a Connection: close header; got response: %s", res) 1289 } 1290 } 1291 1292 type handlerBodyCloseTest struct { 1293 bodySize int 1294 bodyChunked bool 1295 reqConnClose bool 1296 1297 wantEOFSearch bool // should Handler's Body.Close do Reads, looking for EOF? 1298 wantNextReq bool // should it find the next request on the same conn? 1299 } 1300 1301 func (t handlerBodyCloseTest) connectionHeader() string { 1302 if t.reqConnClose { 1303 return "Connection: close\r\n" 1304 } 1305 return "" 1306 } 1307 1308 var handlerBodyCloseTests = [...]handlerBodyCloseTest{ 1309 // Small enough to slurp past to the next request + 1310 // has Content-Length. 1311 0: { 1312 bodySize: 20 << 10, 1313 bodyChunked: false, 1314 reqConnClose: false, 1315 wantEOFSearch: true, 1316 wantNextReq: true, 1317 }, 1318 1319 // Small enough to slurp past to the next request + 1320 // is chunked. 1321 1: { 1322 bodySize: 20 << 10, 1323 bodyChunked: true, 1324 reqConnClose: false, 1325 wantEOFSearch: true, 1326 wantNextReq: true, 1327 }, 1328 1329 // Small enough to slurp past to the next request + 1330 // has Content-Length + 1331 // declares Connection: close (so pointless to read more). 1332 2: { 1333 bodySize: 20 << 10, 1334 bodyChunked: false, 1335 reqConnClose: true, 1336 wantEOFSearch: false, 1337 wantNextReq: false, 1338 }, 1339 1340 // Small enough to slurp past to the next request + 1341 // declares Connection: close, 1342 // but chunked, so it might have trailers. 1343 // TODO: maybe skip this search if no trailers were declared 1344 // in the headers. 1345 3: { 1346 bodySize: 20 << 10, 1347 bodyChunked: true, 1348 reqConnClose: true, 1349 wantEOFSearch: true, 1350 wantNextReq: false, 1351 }, 1352 1353 // Big with Content-Length, so give up immediately if we know it's too big. 1354 4: { 1355 bodySize: 1 << 20, 1356 bodyChunked: false, // has a Content-Length 1357 reqConnClose: false, 1358 wantEOFSearch: false, 1359 wantNextReq: false, 1360 }, 1361 1362 // Big chunked, so read a bit before giving up. 1363 5: { 1364 bodySize: 1 << 20, 1365 bodyChunked: true, 1366 reqConnClose: false, 1367 wantEOFSearch: true, 1368 wantNextReq: false, 1369 }, 1370 1371 // Big with Connection: close, but chunked, so search for trailers. 1372 // TODO: maybe skip this search if no trailers were declared 1373 // in the headers. 1374 6: { 1375 bodySize: 1 << 20, 1376 bodyChunked: true, 1377 reqConnClose: true, 1378 wantEOFSearch: true, 1379 wantNextReq: false, 1380 }, 1381 1382 // Big with Connection: close, so don't do any reads on Close. 1383 // With Content-Length. 1384 7: { 1385 bodySize: 1 << 20, 1386 bodyChunked: false, 1387 reqConnClose: true, 1388 wantEOFSearch: false, 1389 wantNextReq: false, 1390 }, 1391 } 1392 1393 func TestHandlerBodyClose(t *testing.T) { 1394 for i, tt := range handlerBodyCloseTests { 1395 testHandlerBodyClose(t, i, tt) 1396 } 1397 } 1398 1399 func testHandlerBodyClose(t *testing.T, i int, tt handlerBodyCloseTest) { 1400 conn := new(testConn) 1401 body := strings.Repeat("x", tt.bodySize) 1402 if tt.bodyChunked { 1403 conn.readBuf.WriteString("POST / HTTP/1.1\r\n" + 1404 "Host: test\r\n" + 1405 tt.connectionHeader() + 1406 "Transfer-Encoding: chunked\r\n" + 1407 "\r\n") 1408 cw := internal.NewChunkedWriter(&conn.readBuf) 1409 io.WriteString(cw, body) 1410 cw.Close() 1411 conn.readBuf.WriteString("\r\n") 1412 } else { 1413 conn.readBuf.Write([]byte(fmt.Sprintf( 1414 "POST / HTTP/1.1\r\n"+ 1415 "Host: test\r\n"+ 1416 tt.connectionHeader()+ 1417 "Content-Length: %d\r\n"+ 1418 "\r\n", len(body)))) 1419 conn.readBuf.Write([]byte(body)) 1420 } 1421 if !tt.reqConnClose { 1422 conn.readBuf.WriteString("GET / HTTP/1.1\r\nHost: test\r\n\r\n") 1423 } 1424 conn.closec = make(chan bool, 1) 1425 1426 ls := &oneConnListener{conn} 1427 var numReqs int 1428 var size0, size1 int 1429 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 1430 numReqs++ 1431 if numReqs == 1 { 1432 size0 = conn.readBuf.Len() 1433 req.Body.Close() 1434 size1 = conn.readBuf.Len() 1435 } 1436 })) 1437 <-conn.closec 1438 if numReqs < 1 || numReqs > 2 { 1439 t.Fatalf("%d. bug in test. unexpected number of requests = %d", i, numReqs) 1440 } 1441 didSearch := size0 != size1 1442 if didSearch != tt.wantEOFSearch { 1443 t.Errorf("%d. did EOF search = %v; want %v (size went from %d to %d)", i, didSearch, !didSearch, size0, size1) 1444 } 1445 if tt.wantNextReq && numReqs != 2 { 1446 t.Errorf("%d. numReq = %d; want 2", i, numReqs) 1447 } 1448 } 1449 1450 // testHandlerBodyConsumer represents a function injected into a test handler to 1451 // vary work done on a request Body. 1452 type testHandlerBodyConsumer struct { 1453 name string 1454 f func(io.ReadCloser) 1455 } 1456 1457 var testHandlerBodyConsumers = []testHandlerBodyConsumer{ 1458 {"nil", func(io.ReadCloser) {}}, 1459 {"close", func(r io.ReadCloser) { r.Close() }}, 1460 {"discard", func(r io.ReadCloser) { io.Copy(ioutil.Discard, r) }}, 1461 } 1462 1463 func TestRequestBodyReadErrorClosesConnection(t *testing.T) { 1464 defer afterTest(t) 1465 for _, handler := range testHandlerBodyConsumers { 1466 conn := new(testConn) 1467 conn.readBuf.WriteString("POST /public HTTP/1.1\r\n" + 1468 "Host: test\r\n" + 1469 "Transfer-Encoding: chunked\r\n" + 1470 "\r\n" + 1471 "hax\r\n" + // Invalid chunked encoding 1472 "GET /secret HTTP/1.1\r\n" + 1473 "Host: test\r\n" + 1474 "\r\n") 1475 1476 conn.closec = make(chan bool, 1) 1477 ls := &oneConnListener{conn} 1478 var numReqs int 1479 go Serve(ls, HandlerFunc(func(_ ResponseWriter, req *Request) { 1480 numReqs++ 1481 if strings.Contains(req.URL.Path, "secret") { 1482 t.Error("Request for /secret encountered, should not have happened.") 1483 } 1484 handler.f(req.Body) 1485 })) 1486 <-conn.closec 1487 if numReqs != 1 { 1488 t.Errorf("Handler %v: got %d reqs; want 1", handler.name, numReqs) 1489 } 1490 } 1491 } 1492 1493 func TestInvalidTrailerClosesConnection(t *testing.T) { 1494 defer afterTest(t) 1495 for _, handler := range testHandlerBodyConsumers { 1496 conn := new(testConn) 1497 conn.readBuf.WriteString("POST /public HTTP/1.1\r\n" + 1498 "Host: test\r\n" + 1499 "Trailer: hack\r\n" + 1500 "Transfer-Encoding: chunked\r\n" + 1501 "\r\n" + 1502 "3\r\n" + 1503 "hax\r\n" + 1504 "0\r\n" + 1505 "I'm not a valid trailer\r\n" + 1506 "GET /secret HTTP/1.1\r\n" + 1507 "Host: test\r\n" + 1508 "\r\n") 1509 1510 conn.closec = make(chan bool, 1) 1511 ln := &oneConnListener{conn} 1512 var numReqs int 1513 go Serve(ln, HandlerFunc(func(_ ResponseWriter, req *Request) { 1514 numReqs++ 1515 if strings.Contains(req.URL.Path, "secret") { 1516 t.Errorf("Handler %s, Request for /secret encountered, should not have happened.", handler.name) 1517 } 1518 handler.f(req.Body) 1519 })) 1520 <-conn.closec 1521 if numReqs != 1 { 1522 t.Errorf("Handler %s: got %d reqs; want 1", handler.name, numReqs) 1523 } 1524 } 1525 } 1526 1527 // slowTestConn is a net.Conn that provides a means to simulate parts of a 1528 // request being received piecemeal. Deadlines can be set and enforced in both 1529 // Read and Write. 1530 type slowTestConn struct { 1531 // over multiple calls to Read, time.Durations are slept, strings are read. 1532 script []interface{} 1533 closec chan bool 1534 rd, wd time.Time // read, write deadline 1535 noopConn 1536 } 1537 1538 func (c *slowTestConn) SetDeadline(t time.Time) error { 1539 c.SetReadDeadline(t) 1540 c.SetWriteDeadline(t) 1541 return nil 1542 } 1543 1544 func (c *slowTestConn) SetReadDeadline(t time.Time) error { 1545 c.rd = t 1546 return nil 1547 } 1548 1549 func (c *slowTestConn) SetWriteDeadline(t time.Time) error { 1550 c.wd = t 1551 return nil 1552 } 1553 1554 func (c *slowTestConn) Read(b []byte) (n int, err error) { 1555 restart: 1556 if !c.rd.IsZero() && time.Now().After(c.rd) { 1557 return 0, syscall.ETIMEDOUT 1558 } 1559 if len(c.script) == 0 { 1560 return 0, io.EOF 1561 } 1562 1563 switch cue := c.script[0].(type) { 1564 case time.Duration: 1565 if !c.rd.IsZero() { 1566 // If the deadline falls in the middle of our sleep window, deduct 1567 // part of the sleep, then return a timeout. 1568 if remaining := c.rd.Sub(time.Now()); remaining < cue { 1569 c.script[0] = cue - remaining 1570 time.Sleep(remaining) 1571 return 0, syscall.ETIMEDOUT 1572 } 1573 } 1574 c.script = c.script[1:] 1575 time.Sleep(cue) 1576 goto restart 1577 1578 case string: 1579 n = copy(b, cue) 1580 // If cue is too big for the buffer, leave the end for the next Read. 1581 if len(cue) > n { 1582 c.script[0] = cue[n:] 1583 } else { 1584 c.script = c.script[1:] 1585 } 1586 1587 default: 1588 panic("unknown cue in slowTestConn script") 1589 } 1590 1591 return 1592 } 1593 1594 func (c *slowTestConn) Close() error { 1595 select { 1596 case c.closec <- true: 1597 default: 1598 } 1599 return nil 1600 } 1601 1602 func (c *slowTestConn) Write(b []byte) (int, error) { 1603 if !c.wd.IsZero() && time.Now().After(c.wd) { 1604 return 0, syscall.ETIMEDOUT 1605 } 1606 return len(b), nil 1607 } 1608 1609 func TestRequestBodyTimeoutClosesConnection(t *testing.T) { 1610 if testing.Short() { 1611 t.Skip("skipping in -short mode") 1612 } 1613 defer afterTest(t) 1614 for _, handler := range testHandlerBodyConsumers { 1615 conn := &slowTestConn{ 1616 script: []interface{}{ 1617 "POST /public HTTP/1.1\r\n" + 1618 "Host: test\r\n" + 1619 "Content-Length: 10000\r\n" + 1620 "\r\n", 1621 "foo bar baz", 1622 600 * time.Millisecond, // Request deadline should hit here 1623 "GET /secret HTTP/1.1\r\n" + 1624 "Host: test\r\n" + 1625 "\r\n", 1626 }, 1627 closec: make(chan bool, 1), 1628 } 1629 ls := &oneConnListener{conn} 1630 1631 var numReqs int 1632 s := Server{ 1633 Handler: HandlerFunc(func(_ ResponseWriter, req *Request) { 1634 numReqs++ 1635 if strings.Contains(req.URL.Path, "secret") { 1636 t.Error("Request for /secret encountered, should not have happened.") 1637 } 1638 handler.f(req.Body) 1639 }), 1640 ReadTimeout: 400 * time.Millisecond, 1641 } 1642 go s.Serve(ls) 1643 <-conn.closec 1644 1645 if numReqs != 1 { 1646 t.Errorf("Handler %v: got %d reqs; want 1", handler.name, numReqs) 1647 } 1648 } 1649 } 1650 1651 func TestTimeoutHandler(t *testing.T) { 1652 defer afterTest(t) 1653 sendHi := make(chan bool, 1) 1654 writeErrors := make(chan error, 1) 1655 sayHi := HandlerFunc(func(w ResponseWriter, r *Request) { 1656 <-sendHi 1657 _, werr := w.Write([]byte("hi")) 1658 writeErrors <- werr 1659 }) 1660 timeout := make(chan time.Time, 1) // write to this to force timeouts 1661 ts := httptest.NewServer(NewTestTimeoutHandler(sayHi, timeout)) 1662 defer ts.Close() 1663 1664 // Succeed without timing out: 1665 sendHi <- true 1666 res, err := Get(ts.URL) 1667 if err != nil { 1668 t.Error(err) 1669 } 1670 if g, e := res.StatusCode, StatusOK; g != e { 1671 t.Errorf("got res.StatusCode %d; expected %d", g, e) 1672 } 1673 body, _ := ioutil.ReadAll(res.Body) 1674 if g, e := string(body), "hi"; g != e { 1675 t.Errorf("got body %q; expected %q", g, e) 1676 } 1677 if g := <-writeErrors; g != nil { 1678 t.Errorf("got unexpected Write error on first request: %v", g) 1679 } 1680 1681 // Times out: 1682 timeout <- time.Time{} 1683 res, err = Get(ts.URL) 1684 if err != nil { 1685 t.Error(err) 1686 } 1687 if g, e := res.StatusCode, StatusServiceUnavailable; g != e { 1688 t.Errorf("got res.StatusCode %d; expected %d", g, e) 1689 } 1690 body, _ = ioutil.ReadAll(res.Body) 1691 if !strings.Contains(string(body), "<title>Timeout</title>") { 1692 t.Errorf("expected timeout body; got %q", string(body)) 1693 } 1694 1695 // Now make the previously-timed out handler speak again, 1696 // which verifies the panic is handled: 1697 sendHi <- true 1698 if g, e := <-writeErrors, ErrHandlerTimeout; g != e { 1699 t.Errorf("expected Write error of %v; got %v", e, g) 1700 } 1701 } 1702 1703 // See issues 8209 and 8414. 1704 func TestTimeoutHandlerRace(t *testing.T) { 1705 defer afterTest(t) 1706 1707 delayHi := HandlerFunc(func(w ResponseWriter, r *Request) { 1708 ms, _ := strconv.Atoi(r.URL.Path[1:]) 1709 if ms == 0 { 1710 ms = 1 1711 } 1712 for i := 0; i < ms; i++ { 1713 w.Write([]byte("hi")) 1714 time.Sleep(time.Millisecond) 1715 } 1716 }) 1717 1718 ts := httptest.NewServer(TimeoutHandler(delayHi, 20*time.Millisecond, "")) 1719 defer ts.Close() 1720 1721 var wg sync.WaitGroup 1722 gate := make(chan bool, 10) 1723 n := 50 1724 if testing.Short() { 1725 n = 10 1726 gate = make(chan bool, 3) 1727 } 1728 for i := 0; i < n; i++ { 1729 gate <- true 1730 wg.Add(1) 1731 go func() { 1732 defer wg.Done() 1733 defer func() { <-gate }() 1734 res, err := Get(fmt.Sprintf("%s/%d", ts.URL, rand.Intn(50))) 1735 if err == nil { 1736 io.Copy(ioutil.Discard, res.Body) 1737 res.Body.Close() 1738 } 1739 }() 1740 } 1741 wg.Wait() 1742 } 1743 1744 // See issues 8209 and 8414. 1745 func TestTimeoutHandlerRaceHeader(t *testing.T) { 1746 defer afterTest(t) 1747 1748 delay204 := HandlerFunc(func(w ResponseWriter, r *Request) { 1749 w.WriteHeader(204) 1750 }) 1751 1752 ts := httptest.NewServer(TimeoutHandler(delay204, time.Nanosecond, "")) 1753 defer ts.Close() 1754 1755 var wg sync.WaitGroup 1756 gate := make(chan bool, 50) 1757 n := 500 1758 if testing.Short() { 1759 n = 10 1760 } 1761 for i := 0; i < n; i++ { 1762 gate <- true 1763 wg.Add(1) 1764 go func() { 1765 defer wg.Done() 1766 defer func() { <-gate }() 1767 res, err := Get(ts.URL) 1768 if err != nil { 1769 t.Error(err) 1770 return 1771 } 1772 defer res.Body.Close() 1773 io.Copy(ioutil.Discard, res.Body) 1774 }() 1775 } 1776 wg.Wait() 1777 } 1778 1779 // Verifies we don't path.Clean() on the wrong parts in redirects. 1780 func TestRedirectMunging(t *testing.T) { 1781 req, _ := NewRequest("GET", "http://example.com/", nil) 1782 1783 resp := httptest.NewRecorder() 1784 Redirect(resp, req, "/foo?next=http://bar.com/", 302) 1785 if g, e := resp.Header().Get("Location"), "/foo?next=http://bar.com/"; g != e { 1786 t.Errorf("Location header was %q; want %q", g, e) 1787 } 1788 1789 resp = httptest.NewRecorder() 1790 Redirect(resp, req, "http://localhost:8080/_ah/login?continue=http://localhost:8080/", 302) 1791 if g, e := resp.Header().Get("Location"), "http://localhost:8080/_ah/login?continue=http://localhost:8080/"; g != e { 1792 t.Errorf("Location header was %q; want %q", g, e) 1793 } 1794 } 1795 1796 func TestRedirectBadPath(t *testing.T) { 1797 // This used to crash. It's not valid input (bad path), but it 1798 // shouldn't crash. 1799 rr := httptest.NewRecorder() 1800 req := &Request{ 1801 Method: "GET", 1802 URL: &url.URL{ 1803 Scheme: "http", 1804 Path: "not-empty-but-no-leading-slash", // bogus 1805 }, 1806 } 1807 Redirect(rr, req, "", 304) 1808 if rr.Code != 304 { 1809 t.Errorf("Code = %d; want 304", rr.Code) 1810 } 1811 } 1812 1813 // TestZeroLengthPostAndResponse exercises an optimization done by the Transport: 1814 // when there is no body (either because the method doesn't permit a body, or an 1815 // explicit Content-Length of zero is present), then the transport can re-use the 1816 // connection immediately. But when it re-uses the connection, it typically closes 1817 // the previous request's body, which is not optimal for zero-lengthed bodies, 1818 // as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF. 1819 func TestZeroLengthPostAndResponse(t *testing.T) { 1820 defer afterTest(t) 1821 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 1822 all, err := ioutil.ReadAll(r.Body) 1823 if err != nil { 1824 t.Fatalf("handler ReadAll: %v", err) 1825 } 1826 if len(all) != 0 { 1827 t.Errorf("handler got %d bytes; expected 0", len(all)) 1828 } 1829 rw.Header().Set("Content-Length", "0") 1830 })) 1831 defer ts.Close() 1832 1833 req, err := NewRequest("POST", ts.URL, strings.NewReader("")) 1834 if err != nil { 1835 t.Fatal(err) 1836 } 1837 req.ContentLength = 0 1838 1839 var resp [5]*Response 1840 for i := range resp { 1841 resp[i], err = DefaultClient.Do(req) 1842 if err != nil { 1843 t.Fatalf("client post #%d: %v", i, err) 1844 } 1845 } 1846 1847 for i := range resp { 1848 all, err := ioutil.ReadAll(resp[i].Body) 1849 if err != nil { 1850 t.Fatalf("req #%d: client ReadAll: %v", i, err) 1851 } 1852 if len(all) != 0 { 1853 t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all)) 1854 } 1855 } 1856 } 1857 1858 func TestHandlerPanicNil(t *testing.T) { 1859 testHandlerPanic(t, false, nil) 1860 } 1861 1862 func TestHandlerPanic(t *testing.T) { 1863 testHandlerPanic(t, false, "intentional death for testing") 1864 } 1865 1866 func TestHandlerPanicWithHijack(t *testing.T) { 1867 testHandlerPanic(t, true, "intentional death for testing") 1868 } 1869 1870 func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) { 1871 defer afterTest(t) 1872 // Unlike the other tests that set the log output to ioutil.Discard 1873 // to quiet the output, this test uses a pipe. The pipe serves three 1874 // purposes: 1875 // 1876 // 1) The log.Print from the http server (generated by the caught 1877 // panic) will go to the pipe instead of stderr, making the 1878 // output quiet. 1879 // 1880 // 2) We read from the pipe to verify that the handler 1881 // actually caught the panic and logged something. 1882 // 1883 // 3) The blocking Read call prevents this TestHandlerPanic 1884 // function from exiting before the HTTP server handler 1885 // finishes crashing. If this text function exited too 1886 // early (and its defer log.SetOutput(os.Stderr) ran), 1887 // then the crash output could spill into the next test. 1888 pr, pw := io.Pipe() 1889 log.SetOutput(pw) 1890 defer log.SetOutput(os.Stderr) 1891 defer pw.Close() 1892 1893 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1894 if withHijack { 1895 rwc, _, err := w.(Hijacker).Hijack() 1896 if err != nil { 1897 t.Logf("unexpected error: %v", err) 1898 } 1899 defer rwc.Close() 1900 } 1901 panic(panicValue) 1902 })) 1903 defer ts.Close() 1904 1905 // Do a blocking read on the log output pipe so its logging 1906 // doesn't bleed into the next test. But wait only 5 seconds 1907 // for it. 1908 done := make(chan bool, 1) 1909 go func() { 1910 buf := make([]byte, 4<<10) 1911 _, err := pr.Read(buf) 1912 pr.Close() 1913 if err != nil && err != io.EOF { 1914 t.Error(err) 1915 } 1916 done <- true 1917 }() 1918 1919 _, err := Get(ts.URL) 1920 if err == nil { 1921 t.Logf("expected an error") 1922 } 1923 1924 if panicValue == nil { 1925 return 1926 } 1927 1928 select { 1929 case <-done: 1930 return 1931 case <-time.After(5 * time.Second): 1932 t.Fatal("expected server handler to log an error") 1933 } 1934 } 1935 1936 func TestServerNoDate(t *testing.T) { testServerNoHeader(t, "Date") } 1937 func TestServerNoContentType(t *testing.T) { testServerNoHeader(t, "Content-Type") } 1938 1939 func testServerNoHeader(t *testing.T, header string) { 1940 defer afterTest(t) 1941 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1942 w.Header()[header] = nil 1943 io.WriteString(w, "<html>foo</html>") // non-empty 1944 })) 1945 defer ts.Close() 1946 res, err := Get(ts.URL) 1947 if err != nil { 1948 t.Fatal(err) 1949 } 1950 res.Body.Close() 1951 if got, ok := res.Header[header]; ok { 1952 t.Fatalf("Expected no %s header; got %q", header, got) 1953 } 1954 } 1955 1956 func TestStripPrefix(t *testing.T) { 1957 defer afterTest(t) 1958 h := HandlerFunc(func(w ResponseWriter, r *Request) { 1959 w.Header().Set("X-Path", r.URL.Path) 1960 }) 1961 ts := httptest.NewServer(StripPrefix("/foo", h)) 1962 defer ts.Close() 1963 1964 res, err := Get(ts.URL + "/foo/bar") 1965 if err != nil { 1966 t.Fatal(err) 1967 } 1968 if g, e := res.Header.Get("X-Path"), "/bar"; g != e { 1969 t.Errorf("test 1: got %s, want %s", g, e) 1970 } 1971 res.Body.Close() 1972 1973 res, err = Get(ts.URL + "/bar") 1974 if err != nil { 1975 t.Fatal(err) 1976 } 1977 if g, e := res.StatusCode, 404; g != e { 1978 t.Errorf("test 2: got status %v, want %v", g, e) 1979 } 1980 res.Body.Close() 1981 } 1982 1983 func TestRequestLimit(t *testing.T) { 1984 defer afterTest(t) 1985 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1986 t.Fatalf("didn't expect to get request in Handler") 1987 })) 1988 defer ts.Close() 1989 req, _ := NewRequest("GET", ts.URL, nil) 1990 var bytesPerHeader = len("header12345: val12345\r\n") 1991 for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ { 1992 req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i)) 1993 } 1994 res, err := DefaultClient.Do(req) 1995 if err != nil { 1996 // Some HTTP clients may fail on this undefined behavior (server replying and 1997 // closing the connection while the request is still being written), but 1998 // we do support it (at least currently), so we expect a response below. 1999 t.Fatalf("Do: %v", err) 2000 } 2001 defer res.Body.Close() 2002 if res.StatusCode != 413 { 2003 t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status) 2004 } 2005 } 2006 2007 type neverEnding byte 2008 2009 func (b neverEnding) Read(p []byte) (n int, err error) { 2010 for i := range p { 2011 p[i] = byte(b) 2012 } 2013 return len(p), nil 2014 } 2015 2016 type countReader struct { 2017 r io.Reader 2018 n *int64 2019 } 2020 2021 func (cr countReader) Read(p []byte) (n int, err error) { 2022 n, err = cr.r.Read(p) 2023 atomic.AddInt64(cr.n, int64(n)) 2024 return 2025 } 2026 2027 func TestRequestBodyLimit(t *testing.T) { 2028 defer afterTest(t) 2029 const limit = 1 << 20 2030 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2031 r.Body = MaxBytesReader(w, r.Body, limit) 2032 n, err := io.Copy(ioutil.Discard, r.Body) 2033 if err == nil { 2034 t.Errorf("expected error from io.Copy") 2035 } 2036 if n != limit { 2037 t.Errorf("io.Copy = %d, want %d", n, limit) 2038 } 2039 })) 2040 defer ts.Close() 2041 2042 nWritten := new(int64) 2043 req, _ := NewRequest("POST", ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200)) 2044 2045 // Send the POST, but don't care it succeeds or not. The 2046 // remote side is going to reply and then close the TCP 2047 // connection, and HTTP doesn't really define if that's 2048 // allowed or not. Some HTTP clients will get the response 2049 // and some (like ours, currently) will complain that the 2050 // request write failed, without reading the response. 2051 // 2052 // But that's okay, since what we're really testing is that 2053 // the remote side hung up on us before we wrote too much. 2054 _, _ = DefaultClient.Do(req) 2055 2056 if atomic.LoadInt64(nWritten) > limit*100 { 2057 t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d", 2058 limit, nWritten) 2059 } 2060 } 2061 2062 // TestClientWriteShutdown tests that if the client shuts down the write 2063 // side of their TCP connection, the server doesn't send a 400 Bad Request. 2064 func TestClientWriteShutdown(t *testing.T) { 2065 if runtime.GOOS == "plan9" { 2066 t.Skip("skipping test; see https://golang.org/issue/7237") 2067 } 2068 defer afterTest(t) 2069 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 2070 defer ts.Close() 2071 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 2072 if err != nil { 2073 t.Fatalf("Dial: %v", err) 2074 } 2075 err = conn.(*net.TCPConn).CloseWrite() 2076 if err != nil { 2077 t.Fatalf("Dial: %v", err) 2078 } 2079 donec := make(chan bool) 2080 go func() { 2081 defer close(donec) 2082 bs, err := ioutil.ReadAll(conn) 2083 if err != nil { 2084 t.Fatalf("ReadAll: %v", err) 2085 } 2086 got := string(bs) 2087 if got != "" { 2088 t.Errorf("read %q from server; want nothing", got) 2089 } 2090 }() 2091 select { 2092 case <-donec: 2093 case <-time.After(10 * time.Second): 2094 t.Fatalf("timeout") 2095 } 2096 } 2097 2098 // Tests that chunked server responses that write 1 byte at a time are 2099 // buffered before chunk headers are added, not after chunk headers. 2100 func TestServerBufferedChunking(t *testing.T) { 2101 conn := new(testConn) 2102 conn.readBuf.Write([]byte("GET / HTTP/1.1\r\n\r\n")) 2103 conn.closec = make(chan bool, 1) 2104 ls := &oneConnListener{conn} 2105 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 2106 rw.(Flusher).Flush() // force the Header to be sent, in chunking mode, not counting the length 2107 rw.Write([]byte{'x'}) 2108 rw.Write([]byte{'y'}) 2109 rw.Write([]byte{'z'}) 2110 })) 2111 <-conn.closec 2112 if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) { 2113 t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q", 2114 conn.writeBuf.Bytes()) 2115 } 2116 } 2117 2118 // Tests that the server flushes its response headers out when it's 2119 // ignoring the response body and waits a bit before forcefully 2120 // closing the TCP connection, causing the client to get a RST. 2121 // See https://golang.org/issue/3595 2122 func TestServerGracefulClose(t *testing.T) { 2123 defer afterTest(t) 2124 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2125 Error(w, "bye", StatusUnauthorized) 2126 })) 2127 defer ts.Close() 2128 2129 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 2130 if err != nil { 2131 t.Fatal(err) 2132 } 2133 defer conn.Close() 2134 const bodySize = 5 << 20 2135 req := []byte(fmt.Sprintf("POST / HTTP/1.1\r\nHost: foo.com\r\nContent-Length: %d\r\n\r\n", bodySize)) 2136 for i := 0; i < bodySize; i++ { 2137 req = append(req, 'x') 2138 } 2139 writeErr := make(chan error) 2140 go func() { 2141 _, err := conn.Write(req) 2142 writeErr <- err 2143 }() 2144 br := bufio.NewReader(conn) 2145 lineNum := 0 2146 for { 2147 line, err := br.ReadString('\n') 2148 if err == io.EOF { 2149 break 2150 } 2151 if err != nil { 2152 t.Fatalf("ReadLine: %v", err) 2153 } 2154 lineNum++ 2155 if lineNum == 1 && !strings.Contains(line, "401 Unauthorized") { 2156 t.Errorf("Response line = %q; want a 401", line) 2157 } 2158 } 2159 // Wait for write to finish. This is a broken pipe on both 2160 // Darwin and Linux, but checking this isn't the point of 2161 // the test. 2162 <-writeErr 2163 } 2164 2165 func TestCaseSensitiveMethod(t *testing.T) { 2166 defer afterTest(t) 2167 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2168 if r.Method != "get" { 2169 t.Errorf(`Got method %q; want "get"`, r.Method) 2170 } 2171 })) 2172 defer ts.Close() 2173 req, _ := NewRequest("get", ts.URL, nil) 2174 res, err := DefaultClient.Do(req) 2175 if err != nil { 2176 t.Error(err) 2177 return 2178 } 2179 res.Body.Close() 2180 } 2181 2182 // TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1 2183 // request (both keep-alive), when a Handler never writes any 2184 // response, the net/http package adds a "Content-Length: 0" response 2185 // header. 2186 func TestContentLengthZero(t *testing.T) { 2187 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {})) 2188 defer ts.Close() 2189 2190 for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} { 2191 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 2192 if err != nil { 2193 t.Fatalf("error dialing: %v", err) 2194 } 2195 _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version) 2196 if err != nil { 2197 t.Fatalf("error writing: %v", err) 2198 } 2199 req, _ := NewRequest("GET", "/", nil) 2200 res, err := ReadResponse(bufio.NewReader(conn), req) 2201 if err != nil { 2202 t.Fatalf("error reading response: %v", err) 2203 } 2204 if te := res.TransferEncoding; len(te) > 0 { 2205 t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te) 2206 } 2207 if cl := res.ContentLength; cl != 0 { 2208 t.Errorf("For version %q, Content-Length = %v; want 0", version, cl) 2209 } 2210 conn.Close() 2211 } 2212 } 2213 2214 func TestCloseNotifier(t *testing.T) { 2215 defer afterTest(t) 2216 gotReq := make(chan bool, 1) 2217 sawClose := make(chan bool, 1) 2218 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 2219 gotReq <- true 2220 cc := rw.(CloseNotifier).CloseNotify() 2221 <-cc 2222 sawClose <- true 2223 })) 2224 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 2225 if err != nil { 2226 t.Fatalf("error dialing: %v", err) 2227 } 2228 diec := make(chan bool) 2229 go func() { 2230 _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n") 2231 if err != nil { 2232 t.Fatal(err) 2233 } 2234 <-diec 2235 conn.Close() 2236 }() 2237 For: 2238 for { 2239 select { 2240 case <-gotReq: 2241 diec <- true 2242 case <-sawClose: 2243 break For 2244 case <-time.After(5 * time.Second): 2245 t.Fatal("timeout") 2246 } 2247 } 2248 ts.Close() 2249 } 2250 2251 func TestCloseNotifierChanLeak(t *testing.T) { 2252 defer afterTest(t) 2253 req := reqBytes("GET / HTTP/1.0\nHost: golang.org") 2254 for i := 0; i < 20; i++ { 2255 var output bytes.Buffer 2256 conn := &rwTestConn{ 2257 Reader: bytes.NewReader(req), 2258 Writer: &output, 2259 closec: make(chan bool, 1), 2260 } 2261 ln := &oneConnListener{conn: conn} 2262 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 2263 // Ignore the return value and never read from 2264 // it, testing that we don't leak goroutines 2265 // on the sending side: 2266 _ = rw.(CloseNotifier).CloseNotify() 2267 }) 2268 go Serve(ln, handler) 2269 <-conn.closec 2270 } 2271 } 2272 2273 func TestOptions(t *testing.T) { 2274 uric := make(chan string, 2) // only expect 1, but leave space for 2 2275 mux := NewServeMux() 2276 mux.HandleFunc("/", func(w ResponseWriter, r *Request) { 2277 uric <- r.RequestURI 2278 }) 2279 ts := httptest.NewServer(mux) 2280 defer ts.Close() 2281 2282 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 2283 if err != nil { 2284 t.Fatal(err) 2285 } 2286 defer conn.Close() 2287 2288 // An OPTIONS * request should succeed. 2289 _, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n")) 2290 if err != nil { 2291 t.Fatal(err) 2292 } 2293 br := bufio.NewReader(conn) 2294 res, err := ReadResponse(br, &Request{Method: "OPTIONS"}) 2295 if err != nil { 2296 t.Fatal(err) 2297 } 2298 if res.StatusCode != 200 { 2299 t.Errorf("Got non-200 response to OPTIONS *: %#v", res) 2300 } 2301 2302 // A GET * request on a ServeMux should fail. 2303 _, err = conn.Write([]byte("GET * HTTP/1.1\r\nHost: foo.com\r\n\r\n")) 2304 if err != nil { 2305 t.Fatal(err) 2306 } 2307 res, err = ReadResponse(br, &Request{Method: "GET"}) 2308 if err != nil { 2309 t.Fatal(err) 2310 } 2311 if res.StatusCode != 400 { 2312 t.Errorf("Got non-400 response to GET *: %#v", res) 2313 } 2314 2315 res, err = Get(ts.URL + "/second") 2316 if err != nil { 2317 t.Fatal(err) 2318 } 2319 res.Body.Close() 2320 if got := <-uric; got != "/second" { 2321 t.Errorf("Handler saw request for %q; want /second", got) 2322 } 2323 } 2324 2325 // Tests regarding the ordering of Write, WriteHeader, Header, and 2326 // Flush calls. In Go 1.0, rw.WriteHeader immediately flushed the 2327 // (*response).header to the wire. In Go 1.1, the actual wire flush is 2328 // delayed, so we could maybe tack on a Content-Length and better 2329 // Content-Type after we see more (or all) of the output. To preserve 2330 // compatibility with Go 1, we need to be careful to track which 2331 // headers were live at the time of WriteHeader, so we write the same 2332 // ones, even if the handler modifies them (~erroneously) after the 2333 // first Write. 2334 func TestHeaderToWire(t *testing.T) { 2335 tests := []struct { 2336 name string 2337 handler func(ResponseWriter, *Request) 2338 check func(output string) error 2339 }{ 2340 { 2341 name: "write without Header", 2342 handler: func(rw ResponseWriter, r *Request) { 2343 rw.Write([]byte("hello world")) 2344 }, 2345 check: func(got string) error { 2346 if !strings.Contains(got, "Content-Length:") { 2347 return errors.New("no content-length") 2348 } 2349 if !strings.Contains(got, "Content-Type: text/plain") { 2350 return errors.New("no content-length") 2351 } 2352 return nil 2353 }, 2354 }, 2355 { 2356 name: "Header mutation before write", 2357 handler: func(rw ResponseWriter, r *Request) { 2358 h := rw.Header() 2359 h.Set("Content-Type", "some/type") 2360 rw.Write([]byte("hello world")) 2361 h.Set("Too-Late", "bogus") 2362 }, 2363 check: func(got string) error { 2364 if !strings.Contains(got, "Content-Length:") { 2365 return errors.New("no content-length") 2366 } 2367 if !strings.Contains(got, "Content-Type: some/type") { 2368 return errors.New("wrong content-type") 2369 } 2370 if strings.Contains(got, "Too-Late") { 2371 return errors.New("don't want too-late header") 2372 } 2373 return nil 2374 }, 2375 }, 2376 { 2377 name: "write then useless Header mutation", 2378 handler: func(rw ResponseWriter, r *Request) { 2379 rw.Write([]byte("hello world")) 2380 rw.Header().Set("Too-Late", "Write already wrote headers") 2381 }, 2382 check: func(got string) error { 2383 if strings.Contains(got, "Too-Late") { 2384 return errors.New("header appeared from after WriteHeader") 2385 } 2386 return nil 2387 }, 2388 }, 2389 { 2390 name: "flush then write", 2391 handler: func(rw ResponseWriter, r *Request) { 2392 rw.(Flusher).Flush() 2393 rw.Write([]byte("post-flush")) 2394 rw.Header().Set("Too-Late", "Write already wrote headers") 2395 }, 2396 check: func(got string) error { 2397 if !strings.Contains(got, "Transfer-Encoding: chunked") { 2398 return errors.New("not chunked") 2399 } 2400 if strings.Contains(got, "Too-Late") { 2401 return errors.New("header appeared from after WriteHeader") 2402 } 2403 return nil 2404 }, 2405 }, 2406 { 2407 name: "header then flush", 2408 handler: func(rw ResponseWriter, r *Request) { 2409 rw.Header().Set("Content-Type", "some/type") 2410 rw.(Flusher).Flush() 2411 rw.Write([]byte("post-flush")) 2412 rw.Header().Set("Too-Late", "Write already wrote headers") 2413 }, 2414 check: func(got string) error { 2415 if !strings.Contains(got, "Transfer-Encoding: chunked") { 2416 return errors.New("not chunked") 2417 } 2418 if strings.Contains(got, "Too-Late") { 2419 return errors.New("header appeared from after WriteHeader") 2420 } 2421 if !strings.Contains(got, "Content-Type: some/type") { 2422 return errors.New("wrong content-length") 2423 } 2424 return nil 2425 }, 2426 }, 2427 { 2428 name: "sniff-on-first-write content-type", 2429 handler: func(rw ResponseWriter, r *Request) { 2430 rw.Write([]byte("<html><head></head><body>some html</body></html>")) 2431 rw.Header().Set("Content-Type", "x/wrong") 2432 }, 2433 check: func(got string) error { 2434 if !strings.Contains(got, "Content-Type: text/html") { 2435 return errors.New("wrong content-length; want html") 2436 } 2437 return nil 2438 }, 2439 }, 2440 { 2441 name: "explicit content-type wins", 2442 handler: func(rw ResponseWriter, r *Request) { 2443 rw.Header().Set("Content-Type", "some/type") 2444 rw.Write([]byte("<html><head></head><body>some html</body></html>")) 2445 }, 2446 check: func(got string) error { 2447 if !strings.Contains(got, "Content-Type: some/type") { 2448 return errors.New("wrong content-length; want html") 2449 } 2450 return nil 2451 }, 2452 }, 2453 { 2454 name: "empty handler", 2455 handler: func(rw ResponseWriter, r *Request) { 2456 }, 2457 check: func(got string) error { 2458 if !strings.Contains(got, "Content-Type: text/plain") { 2459 return errors.New("wrong content-length; want text/plain") 2460 } 2461 if !strings.Contains(got, "Content-Length: 0") { 2462 return errors.New("want 0 content-length") 2463 } 2464 return nil 2465 }, 2466 }, 2467 { 2468 name: "only Header, no write", 2469 handler: func(rw ResponseWriter, r *Request) { 2470 rw.Header().Set("Some-Header", "some-value") 2471 }, 2472 check: func(got string) error { 2473 if !strings.Contains(got, "Some-Header") { 2474 return errors.New("didn't get header") 2475 } 2476 return nil 2477 }, 2478 }, 2479 { 2480 name: "WriteHeader call", 2481 handler: func(rw ResponseWriter, r *Request) { 2482 rw.WriteHeader(404) 2483 rw.Header().Set("Too-Late", "some-value") 2484 }, 2485 check: func(got string) error { 2486 if !strings.Contains(got, "404") { 2487 return errors.New("wrong status") 2488 } 2489 if strings.Contains(got, "Some-Header") { 2490 return errors.New("shouldn't have seen Too-Late") 2491 } 2492 return nil 2493 }, 2494 }, 2495 } 2496 for _, tc := range tests { 2497 ht := newHandlerTest(HandlerFunc(tc.handler)) 2498 got := ht.rawResponse("GET / HTTP/1.1\nHost: golang.org") 2499 if err := tc.check(got); err != nil { 2500 t.Errorf("%s: %v\nGot response:\n%s", tc.name, err, got) 2501 } 2502 } 2503 } 2504 2505 // goTimeout runs f, failing t if f takes more than ns to complete. 2506 func goTimeout(t *testing.T, d time.Duration, f func()) { 2507 ch := make(chan bool, 2) 2508 timer := time.AfterFunc(d, func() { 2509 t.Errorf("Timeout expired after %v", d) 2510 ch <- true 2511 }) 2512 defer timer.Stop() 2513 go func() { 2514 defer func() { ch <- true }() 2515 f() 2516 }() 2517 <-ch 2518 } 2519 2520 type errorListener struct { 2521 errs []error 2522 } 2523 2524 func (l *errorListener) Accept() (c net.Conn, err error) { 2525 if len(l.errs) == 0 { 2526 return nil, io.EOF 2527 } 2528 err = l.errs[0] 2529 l.errs = l.errs[1:] 2530 return 2531 } 2532 2533 func (l *errorListener) Close() error { 2534 return nil 2535 } 2536 2537 func (l *errorListener) Addr() net.Addr { 2538 return dummyAddr("test-address") 2539 } 2540 2541 func TestAcceptMaxFds(t *testing.T) { 2542 log.SetOutput(ioutil.Discard) // is noisy otherwise 2543 defer log.SetOutput(os.Stderr) 2544 2545 ln := &errorListener{[]error{ 2546 &net.OpError{ 2547 Op: "accept", 2548 Err: syscall.EMFILE, 2549 }}} 2550 err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {}))) 2551 if err != io.EOF { 2552 t.Errorf("got error %v, want EOF", err) 2553 } 2554 } 2555 2556 func TestWriteAfterHijack(t *testing.T) { 2557 req := reqBytes("GET / HTTP/1.1\nHost: golang.org") 2558 var buf bytes.Buffer 2559 wrotec := make(chan bool, 1) 2560 conn := &rwTestConn{ 2561 Reader: bytes.NewReader(req), 2562 Writer: &buf, 2563 closec: make(chan bool, 1), 2564 } 2565 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 2566 conn, bufrw, err := rw.(Hijacker).Hijack() 2567 if err != nil { 2568 t.Error(err) 2569 return 2570 } 2571 go func() { 2572 bufrw.Write([]byte("[hijack-to-bufw]")) 2573 bufrw.Flush() 2574 conn.Write([]byte("[hijack-to-conn]")) 2575 conn.Close() 2576 wrotec <- true 2577 }() 2578 }) 2579 ln := &oneConnListener{conn: conn} 2580 go Serve(ln, handler) 2581 <-conn.closec 2582 <-wrotec 2583 if g, w := buf.String(), "[hijack-to-bufw][hijack-to-conn]"; g != w { 2584 t.Errorf("wrote %q; want %q", g, w) 2585 } 2586 } 2587 2588 func TestDoubleHijack(t *testing.T) { 2589 req := reqBytes("GET / HTTP/1.1\nHost: golang.org") 2590 var buf bytes.Buffer 2591 conn := &rwTestConn{ 2592 Reader: bytes.NewReader(req), 2593 Writer: &buf, 2594 closec: make(chan bool, 1), 2595 } 2596 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 2597 conn, _, err := rw.(Hijacker).Hijack() 2598 if err != nil { 2599 t.Error(err) 2600 return 2601 } 2602 _, _, err = rw.(Hijacker).Hijack() 2603 if err == nil { 2604 t.Errorf("got err = nil; want err != nil") 2605 } 2606 conn.Close() 2607 }) 2608 ln := &oneConnListener{conn: conn} 2609 go Serve(ln, handler) 2610 <-conn.closec 2611 } 2612 2613 // https://golang.org/issue/5955 2614 // Note that this does not test the "request too large" 2615 // exit path from the http server. This is intentional; 2616 // not sending Connection: close is just a minor wire 2617 // optimization and is pointless if dealing with a 2618 // badly behaved client. 2619 func TestHTTP10ConnectionHeader(t *testing.T) { 2620 defer afterTest(t) 2621 2622 mux := NewServeMux() 2623 mux.Handle("/", HandlerFunc(func(resp ResponseWriter, req *Request) {})) 2624 ts := httptest.NewServer(mux) 2625 defer ts.Close() 2626 2627 // net/http uses HTTP/1.1 for requests, so write requests manually 2628 tests := []struct { 2629 req string // raw http request 2630 expect []string // expected Connection header(s) 2631 }{ 2632 { 2633 req: "GET / HTTP/1.0\r\n\r\n", 2634 expect: nil, 2635 }, 2636 { 2637 req: "OPTIONS * HTTP/1.0\r\n\r\n", 2638 expect: nil, 2639 }, 2640 { 2641 req: "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", 2642 expect: []string{"keep-alive"}, 2643 }, 2644 } 2645 2646 for _, tt := range tests { 2647 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 2648 if err != nil { 2649 t.Fatal("dial err:", err) 2650 } 2651 2652 _, err = fmt.Fprint(conn, tt.req) 2653 if err != nil { 2654 t.Fatal("conn write err:", err) 2655 } 2656 2657 resp, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "GET"}) 2658 if err != nil { 2659 t.Fatal("ReadResponse err:", err) 2660 } 2661 conn.Close() 2662 resp.Body.Close() 2663 2664 got := resp.Header["Connection"] 2665 if !reflect.DeepEqual(got, tt.expect) { 2666 t.Errorf("wrong Connection headers for request %q. Got %q expect %q", tt.req, got, tt.expect) 2667 } 2668 } 2669 } 2670 2671 // See golang.org/issue/5660 2672 func TestServerReaderFromOrder(t *testing.T) { 2673 defer afterTest(t) 2674 pr, pw := io.Pipe() 2675 const size = 3 << 20 2676 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 2677 rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path 2678 done := make(chan bool) 2679 go func() { 2680 io.Copy(rw, pr) 2681 close(done) 2682 }() 2683 time.Sleep(25 * time.Millisecond) // give Copy a chance to break things 2684 n, err := io.Copy(ioutil.Discard, req.Body) 2685 if err != nil { 2686 t.Errorf("handler Copy: %v", err) 2687 return 2688 } 2689 if n != size { 2690 t.Errorf("handler Copy = %d; want %d", n, size) 2691 } 2692 pw.Write([]byte("hi")) 2693 pw.Close() 2694 <-done 2695 })) 2696 defer ts.Close() 2697 2698 req, err := NewRequest("POST", ts.URL, io.LimitReader(neverEnding('a'), size)) 2699 if err != nil { 2700 t.Fatal(err) 2701 } 2702 res, err := DefaultClient.Do(req) 2703 if err != nil { 2704 t.Fatal(err) 2705 } 2706 all, err := ioutil.ReadAll(res.Body) 2707 if err != nil { 2708 t.Fatal(err) 2709 } 2710 res.Body.Close() 2711 if string(all) != "hi" { 2712 t.Errorf("Body = %q; want hi", all) 2713 } 2714 } 2715 2716 // Issue 6157, Issue 6685 2717 func TestCodesPreventingContentTypeAndBody(t *testing.T) { 2718 for _, code := range []int{StatusNotModified, StatusNoContent, StatusContinue} { 2719 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 2720 if r.URL.Path == "/header" { 2721 w.Header().Set("Content-Length", "123") 2722 } 2723 w.WriteHeader(code) 2724 if r.URL.Path == "/more" { 2725 w.Write([]byte("stuff")) 2726 } 2727 })) 2728 for _, req := range []string{ 2729 "GET / HTTP/1.0", 2730 "GET /header HTTP/1.0", 2731 "GET /more HTTP/1.0", 2732 "GET / HTTP/1.1", 2733 "GET /header HTTP/1.1", 2734 "GET /more HTTP/1.1", 2735 } { 2736 got := ht.rawResponse(req) 2737 wantStatus := fmt.Sprintf("%d %s", code, StatusText(code)) 2738 if !strings.Contains(got, wantStatus) { 2739 t.Errorf("Code %d: Wanted %q Modified for %q: %s", code, wantStatus, req, got) 2740 } else if strings.Contains(got, "Content-Length") { 2741 t.Errorf("Code %d: Got a Content-Length from %q: %s", code, req, got) 2742 } else if strings.Contains(got, "stuff") { 2743 t.Errorf("Code %d: Response contains a body from %q: %s", code, req, got) 2744 } 2745 } 2746 } 2747 } 2748 2749 func TestContentTypeOkayOn204(t *testing.T) { 2750 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 2751 w.Header().Set("Content-Length", "123") // suppressed 2752 w.Header().Set("Content-Type", "foo/bar") 2753 w.WriteHeader(204) 2754 })) 2755 got := ht.rawResponse("GET / HTTP/1.1") 2756 if !strings.Contains(got, "Content-Type: foo/bar") { 2757 t.Errorf("Response = %q; want Content-Type: foo/bar", got) 2758 } 2759 if strings.Contains(got, "Content-Length: 123") { 2760 t.Errorf("Response = %q; don't want a Content-Length", got) 2761 } 2762 } 2763 2764 // Issue 6995 2765 // A server Handler can receive a Request, and then turn around and 2766 // give a copy of that Request.Body out to the Transport (e.g. any 2767 // proxy). So then two people own that Request.Body (both the server 2768 // and the http client), and both think they can close it on failure. 2769 // Therefore, all incoming server requests Bodies need to be thread-safe. 2770 func TestTransportAndServerSharedBodyRace(t *testing.T) { 2771 defer afterTest(t) 2772 2773 const bodySize = 1 << 20 2774 2775 unblockBackend := make(chan bool) 2776 backend := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 2777 io.CopyN(rw, req.Body, bodySize) 2778 <-unblockBackend 2779 })) 2780 defer backend.Close() 2781 2782 backendRespc := make(chan *Response, 1) 2783 proxy := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 2784 req2, _ := NewRequest("POST", backend.URL, req.Body) 2785 req2.ContentLength = bodySize 2786 2787 bresp, err := DefaultClient.Do(req2) 2788 if err != nil { 2789 t.Errorf("Proxy outbound request: %v", err) 2790 return 2791 } 2792 _, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/2) 2793 if err != nil { 2794 t.Errorf("Proxy copy error: %v", err) 2795 return 2796 } 2797 backendRespc <- bresp // to close later 2798 2799 // Try to cause a race: Both the DefaultTransport and the proxy handler's Server 2800 // will try to read/close req.Body (aka req2.Body) 2801 DefaultTransport.(*Transport).CancelRequest(req2) 2802 rw.Write([]byte("OK")) 2803 })) 2804 defer proxy.Close() 2805 2806 defer close(unblockBackend) 2807 req, _ := NewRequest("POST", proxy.URL, io.LimitReader(neverEnding('a'), bodySize)) 2808 res, err := DefaultClient.Do(req) 2809 if err != nil { 2810 t.Fatalf("Original request: %v", err) 2811 } 2812 2813 // Cleanup, so we don't leak goroutines. 2814 res.Body.Close() 2815 select { 2816 case res := <-backendRespc: 2817 res.Body.Close() 2818 default: 2819 // We failed earlier. (e.g. on DefaultClient.Do(req2)) 2820 } 2821 } 2822 2823 // Test that a hanging Request.Body.Read from another goroutine can't 2824 // cause the Handler goroutine's Request.Body.Close to block. 2825 func TestRequestBodyCloseDoesntBlock(t *testing.T) { 2826 t.Skipf("Skipping known issue; see golang.org/issue/7121") 2827 if testing.Short() { 2828 t.Skip("skipping in -short mode") 2829 } 2830 defer afterTest(t) 2831 2832 readErrCh := make(chan error, 1) 2833 errCh := make(chan error, 2) 2834 2835 server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 2836 go func(body io.Reader) { 2837 _, err := body.Read(make([]byte, 100)) 2838 readErrCh <- err 2839 }(req.Body) 2840 time.Sleep(500 * time.Millisecond) 2841 })) 2842 defer server.Close() 2843 2844 closeConn := make(chan bool) 2845 defer close(closeConn) 2846 go func() { 2847 conn, err := net.Dial("tcp", server.Listener.Addr().String()) 2848 if err != nil { 2849 errCh <- err 2850 return 2851 } 2852 defer conn.Close() 2853 _, err = conn.Write([]byte("POST / HTTP/1.1\r\nConnection: close\r\nHost: foo\r\nContent-Length: 100000\r\n\r\n")) 2854 if err != nil { 2855 errCh <- err 2856 return 2857 } 2858 // And now just block, making the server block on our 2859 // 100000 bytes of body that will never arrive. 2860 <-closeConn 2861 }() 2862 select { 2863 case err := <-readErrCh: 2864 if err == nil { 2865 t.Error("Read was nil. Expected error.") 2866 } 2867 case err := <-errCh: 2868 t.Error(err) 2869 case <-time.After(5 * time.Second): 2870 t.Error("timeout") 2871 } 2872 } 2873 2874 // test that ResponseWriter implements io.stringWriter. 2875 func TestResponseWriterWriteString(t *testing.T) { 2876 okc := make(chan bool, 1) 2877 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 2878 type stringWriter interface { 2879 WriteString(s string) (n int, err error) 2880 } 2881 _, ok := w.(stringWriter) 2882 okc <- ok 2883 })) 2884 ht.rawResponse("GET / HTTP/1.0") 2885 select { 2886 case ok := <-okc: 2887 if !ok { 2888 t.Error("ResponseWriter did not implement io.stringWriter") 2889 } 2890 default: 2891 t.Error("handler was never called") 2892 } 2893 } 2894 2895 func TestAppendTime(t *testing.T) { 2896 var b [len(TimeFormat)]byte 2897 t1 := time.Date(2013, 9, 21, 15, 41, 0, 0, time.FixedZone("CEST", 2*60*60)) 2898 res := ExportAppendTime(b[:0], t1) 2899 t2, err := ParseTime(string(res)) 2900 if err != nil { 2901 t.Fatalf("Error parsing time: %s", err) 2902 } 2903 if !t1.Equal(t2) { 2904 t.Fatalf("Times differ; expected: %v, got %v (%s)", t1, t2, string(res)) 2905 } 2906 } 2907 2908 func TestServerConnState(t *testing.T) { 2909 defer afterTest(t) 2910 handler := map[string]func(w ResponseWriter, r *Request){ 2911 "/": func(w ResponseWriter, r *Request) { 2912 fmt.Fprintf(w, "Hello.") 2913 }, 2914 "/close": func(w ResponseWriter, r *Request) { 2915 w.Header().Set("Connection", "close") 2916 fmt.Fprintf(w, "Hello.") 2917 }, 2918 "/hijack": func(w ResponseWriter, r *Request) { 2919 c, _, _ := w.(Hijacker).Hijack() 2920 c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello.")) 2921 c.Close() 2922 }, 2923 "/hijack-panic": func(w ResponseWriter, r *Request) { 2924 c, _, _ := w.(Hijacker).Hijack() 2925 c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello.")) 2926 c.Close() 2927 panic("intentional panic") 2928 }, 2929 } 2930 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2931 handler[r.URL.Path](w, r) 2932 })) 2933 defer ts.Close() 2934 2935 var mu sync.Mutex // guard stateLog and connID 2936 var stateLog = map[int][]ConnState{} 2937 var connID = map[net.Conn]int{} 2938 2939 ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) 2940 ts.Config.ConnState = func(c net.Conn, state ConnState) { 2941 if c == nil { 2942 t.Errorf("nil conn seen in state %s", state) 2943 return 2944 } 2945 mu.Lock() 2946 defer mu.Unlock() 2947 id, ok := connID[c] 2948 if !ok { 2949 id = len(connID) + 1 2950 connID[c] = id 2951 } 2952 stateLog[id] = append(stateLog[id], state) 2953 } 2954 ts.Start() 2955 2956 mustGet(t, ts.URL+"/") 2957 mustGet(t, ts.URL+"/close") 2958 2959 mustGet(t, ts.URL+"/") 2960 mustGet(t, ts.URL+"/", "Connection", "close") 2961 2962 mustGet(t, ts.URL+"/hijack") 2963 mustGet(t, ts.URL+"/hijack-panic") 2964 2965 // New->Closed 2966 { 2967 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 2968 if err != nil { 2969 t.Fatal(err) 2970 } 2971 c.Close() 2972 } 2973 2974 // New->Active->Closed 2975 { 2976 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 2977 if err != nil { 2978 t.Fatal(err) 2979 } 2980 if _, err := io.WriteString(c, "BOGUS REQUEST\r\n\r\n"); err != nil { 2981 t.Fatal(err) 2982 } 2983 c.Close() 2984 } 2985 2986 // New->Idle->Closed 2987 { 2988 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 2989 if err != nil { 2990 t.Fatal(err) 2991 } 2992 if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil { 2993 t.Fatal(err) 2994 } 2995 res, err := ReadResponse(bufio.NewReader(c), nil) 2996 if err != nil { 2997 t.Fatal(err) 2998 } 2999 if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { 3000 t.Fatal(err) 3001 } 3002 c.Close() 3003 } 3004 3005 want := map[int][]ConnState{ 3006 1: {StateNew, StateActive, StateIdle, StateActive, StateClosed}, 3007 2: {StateNew, StateActive, StateIdle, StateActive, StateClosed}, 3008 3: {StateNew, StateActive, StateHijacked}, 3009 4: {StateNew, StateActive, StateHijacked}, 3010 5: {StateNew, StateClosed}, 3011 6: {StateNew, StateActive, StateClosed}, 3012 7: {StateNew, StateActive, StateIdle, StateClosed}, 3013 } 3014 logString := func(m map[int][]ConnState) string { 3015 var b bytes.Buffer 3016 for id, l := range m { 3017 fmt.Fprintf(&b, "Conn %d: ", id) 3018 for _, s := range l { 3019 fmt.Fprintf(&b, "%s ", s) 3020 } 3021 b.WriteString("\n") 3022 } 3023 return b.String() 3024 } 3025 3026 for i := 0; i < 5; i++ { 3027 time.Sleep(time.Duration(i) * 50 * time.Millisecond) 3028 mu.Lock() 3029 match := reflect.DeepEqual(stateLog, want) 3030 mu.Unlock() 3031 if match { 3032 return 3033 } 3034 } 3035 3036 mu.Lock() 3037 t.Errorf("Unexpected events.\nGot log: %s\n Want: %s\n", logString(stateLog), logString(want)) 3038 mu.Unlock() 3039 } 3040 3041 func mustGet(t *testing.T, url string, headers ...string) { 3042 req, err := NewRequest("GET", url, nil) 3043 if err != nil { 3044 t.Fatal(err) 3045 } 3046 for len(headers) > 0 { 3047 req.Header.Add(headers[0], headers[1]) 3048 headers = headers[2:] 3049 } 3050 res, err := DefaultClient.Do(req) 3051 if err != nil { 3052 t.Errorf("Error fetching %s: %v", url, err) 3053 return 3054 } 3055 _, err = ioutil.ReadAll(res.Body) 3056 defer res.Body.Close() 3057 if err != nil { 3058 t.Errorf("Error reading %s: %v", url, err) 3059 } 3060 } 3061 3062 func TestServerKeepAlivesEnabled(t *testing.T) { 3063 defer afterTest(t) 3064 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 3065 ts.Config.SetKeepAlivesEnabled(false) 3066 ts.Start() 3067 defer ts.Close() 3068 res, err := Get(ts.URL) 3069 if err != nil { 3070 t.Fatal(err) 3071 } 3072 defer res.Body.Close() 3073 if !res.Close { 3074 t.Errorf("Body.Close == false; want true") 3075 } 3076 } 3077 3078 // golang.org/issue/7856 3079 func TestServerEmptyBodyRace(t *testing.T) { 3080 defer afterTest(t) 3081 var n int32 3082 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 3083 atomic.AddInt32(&n, 1) 3084 })) 3085 defer ts.Close() 3086 var wg sync.WaitGroup 3087 const reqs = 20 3088 for i := 0; i < reqs; i++ { 3089 wg.Add(1) 3090 go func() { 3091 defer wg.Done() 3092 res, err := Get(ts.URL) 3093 if err != nil { 3094 t.Error(err) 3095 return 3096 } 3097 defer res.Body.Close() 3098 _, err = io.Copy(ioutil.Discard, res.Body) 3099 if err != nil { 3100 t.Error(err) 3101 return 3102 } 3103 }() 3104 } 3105 wg.Wait() 3106 if got := atomic.LoadInt32(&n); got != reqs { 3107 t.Errorf("handler ran %d times; want %d", got, reqs) 3108 } 3109 } 3110 3111 func TestServerConnStateNew(t *testing.T) { 3112 sawNew := false // if the test is buggy, we'll race on this variable. 3113 srv := &Server{ 3114 ConnState: func(c net.Conn, state ConnState) { 3115 if state == StateNew { 3116 sawNew = true // testing that this write isn't racy 3117 } 3118 }, 3119 Handler: HandlerFunc(func(w ResponseWriter, r *Request) {}), // irrelevant 3120 } 3121 srv.Serve(&oneConnListener{ 3122 conn: &rwTestConn{ 3123 Reader: strings.NewReader("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"), 3124 Writer: ioutil.Discard, 3125 }, 3126 }) 3127 if !sawNew { // testing that this read isn't racy 3128 t.Error("StateNew not seen") 3129 } 3130 } 3131 3132 type closeWriteTestConn struct { 3133 rwTestConn 3134 didCloseWrite bool 3135 } 3136 3137 func (c *closeWriteTestConn) CloseWrite() error { 3138 c.didCloseWrite = true 3139 return nil 3140 } 3141 3142 func TestCloseWrite(t *testing.T) { 3143 var srv Server 3144 var testConn closeWriteTestConn 3145 c, err := ExportServerNewConn(&srv, &testConn) 3146 if err != nil { 3147 t.Fatal(err) 3148 } 3149 ExportCloseWriteAndWait(c) 3150 if !testConn.didCloseWrite { 3151 t.Error("didn't see CloseWrite call") 3152 } 3153 } 3154 3155 // This verifies that a handler can Flush and then Hijack. 3156 // 3157 // An similar test crashed once during development, but it was only 3158 // testing this tangentially and temporarily until another TODO was 3159 // fixed. 3160 // 3161 // So add an explicit test for this. 3162 func TestServerFlushAndHijack(t *testing.T) { 3163 defer afterTest(t) 3164 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3165 io.WriteString(w, "Hello, ") 3166 w.(Flusher).Flush() 3167 conn, buf, _ := w.(Hijacker).Hijack() 3168 buf.WriteString("6\r\nworld!\r\n0\r\n\r\n") 3169 if err := buf.Flush(); err != nil { 3170 t.Error(err) 3171 } 3172 if err := conn.Close(); err != nil { 3173 t.Error(err) 3174 } 3175 })) 3176 defer ts.Close() 3177 res, err := Get(ts.URL) 3178 if err != nil { 3179 t.Fatal(err) 3180 } 3181 defer res.Body.Close() 3182 all, err := ioutil.ReadAll(res.Body) 3183 if err != nil { 3184 t.Fatal(err) 3185 } 3186 if want := "Hello, world!"; string(all) != want { 3187 t.Errorf("Got %q; want %q", all, want) 3188 } 3189 } 3190 3191 // golang.org/issue/8534 -- the Server shouldn't reuse a connection 3192 // for keep-alive after it's seen any Write error (e.g. a timeout) on 3193 // that net.Conn. 3194 // 3195 // To test, verify we don't timeout or see fewer unique client 3196 // addresses (== unique connections) than requests. 3197 func TestServerKeepAliveAfterWriteError(t *testing.T) { 3198 if testing.Short() { 3199 t.Skip("skipping in -short mode") 3200 } 3201 defer afterTest(t) 3202 const numReq = 3 3203 addrc := make(chan string, numReq) 3204 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3205 addrc <- r.RemoteAddr 3206 time.Sleep(500 * time.Millisecond) 3207 w.(Flusher).Flush() 3208 })) 3209 ts.Config.WriteTimeout = 250 * time.Millisecond 3210 ts.Start() 3211 defer ts.Close() 3212 3213 errc := make(chan error, numReq) 3214 go func() { 3215 defer close(errc) 3216 for i := 0; i < numReq; i++ { 3217 res, err := Get(ts.URL) 3218 if res != nil { 3219 res.Body.Close() 3220 } 3221 errc <- err 3222 } 3223 }() 3224 3225 timeout := time.NewTimer(numReq * 2 * time.Second) // 4x overkill 3226 defer timeout.Stop() 3227 addrSeen := map[string]bool{} 3228 numOkay := 0 3229 for { 3230 select { 3231 case v := <-addrc: 3232 addrSeen[v] = true 3233 case err, ok := <-errc: 3234 if !ok { 3235 if len(addrSeen) != numReq { 3236 t.Errorf("saw %d unique client addresses; want %d", len(addrSeen), numReq) 3237 } 3238 if numOkay != 0 { 3239 t.Errorf("got %d successful client requests; want 0", numOkay) 3240 } 3241 return 3242 } 3243 if err == nil { 3244 numOkay++ 3245 } 3246 case <-timeout.C: 3247 t.Fatal("timeout waiting for requests to complete") 3248 } 3249 } 3250 } 3251 3252 // Issue 9987: shouldn't add automatic Content-Length (or 3253 // Content-Type) if a Transfer-Encoding was set by the handler. 3254 func TestNoContentLengthIfTransferEncoding(t *testing.T) { 3255 defer afterTest(t) 3256 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3257 w.Header().Set("Transfer-Encoding", "foo") 3258 io.WriteString(w, "<html>") 3259 })) 3260 defer ts.Close() 3261 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 3262 if err != nil { 3263 t.Fatalf("Dial: %v", err) 3264 } 3265 defer c.Close() 3266 if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil { 3267 t.Fatal(err) 3268 } 3269 bs := bufio.NewScanner(c) 3270 var got bytes.Buffer 3271 for bs.Scan() { 3272 if strings.TrimSpace(bs.Text()) == "" { 3273 break 3274 } 3275 got.WriteString(bs.Text()) 3276 got.WriteByte('\n') 3277 } 3278 if err := bs.Err(); err != nil { 3279 t.Fatal(err) 3280 } 3281 if strings.Contains(got.String(), "Content-Length") { 3282 t.Errorf("Unexpected Content-Length in response headers: %s", got.String()) 3283 } 3284 if strings.Contains(got.String(), "Content-Type") { 3285 t.Errorf("Unexpected Content-Type in response headers: %s", got.String()) 3286 } 3287 } 3288 3289 // tolerate extra CRLF(s) before Request-Line on subsequent requests on a conn 3290 // Issue 10876. 3291 func TestTolerateCRLFBeforeRequestLine(t *testing.T) { 3292 req := []byte("POST / HTTP/1.1\r\nHost: golang.org\r\nContent-Length: 3\r\n\r\nABC" + 3293 "\r\n\r\n" + // <-- this stuff is bogus, but we'll ignore it 3294 "GET / HTTP/1.1\r\nHost: golang.org\r\n\r\n") 3295 var buf bytes.Buffer 3296 conn := &rwTestConn{ 3297 Reader: bytes.NewReader(req), 3298 Writer: &buf, 3299 closec: make(chan bool, 1), 3300 } 3301 ln := &oneConnListener{conn: conn} 3302 numReq := 0 3303 go Serve(ln, HandlerFunc(func(rw ResponseWriter, r *Request) { 3304 numReq++ 3305 })) 3306 <-conn.closec 3307 if numReq != 2 { 3308 t.Errorf("num requests = %d; want 2", numReq) 3309 t.Logf("Res: %s", buf.Bytes()) 3310 } 3311 } 3312 3313 func TestIssue11549_Expect100(t *testing.T) { 3314 req := reqBytes(`PUT /readbody HTTP/1.1 3315 User-Agent: PycURL/7.22.0 3316 Host: 127.0.0.1:9000 3317 Accept: */* 3318 Expect: 100-continue 3319 Content-Length: 10 3320 3321 HelloWorldPUT /noreadbody HTTP/1.1 3322 User-Agent: PycURL/7.22.0 3323 Host: 127.0.0.1:9000 3324 Accept: */* 3325 Expect: 100-continue 3326 Content-Length: 10 3327 3328 GET /should-be-ignored HTTP/1.1 3329 Host: foo 3330 3331 `) 3332 var buf bytes.Buffer 3333 conn := &rwTestConn{ 3334 Reader: bytes.NewReader(req), 3335 Writer: &buf, 3336 closec: make(chan bool, 1), 3337 } 3338 ln := &oneConnListener{conn: conn} 3339 numReq := 0 3340 go Serve(ln, HandlerFunc(func(w ResponseWriter, r *Request) { 3341 numReq++ 3342 if r.URL.Path == "/readbody" { 3343 ioutil.ReadAll(r.Body) 3344 } 3345 io.WriteString(w, "Hello world!") 3346 })) 3347 <-conn.closec 3348 if numReq != 2 { 3349 t.Errorf("num requests = %d; want 2", numReq) 3350 } 3351 if !strings.Contains(buf.String(), "Connection: close\r\n") { 3352 t.Errorf("expected 'Connection: close' in response; got: %s", buf.String()) 3353 } 3354 } 3355 3356 // If a Handler finishes and there's an unread request body, 3357 // verify the server try to do implicit read on it before replying. 3358 func TestHandlerFinishSkipBigContentLengthRead(t *testing.T) { 3359 conn := &testConn{closec: make(chan bool)} 3360 conn.readBuf.Write([]byte(fmt.Sprintf( 3361 "POST / HTTP/1.1\r\n" + 3362 "Host: test\r\n" + 3363 "Content-Length: 9999999999\r\n" + 3364 "\r\n" + strings.Repeat("a", 1<<20)))) 3365 3366 ls := &oneConnListener{conn} 3367 var inHandlerLen int 3368 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 3369 inHandlerLen = conn.readBuf.Len() 3370 rw.WriteHeader(404) 3371 })) 3372 <-conn.closec 3373 afterHandlerLen := conn.readBuf.Len() 3374 3375 if afterHandlerLen != inHandlerLen { 3376 t.Errorf("unexpected implicit read. Read buffer went from %d -> %d", inHandlerLen, afterHandlerLen) 3377 } 3378 } 3379 3380 func BenchmarkClientServer(b *testing.B) { 3381 b.ReportAllocs() 3382 b.StopTimer() 3383 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 3384 fmt.Fprintf(rw, "Hello world.\n") 3385 })) 3386 defer ts.Close() 3387 b.StartTimer() 3388 3389 for i := 0; i < b.N; i++ { 3390 res, err := Get(ts.URL) 3391 if err != nil { 3392 b.Fatal("Get:", err) 3393 } 3394 all, err := ioutil.ReadAll(res.Body) 3395 res.Body.Close() 3396 if err != nil { 3397 b.Fatal("ReadAll:", err) 3398 } 3399 body := string(all) 3400 if body != "Hello world.\n" { 3401 b.Fatal("Got body:", body) 3402 } 3403 } 3404 3405 b.StopTimer() 3406 } 3407 3408 func BenchmarkClientServerParallel4(b *testing.B) { 3409 benchmarkClientServerParallel(b, 4, false) 3410 } 3411 3412 func BenchmarkClientServerParallel64(b *testing.B) { 3413 benchmarkClientServerParallel(b, 64, false) 3414 } 3415 3416 func BenchmarkClientServerParallelTLS4(b *testing.B) { 3417 benchmarkClientServerParallel(b, 4, true) 3418 } 3419 3420 func BenchmarkClientServerParallelTLS64(b *testing.B) { 3421 benchmarkClientServerParallel(b, 64, true) 3422 } 3423 3424 func benchmarkClientServerParallel(b *testing.B, parallelism int, useTLS bool) { 3425 b.ReportAllocs() 3426 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 3427 fmt.Fprintf(rw, "Hello world.\n") 3428 })) 3429 if useTLS { 3430 ts.StartTLS() 3431 } else { 3432 ts.Start() 3433 } 3434 defer ts.Close() 3435 b.ResetTimer() 3436 b.SetParallelism(parallelism) 3437 b.RunParallel(func(pb *testing.PB) { 3438 noVerifyTransport := &Transport{ 3439 TLSClientConfig: &tls.Config{ 3440 InsecureSkipVerify: true, 3441 }, 3442 } 3443 defer noVerifyTransport.CloseIdleConnections() 3444 client := &Client{Transport: noVerifyTransport} 3445 for pb.Next() { 3446 res, err := client.Get(ts.URL) 3447 if err != nil { 3448 b.Logf("Get: %v", err) 3449 continue 3450 } 3451 all, err := ioutil.ReadAll(res.Body) 3452 res.Body.Close() 3453 if err != nil { 3454 b.Logf("ReadAll: %v", err) 3455 continue 3456 } 3457 body := string(all) 3458 if body != "Hello world.\n" { 3459 panic("Got body: " + body) 3460 } 3461 } 3462 }) 3463 } 3464 3465 // A benchmark for profiling the server without the HTTP client code. 3466 // The client code runs in a subprocess. 3467 // 3468 // For use like: 3469 // $ go test -c 3470 // $ ./http.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=http.prof 3471 // $ go tool pprof http.test http.prof 3472 // (pprof) web 3473 func BenchmarkServer(b *testing.B) { 3474 b.ReportAllocs() 3475 // Child process mode; 3476 if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" { 3477 n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N")) 3478 if err != nil { 3479 panic(err) 3480 } 3481 for i := 0; i < n; i++ { 3482 res, err := Get(url) 3483 if err != nil { 3484 log.Panicf("Get: %v", err) 3485 } 3486 all, err := ioutil.ReadAll(res.Body) 3487 res.Body.Close() 3488 if err != nil { 3489 log.Panicf("ReadAll: %v", err) 3490 } 3491 body := string(all) 3492 if body != "Hello world.\n" { 3493 log.Panicf("Got body: %q", body) 3494 } 3495 } 3496 os.Exit(0) 3497 return 3498 } 3499 3500 var res = []byte("Hello world.\n") 3501 b.StopTimer() 3502 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 3503 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 3504 rw.Write(res) 3505 })) 3506 defer ts.Close() 3507 b.StartTimer() 3508 3509 cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer$") 3510 cmd.Env = append([]string{ 3511 fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N), 3512 fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL), 3513 }, os.Environ()...) 3514 out, err := cmd.CombinedOutput() 3515 if err != nil { 3516 b.Errorf("Test failure: %v, with output: %s", err, out) 3517 } 3518 } 3519 3520 // getNoBody wraps Get but closes any Response.Body before returning the response. 3521 func getNoBody(urlStr string) (*Response, error) { 3522 res, err := Get(urlStr) 3523 if err != nil { 3524 return nil, err 3525 } 3526 res.Body.Close() 3527 return res, nil 3528 } 3529 3530 // A benchmark for profiling the client without the HTTP server code. 3531 // The server code runs in a subprocess. 3532 func BenchmarkClient(b *testing.B) { 3533 b.ReportAllocs() 3534 b.StopTimer() 3535 defer afterTest(b) 3536 3537 port := os.Getenv("TEST_BENCH_SERVER_PORT") // can be set by user 3538 if port == "" { 3539 port = "39207" 3540 } 3541 var data = []byte("Hello world.\n") 3542 if server := os.Getenv("TEST_BENCH_SERVER"); server != "" { 3543 // Server process mode. 3544 HandleFunc("/", func(w ResponseWriter, r *Request) { 3545 r.ParseForm() 3546 if r.Form.Get("stop") != "" { 3547 os.Exit(0) 3548 } 3549 w.Header().Set("Content-Type", "text/html; charset=utf-8") 3550 w.Write(data) 3551 }) 3552 log.Fatal(ListenAndServe("localhost:"+port, nil)) 3553 } 3554 3555 // Start server process. 3556 cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkClient$") 3557 cmd.Env = append(os.Environ(), "TEST_BENCH_SERVER=yes") 3558 if err := cmd.Start(); err != nil { 3559 b.Fatalf("subprocess failed to start: %v", err) 3560 } 3561 defer cmd.Process.Kill() 3562 done := make(chan error) 3563 go func() { 3564 done <- cmd.Wait() 3565 }() 3566 3567 // Wait for the server process to respond. 3568 url := "http://localhost:" + port + "/" 3569 for i := 0; i < 100; i++ { 3570 time.Sleep(50 * time.Millisecond) 3571 if _, err := getNoBody(url); err == nil { 3572 break 3573 } 3574 if i == 99 { 3575 b.Fatalf("subprocess does not respond") 3576 } 3577 } 3578 3579 // Do b.N requests to the server. 3580 b.StartTimer() 3581 for i := 0; i < b.N; i++ { 3582 res, err := Get(url) 3583 if err != nil { 3584 b.Fatalf("Get: %v", err) 3585 } 3586 body, err := ioutil.ReadAll(res.Body) 3587 res.Body.Close() 3588 if err != nil { 3589 b.Fatalf("ReadAll: %v", err) 3590 } 3591 if bytes.Compare(body, data) != 0 { 3592 b.Fatalf("Got body: %q", body) 3593 } 3594 } 3595 b.StopTimer() 3596 3597 // Instruct server process to stop. 3598 getNoBody(url + "?stop=yes") 3599 select { 3600 case err := <-done: 3601 if err != nil { 3602 b.Fatalf("subprocess failed: %v", err) 3603 } 3604 case <-time.After(5 * time.Second): 3605 b.Fatalf("subprocess did not stop") 3606 } 3607 } 3608 3609 func BenchmarkServerFakeConnNoKeepAlive(b *testing.B) { 3610 b.ReportAllocs() 3611 req := reqBytes(`GET / HTTP/1.0 3612 Host: golang.org 3613 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 3614 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 3615 Accept-Encoding: gzip,deflate,sdch 3616 Accept-Language: en-US,en;q=0.8 3617 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 3618 `) 3619 res := []byte("Hello world!\n") 3620 3621 conn := &testConn{ 3622 // testConn.Close will not push into the channel 3623 // if it's full. 3624 closec: make(chan bool, 1), 3625 } 3626 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3627 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 3628 rw.Write(res) 3629 }) 3630 ln := new(oneConnListener) 3631 for i := 0; i < b.N; i++ { 3632 conn.readBuf.Reset() 3633 conn.writeBuf.Reset() 3634 conn.readBuf.Write(req) 3635 ln.conn = conn 3636 Serve(ln, handler) 3637 <-conn.closec 3638 } 3639 } 3640 3641 // repeatReader reads content count times, then EOFs. 3642 type repeatReader struct { 3643 content []byte 3644 count int 3645 off int 3646 } 3647 3648 func (r *repeatReader) Read(p []byte) (n int, err error) { 3649 if r.count <= 0 { 3650 return 0, io.EOF 3651 } 3652 n = copy(p, r.content[r.off:]) 3653 r.off += n 3654 if r.off == len(r.content) { 3655 r.count-- 3656 r.off = 0 3657 } 3658 return 3659 } 3660 3661 func BenchmarkServerFakeConnWithKeepAlive(b *testing.B) { 3662 b.ReportAllocs() 3663 3664 req := reqBytes(`GET / HTTP/1.1 3665 Host: golang.org 3666 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 3667 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 3668 Accept-Encoding: gzip,deflate,sdch 3669 Accept-Language: en-US,en;q=0.8 3670 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 3671 `) 3672 res := []byte("Hello world!\n") 3673 3674 conn := &rwTestConn{ 3675 Reader: &repeatReader{content: req, count: b.N}, 3676 Writer: ioutil.Discard, 3677 closec: make(chan bool, 1), 3678 } 3679 handled := 0 3680 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3681 handled++ 3682 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 3683 rw.Write(res) 3684 }) 3685 ln := &oneConnListener{conn: conn} 3686 go Serve(ln, handler) 3687 <-conn.closec 3688 if b.N != handled { 3689 b.Errorf("b.N=%d but handled %d", b.N, handled) 3690 } 3691 } 3692 3693 // same as above, but representing the most simple possible request 3694 // and handler. Notably: the handler does not call rw.Header(). 3695 func BenchmarkServerFakeConnWithKeepAliveLite(b *testing.B) { 3696 b.ReportAllocs() 3697 3698 req := reqBytes(`GET / HTTP/1.1 3699 Host: golang.org 3700 `) 3701 res := []byte("Hello world!\n") 3702 3703 conn := &rwTestConn{ 3704 Reader: &repeatReader{content: req, count: b.N}, 3705 Writer: ioutil.Discard, 3706 closec: make(chan bool, 1), 3707 } 3708 handled := 0 3709 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3710 handled++ 3711 rw.Write(res) 3712 }) 3713 ln := &oneConnListener{conn: conn} 3714 go Serve(ln, handler) 3715 <-conn.closec 3716 if b.N != handled { 3717 b.Errorf("b.N=%d but handled %d", b.N, handled) 3718 } 3719 } 3720 3721 const someResponse = "<html>some response</html>" 3722 3723 // A Response that's just no bigger than 2KB, the buffer-before-chunking threshold. 3724 var response = bytes.Repeat([]byte(someResponse), 2<<10/len(someResponse)) 3725 3726 // Both Content-Type and Content-Length set. Should be no buffering. 3727 func BenchmarkServerHandlerTypeLen(b *testing.B) { 3728 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 3729 w.Header().Set("Content-Type", "text/html") 3730 w.Header().Set("Content-Length", strconv.Itoa(len(response))) 3731 w.Write(response) 3732 })) 3733 } 3734 3735 // A Content-Type is set, but no length. No sniffing, but will count the Content-Length. 3736 func BenchmarkServerHandlerNoLen(b *testing.B) { 3737 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 3738 w.Header().Set("Content-Type", "text/html") 3739 w.Write(response) 3740 })) 3741 } 3742 3743 // A Content-Length is set, but the Content-Type will be sniffed. 3744 func BenchmarkServerHandlerNoType(b *testing.B) { 3745 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 3746 w.Header().Set("Content-Length", strconv.Itoa(len(response))) 3747 w.Write(response) 3748 })) 3749 } 3750 3751 // Neither a Content-Type or Content-Length, so sniffed and counted. 3752 func BenchmarkServerHandlerNoHeader(b *testing.B) { 3753 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 3754 w.Write(response) 3755 })) 3756 } 3757 3758 func benchmarkHandler(b *testing.B, h Handler) { 3759 b.ReportAllocs() 3760 req := reqBytes(`GET / HTTP/1.1 3761 Host: golang.org 3762 `) 3763 conn := &rwTestConn{ 3764 Reader: &repeatReader{content: req, count: b.N}, 3765 Writer: ioutil.Discard, 3766 closec: make(chan bool, 1), 3767 } 3768 handled := 0 3769 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3770 handled++ 3771 h.ServeHTTP(rw, r) 3772 }) 3773 ln := &oneConnListener{conn: conn} 3774 go Serve(ln, handler) 3775 <-conn.closec 3776 if b.N != handled { 3777 b.Errorf("b.N=%d but handled %d", b.N, handled) 3778 } 3779 } 3780 3781 func BenchmarkServerHijack(b *testing.B) { 3782 b.ReportAllocs() 3783 req := reqBytes(`GET / HTTP/1.1 3784 Host: golang.org 3785 `) 3786 h := HandlerFunc(func(w ResponseWriter, r *Request) { 3787 conn, _, err := w.(Hijacker).Hijack() 3788 if err != nil { 3789 panic(err) 3790 } 3791 conn.Close() 3792 }) 3793 conn := &rwTestConn{ 3794 Writer: ioutil.Discard, 3795 closec: make(chan bool, 1), 3796 } 3797 ln := &oneConnListener{conn: conn} 3798 for i := 0; i < b.N; i++ { 3799 conn.Reader = bytes.NewReader(req) 3800 ln.conn = conn 3801 Serve(ln, h) 3802 <-conn.closec 3803 } 3804 } 3805 3806 func BenchmarkCloseNotifier(b *testing.B) { 3807 b.ReportAllocs() 3808 b.StopTimer() 3809 sawClose := make(chan bool) 3810 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 3811 <-rw.(CloseNotifier).CloseNotify() 3812 sawClose <- true 3813 })) 3814 defer ts.Close() 3815 tot := time.NewTimer(5 * time.Second) 3816 defer tot.Stop() 3817 b.StartTimer() 3818 for i := 0; i < b.N; i++ { 3819 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3820 if err != nil { 3821 b.Fatalf("error dialing: %v", err) 3822 } 3823 _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n") 3824 if err != nil { 3825 b.Fatal(err) 3826 } 3827 conn.Close() 3828 tot.Reset(5 * time.Second) 3829 select { 3830 case <-sawClose: 3831 case <-tot.C: 3832 b.Fatal("timeout") 3833 } 3834 } 3835 b.StopTimer() 3836 }