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