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