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