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