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