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