github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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 "compress/gzip" 13 "compress/zlib" 14 "context" 15 "crypto/tls" 16 "encoding/json" 17 "errors" 18 "fmt" 19 "internal/testenv" 20 "io" 21 "io/ioutil" 22 "log" 23 "math/rand" 24 "net" 25 . "net/http" 26 "net/http/httptest" 27 "net/http/httputil" 28 "net/http/internal" 29 "net/url" 30 "os" 31 "os/exec" 32 "path/filepath" 33 "reflect" 34 "regexp" 35 "runtime" 36 "runtime/debug" 37 "strconv" 38 "strings" 39 "sync" 40 "sync/atomic" 41 "syscall" 42 "testing" 43 "time" 44 ) 45 46 type dummyAddr string 47 type oneConnListener struct { 48 conn net.Conn 49 } 50 51 func (l *oneConnListener) Accept() (c net.Conn, err error) { 52 c = l.conn 53 if c == nil { 54 err = io.EOF 55 return 56 } 57 err = nil 58 l.conn = nil 59 return 60 } 61 62 func (l *oneConnListener) Close() error { 63 return nil 64 } 65 66 func (l *oneConnListener) Addr() net.Addr { 67 return dummyAddr("test-address") 68 } 69 70 func (a dummyAddr) Network() string { 71 return string(a) 72 } 73 74 func (a dummyAddr) String() string { 75 return string(a) 76 } 77 78 type noopConn struct{} 79 80 func (noopConn) LocalAddr() net.Addr { return dummyAddr("local-addr") } 81 func (noopConn) RemoteAddr() net.Addr { return dummyAddr("remote-addr") } 82 func (noopConn) SetDeadline(t time.Time) error { return nil } 83 func (noopConn) SetReadDeadline(t time.Time) error { return nil } 84 func (noopConn) SetWriteDeadline(t time.Time) error { return nil } 85 86 type rwTestConn struct { 87 io.Reader 88 io.Writer 89 noopConn 90 91 closeFunc func() error // called if non-nil 92 closec chan bool // else, if non-nil, send value to it on close 93 } 94 95 func (c *rwTestConn) Close() error { 96 if c.closeFunc != nil { 97 return c.closeFunc() 98 } 99 select { 100 case c.closec <- true: 101 default: 102 } 103 return nil 104 } 105 106 type testConn struct { 107 readMu sync.Mutex // for TestHandlerBodyClose 108 readBuf bytes.Buffer 109 writeBuf bytes.Buffer 110 closec chan bool // if non-nil, send value to it on close 111 noopConn 112 } 113 114 func (c *testConn) Read(b []byte) (int, error) { 115 c.readMu.Lock() 116 defer c.readMu.Unlock() 117 return c.readBuf.Read(b) 118 } 119 120 func (c *testConn) Write(b []byte) (int, error) { 121 return c.writeBuf.Write(b) 122 } 123 124 func (c *testConn) Close() error { 125 select { 126 case c.closec <- true: 127 default: 128 } 129 return nil 130 } 131 132 // reqBytes treats req as a request (with \n delimiters) and returns it with \r\n delimiters, 133 // ending in \r\n\r\n 134 func reqBytes(req string) []byte { 135 return []byte(strings.ReplaceAll(strings.TrimSpace(req), "\n", "\r\n") + "\r\n\r\n") 136 } 137 138 type handlerTest struct { 139 logbuf bytes.Buffer 140 handler Handler 141 } 142 143 func newHandlerTest(h Handler) handlerTest { 144 return handlerTest{handler: h} 145 } 146 147 func (ht *handlerTest) rawResponse(req string) string { 148 reqb := reqBytes(req) 149 var output bytes.Buffer 150 conn := &rwTestConn{ 151 Reader: bytes.NewReader(reqb), 152 Writer: &output, 153 closec: make(chan bool, 1), 154 } 155 ln := &oneConnListener{conn: conn} 156 srv := &Server{ 157 ErrorLog: log.New(&ht.logbuf, "", 0), 158 Handler: ht.handler, 159 } 160 go srv.Serve(ln) 161 <-conn.closec 162 return output.String() 163 } 164 165 func TestConsumingBodyOnNextConn(t *testing.T) { 166 t.Parallel() 167 defer afterTest(t) 168 conn := new(testConn) 169 for i := 0; i < 2; i++ { 170 conn.readBuf.Write([]byte( 171 "POST / HTTP/1.1\r\n" + 172 "Host: test\r\n" + 173 "Content-Length: 11\r\n" + 174 "\r\n" + 175 "foo=1&bar=1")) 176 } 177 178 reqNum := 0 179 ch := make(chan *Request) 180 servech := make(chan error) 181 listener := &oneConnListener{conn} 182 handler := func(res ResponseWriter, req *Request) { 183 reqNum++ 184 ch <- req 185 } 186 187 go func() { 188 servech <- Serve(listener, HandlerFunc(handler)) 189 }() 190 191 var req *Request 192 req = <-ch 193 if req == nil { 194 t.Fatal("Got nil first request.") 195 } 196 if req.Method != "POST" { 197 t.Errorf("For request #1's method, got %q; expected %q", 198 req.Method, "POST") 199 } 200 201 req = <-ch 202 if req == nil { 203 t.Fatal("Got nil first request.") 204 } 205 if req.Method != "POST" { 206 t.Errorf("For request #2's method, got %q; expected %q", 207 req.Method, "POST") 208 } 209 210 if serveerr := <-servech; serveerr != io.EOF { 211 t.Errorf("Serve returned %q; expected EOF", serveerr) 212 } 213 } 214 215 type stringHandler string 216 217 func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) { 218 w.Header().Set("Result", string(s)) 219 } 220 221 var handlers = []struct { 222 pattern string 223 msg string 224 }{ 225 {"/", "Default"}, 226 {"/someDir/", "someDir"}, 227 {"/#/", "hash"}, 228 {"someHost.com/someDir/", "someHost.com/someDir"}, 229 } 230 231 var vtests = []struct { 232 url string 233 expected string 234 }{ 235 {"http://localhost/someDir/apage", "someDir"}, 236 {"http://localhost/%23/apage", "hash"}, 237 {"http://localhost/otherDir/apage", "Default"}, 238 {"http://someHost.com/someDir/apage", "someHost.com/someDir"}, 239 {"http://otherHost.com/someDir/apage", "someDir"}, 240 {"http://otherHost.com/aDir/apage", "Default"}, 241 // redirections for trees 242 {"http://localhost/someDir", "/someDir/"}, 243 {"http://localhost/%23", "/%23/"}, 244 {"http://someHost.com/someDir", "/someDir/"}, 245 } 246 247 func TestHostHandlers(t *testing.T) { 248 setParallel(t) 249 defer afterTest(t) 250 mux := NewServeMux() 251 for _, h := range handlers { 252 mux.Handle(h.pattern, stringHandler(h.msg)) 253 } 254 ts := httptest.NewServer(mux) 255 defer ts.Close() 256 257 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 258 if err != nil { 259 t.Fatal(err) 260 } 261 defer conn.Close() 262 cc := httputil.NewClientConn(conn, nil) 263 for _, vt := range vtests { 264 var r *Response 265 var req Request 266 if req.URL, err = url.Parse(vt.url); err != nil { 267 t.Errorf("cannot parse url: %v", err) 268 continue 269 } 270 if err := cc.Write(&req); err != nil { 271 t.Errorf("writing request: %v", err) 272 continue 273 } 274 r, err := cc.Read(&req) 275 if err != nil { 276 t.Errorf("reading response: %v", err) 277 continue 278 } 279 switch r.StatusCode { 280 case StatusOK: 281 s := r.Header.Get("Result") 282 if s != vt.expected { 283 t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected) 284 } 285 case StatusMovedPermanently: 286 s := r.Header.Get("Location") 287 if s != vt.expected { 288 t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected) 289 } 290 default: 291 t.Errorf("Get(%q) unhandled status code %d", vt.url, r.StatusCode) 292 } 293 } 294 } 295 296 var serveMuxRegister = []struct { 297 pattern string 298 h Handler 299 }{ 300 {"/dir/", serve(200)}, 301 {"/search", serve(201)}, 302 {"codesearch.google.com/search", serve(202)}, 303 {"codesearch.google.com/", serve(203)}, 304 {"example.com/", HandlerFunc(checkQueryStringHandler)}, 305 } 306 307 // serve returns a handler that sends a response with the given code. 308 func serve(code int) HandlerFunc { 309 return func(w ResponseWriter, r *Request) { 310 w.WriteHeader(code) 311 } 312 } 313 314 // checkQueryStringHandler checks if r.URL.RawQuery has the same value 315 // as the URL excluding the scheme and the query string and sends 200 316 // response code if it is, 500 otherwise. 317 func checkQueryStringHandler(w ResponseWriter, r *Request) { 318 u := *r.URL 319 u.Scheme = "http" 320 u.Host = r.Host 321 u.RawQuery = "" 322 if "http://"+r.URL.RawQuery == u.String() { 323 w.WriteHeader(200) 324 } else { 325 w.WriteHeader(500) 326 } 327 } 328 329 var serveMuxTests = []struct { 330 method string 331 host string 332 path string 333 code int 334 pattern string 335 }{ 336 {"GET", "google.com", "/", 404, ""}, 337 {"GET", "google.com", "/dir", 301, "/dir/"}, 338 {"GET", "google.com", "/dir/", 200, "/dir/"}, 339 {"GET", "google.com", "/dir/file", 200, "/dir/"}, 340 {"GET", "google.com", "/search", 201, "/search"}, 341 {"GET", "google.com", "/search/", 404, ""}, 342 {"GET", "google.com", "/search/foo", 404, ""}, 343 {"GET", "codesearch.google.com", "/search", 202, "codesearch.google.com/search"}, 344 {"GET", "codesearch.google.com", "/search/", 203, "codesearch.google.com/"}, 345 {"GET", "codesearch.google.com", "/search/foo", 203, "codesearch.google.com/"}, 346 {"GET", "codesearch.google.com", "/", 203, "codesearch.google.com/"}, 347 {"GET", "codesearch.google.com:443", "/", 203, "codesearch.google.com/"}, 348 {"GET", "images.google.com", "/search", 201, "/search"}, 349 {"GET", "images.google.com", "/search/", 404, ""}, 350 {"GET", "images.google.com", "/search/foo", 404, ""}, 351 {"GET", "google.com", "/../search", 301, "/search"}, 352 {"GET", "google.com", "/dir/..", 301, ""}, 353 {"GET", "google.com", "/dir/..", 301, ""}, 354 {"GET", "google.com", "/dir/./file", 301, "/dir/"}, 355 356 // The /foo -> /foo/ redirect applies to CONNECT requests 357 // but the path canonicalization does not. 358 {"CONNECT", "google.com", "/dir", 301, "/dir/"}, 359 {"CONNECT", "google.com", "/../search", 404, ""}, 360 {"CONNECT", "google.com", "/dir/..", 200, "/dir/"}, 361 {"CONNECT", "google.com", "/dir/..", 200, "/dir/"}, 362 {"CONNECT", "google.com", "/dir/./file", 200, "/dir/"}, 363 } 364 365 func TestServeMuxHandler(t *testing.T) { 366 setParallel(t) 367 mux := NewServeMux() 368 for _, e := range serveMuxRegister { 369 mux.Handle(e.pattern, e.h) 370 } 371 372 for _, tt := range serveMuxTests { 373 r := &Request{ 374 Method: tt.method, 375 Host: tt.host, 376 URL: &url.URL{ 377 Path: tt.path, 378 }, 379 } 380 h, pattern := mux.Handler(r) 381 rr := httptest.NewRecorder() 382 h.ServeHTTP(rr, r) 383 if pattern != tt.pattern || rr.Code != tt.code { 384 t.Errorf("%s %s %s = %d, %q, want %d, %q", tt.method, tt.host, tt.path, rr.Code, pattern, tt.code, tt.pattern) 385 } 386 } 387 } 388 389 // Issue 24297 390 func TestServeMuxHandleFuncWithNilHandler(t *testing.T) { 391 setParallel(t) 392 defer func() { 393 if err := recover(); err == nil { 394 t.Error("expected call to mux.HandleFunc to panic") 395 } 396 }() 397 mux := NewServeMux() 398 mux.HandleFunc("/", nil) 399 } 400 401 var serveMuxTests2 = []struct { 402 method string 403 host string 404 url string 405 code int 406 redirOk bool 407 }{ 408 {"GET", "google.com", "/", 404, false}, 409 {"GET", "example.com", "/test/?example.com/test/", 200, false}, 410 {"GET", "example.com", "test/?example.com/test/", 200, true}, 411 } 412 413 // TestServeMuxHandlerRedirects tests that automatic redirects generated by 414 // mux.Handler() shouldn't clear the request's query string. 415 func TestServeMuxHandlerRedirects(t *testing.T) { 416 setParallel(t) 417 mux := NewServeMux() 418 for _, e := range serveMuxRegister { 419 mux.Handle(e.pattern, e.h) 420 } 421 422 for _, tt := range serveMuxTests2 { 423 tries := 1 // expect at most 1 redirection if redirOk is true. 424 turl := tt.url 425 for { 426 u, e := url.Parse(turl) 427 if e != nil { 428 t.Fatal(e) 429 } 430 r := &Request{ 431 Method: tt.method, 432 Host: tt.host, 433 URL: u, 434 } 435 h, _ := mux.Handler(r) 436 rr := httptest.NewRecorder() 437 h.ServeHTTP(rr, r) 438 if rr.Code != 301 { 439 if rr.Code != tt.code { 440 t.Errorf("%s %s %s = %d, want %d", tt.method, tt.host, tt.url, rr.Code, tt.code) 441 } 442 break 443 } 444 if !tt.redirOk { 445 t.Errorf("%s %s %s, unexpected redirect", tt.method, tt.host, tt.url) 446 break 447 } 448 turl = rr.HeaderMap.Get("Location") 449 tries-- 450 } 451 if tries < 0 { 452 t.Errorf("%s %s %s, too many redirects", tt.method, tt.host, tt.url) 453 } 454 } 455 } 456 457 // Tests for https://golang.org/issue/900 458 func TestMuxRedirectLeadingSlashes(t *testing.T) { 459 setParallel(t) 460 paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"} 461 for _, path := range paths { 462 req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n"))) 463 if err != nil { 464 t.Errorf("%s", err) 465 } 466 mux := NewServeMux() 467 resp := httptest.NewRecorder() 468 469 mux.ServeHTTP(resp, req) 470 471 if loc, expected := resp.Header().Get("Location"), "/foo.txt"; loc != expected { 472 t.Errorf("Expected Location header set to %q; got %q", expected, loc) 473 return 474 } 475 476 if code, expected := resp.Code, StatusMovedPermanently; code != expected { 477 t.Errorf("Expected response code of StatusMovedPermanently; got %d", code) 478 return 479 } 480 } 481 } 482 483 // Test that the special cased "/route" redirect 484 // implicitly created by a registered "/route/" 485 // properly sets the query string in the redirect URL. 486 // See Issue 17841. 487 func TestServeWithSlashRedirectKeepsQueryString(t *testing.T) { 488 setParallel(t) 489 defer afterTest(t) 490 491 writeBackQuery := func(w ResponseWriter, r *Request) { 492 fmt.Fprintf(w, "%s", r.URL.RawQuery) 493 } 494 495 mux := NewServeMux() 496 mux.HandleFunc("/testOne", writeBackQuery) 497 mux.HandleFunc("/testTwo/", writeBackQuery) 498 mux.HandleFunc("/testThree", writeBackQuery) 499 mux.HandleFunc("/testThree/", func(w ResponseWriter, r *Request) { 500 fmt.Fprintf(w, "%s:bar", r.URL.RawQuery) 501 }) 502 503 ts := httptest.NewServer(mux) 504 defer ts.Close() 505 506 tests := [...]struct { 507 path string 508 method string 509 want string 510 statusOk bool 511 }{ 512 0: {"/testOne?this=that", "GET", "this=that", true}, 513 1: {"/testTwo?foo=bar", "GET", "foo=bar", true}, 514 2: {"/testTwo?a=1&b=2&a=3", "GET", "a=1&b=2&a=3", true}, 515 3: {"/testTwo?", "GET", "", true}, 516 4: {"/testThree?foo", "GET", "foo", true}, 517 5: {"/testThree/?foo", "GET", "foo:bar", true}, 518 6: {"/testThree?foo", "CONNECT", "foo", true}, 519 7: {"/testThree/?foo", "CONNECT", "foo:bar", true}, 520 521 // canonicalization or not 522 8: {"/testOne/foo/..?foo", "GET", "foo", true}, 523 9: {"/testOne/foo/..?foo", "CONNECT", "404 page not found\n", false}, 524 } 525 526 for i, tt := range tests { 527 req, _ := NewRequest(tt.method, ts.URL+tt.path, nil) 528 res, err := ts.Client().Do(req) 529 if err != nil { 530 continue 531 } 532 slurp, _ := ioutil.ReadAll(res.Body) 533 res.Body.Close() 534 if !tt.statusOk { 535 if got, want := res.StatusCode, 404; got != want { 536 t.Errorf("#%d: Status = %d; want = %d", i, got, want) 537 } 538 } 539 if got, want := string(slurp), tt.want; got != want { 540 t.Errorf("#%d: Body = %q; want = %q", i, got, want) 541 } 542 } 543 } 544 545 func TestServeWithSlashRedirectForHostPatterns(t *testing.T) { 546 setParallel(t) 547 defer afterTest(t) 548 549 mux := NewServeMux() 550 mux.Handle("example.com/pkg/foo/", stringHandler("example.com/pkg/foo/")) 551 mux.Handle("example.com/pkg/bar", stringHandler("example.com/pkg/bar")) 552 mux.Handle("example.com/pkg/bar/", stringHandler("example.com/pkg/bar/")) 553 mux.Handle("example.com:3000/pkg/connect/", stringHandler("example.com:3000/pkg/connect/")) 554 mux.Handle("example.com:9000/", stringHandler("example.com:9000/")) 555 mux.Handle("/pkg/baz/", stringHandler("/pkg/baz/")) 556 557 tests := []struct { 558 method string 559 url string 560 code int 561 loc string 562 want string 563 }{ 564 {"GET", "http://example.com/", 404, "", ""}, 565 {"GET", "http://example.com/pkg/foo", 301, "/pkg/foo/", ""}, 566 {"GET", "http://example.com/pkg/bar", 200, "", "example.com/pkg/bar"}, 567 {"GET", "http://example.com/pkg/bar/", 200, "", "example.com/pkg/bar/"}, 568 {"GET", "http://example.com/pkg/baz", 301, "/pkg/baz/", ""}, 569 {"GET", "http://example.com:3000/pkg/foo", 301, "/pkg/foo/", ""}, 570 {"CONNECT", "http://example.com/", 404, "", ""}, 571 {"CONNECT", "http://example.com:3000/", 404, "", ""}, 572 {"CONNECT", "http://example.com:9000/", 200, "", "example.com:9000/"}, 573 {"CONNECT", "http://example.com/pkg/foo", 301, "/pkg/foo/", ""}, 574 {"CONNECT", "http://example.com:3000/pkg/foo", 404, "", ""}, 575 {"CONNECT", "http://example.com:3000/pkg/baz", 301, "/pkg/baz/", ""}, 576 {"CONNECT", "http://example.com:3000/pkg/connect", 301, "/pkg/connect/", ""}, 577 } 578 579 ts := httptest.NewServer(mux) 580 defer ts.Close() 581 582 for i, tt := range tests { 583 req, _ := NewRequest(tt.method, tt.url, nil) 584 w := httptest.NewRecorder() 585 mux.ServeHTTP(w, req) 586 587 if got, want := w.Code, tt.code; got != want { 588 t.Errorf("#%d: Status = %d; want = %d", i, got, want) 589 } 590 591 if tt.code == 301 { 592 if got, want := w.HeaderMap.Get("Location"), tt.loc; got != want { 593 t.Errorf("#%d: Location = %q; want = %q", i, got, want) 594 } 595 } else { 596 if got, want := w.HeaderMap.Get("Result"), tt.want; got != want { 597 t.Errorf("#%d: Result = %q; want = %q", i, got, want) 598 } 599 } 600 } 601 } 602 603 func TestShouldRedirectConcurrency(t *testing.T) { 604 setParallel(t) 605 defer afterTest(t) 606 607 mux := NewServeMux() 608 ts := httptest.NewServer(mux) 609 defer ts.Close() 610 mux.HandleFunc("/", func(w ResponseWriter, r *Request) {}) 611 } 612 613 func BenchmarkServeMux(b *testing.B) { benchmarkServeMux(b, true) } 614 func BenchmarkServeMux_SkipServe(b *testing.B) { benchmarkServeMux(b, false) } 615 func benchmarkServeMux(b *testing.B, runHandler bool) { 616 type test struct { 617 path string 618 code int 619 req *Request 620 } 621 622 // Build example handlers and requests 623 var tests []test 624 endpoints := []string{"search", "dir", "file", "change", "count", "s"} 625 for _, e := range endpoints { 626 for i := 200; i < 230; i++ { 627 p := fmt.Sprintf("/%s/%d/", e, i) 628 tests = append(tests, test{ 629 path: p, 630 code: i, 631 req: &Request{Method: "GET", Host: "localhost", URL: &url.URL{Path: p}}, 632 }) 633 } 634 } 635 mux := NewServeMux() 636 for _, tt := range tests { 637 mux.Handle(tt.path, serve(tt.code)) 638 } 639 640 rw := httptest.NewRecorder() 641 b.ReportAllocs() 642 b.ResetTimer() 643 for i := 0; i < b.N; i++ { 644 for _, tt := range tests { 645 *rw = httptest.ResponseRecorder{} 646 h, pattern := mux.Handler(tt.req) 647 if runHandler { 648 h.ServeHTTP(rw, tt.req) 649 if pattern != tt.path || rw.Code != tt.code { 650 b.Fatalf("got %d, %q, want %d, %q", rw.Code, pattern, tt.code, tt.path) 651 } 652 } 653 } 654 } 655 } 656 657 func TestServerTimeouts(t *testing.T) { 658 setParallel(t) 659 defer afterTest(t) 660 // Try three times, with increasing timeouts. 661 tries := []time.Duration{250 * time.Millisecond, 500 * time.Millisecond, 1 * time.Second} 662 for i, timeout := range tries { 663 err := testServerTimeouts(timeout) 664 if err == nil { 665 return 666 } 667 t.Logf("failed at %v: %v", timeout, err) 668 if i != len(tries)-1 { 669 t.Logf("retrying at %v ...", tries[i+1]) 670 } 671 } 672 t.Fatal("all attempts failed") 673 } 674 675 func testServerTimeouts(timeout time.Duration) error { 676 reqNum := 0 677 ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) { 678 reqNum++ 679 fmt.Fprintf(res, "req=%d", reqNum) 680 })) 681 ts.Config.ReadTimeout = timeout 682 ts.Config.WriteTimeout = timeout 683 ts.Start() 684 defer ts.Close() 685 686 // Hit the HTTP server successfully. 687 c := ts.Client() 688 r, err := c.Get(ts.URL) 689 if err != nil { 690 return fmt.Errorf("http Get #1: %v", err) 691 } 692 got, err := ioutil.ReadAll(r.Body) 693 expected := "req=1" 694 if string(got) != expected || err != nil { 695 return fmt.Errorf("Unexpected response for request #1; got %q ,%v; expected %q, nil", 696 string(got), err, expected) 697 } 698 699 // Slow client that should timeout. 700 t1 := time.Now() 701 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 702 if err != nil { 703 return fmt.Errorf("Dial: %v", err) 704 } 705 buf := make([]byte, 1) 706 n, err := conn.Read(buf) 707 conn.Close() 708 latency := time.Since(t1) 709 if n != 0 || err != io.EOF { 710 return fmt.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF) 711 } 712 minLatency := timeout / 5 * 4 713 if latency < minLatency { 714 return fmt.Errorf("got EOF after %s, want >= %s", latency, minLatency) 715 } 716 717 // Hit the HTTP server successfully again, verifying that the 718 // previous slow connection didn't run our handler. (that we 719 // get "req=2", not "req=3") 720 r, err = c.Get(ts.URL) 721 if err != nil { 722 return fmt.Errorf("http Get #2: %v", err) 723 } 724 got, err = ioutil.ReadAll(r.Body) 725 r.Body.Close() 726 expected = "req=2" 727 if string(got) != expected || err != nil { 728 return fmt.Errorf("Get #2 got %q, %v, want %q, nil", string(got), err, expected) 729 } 730 731 if !testing.Short() { 732 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 733 if err != nil { 734 return fmt.Errorf("long Dial: %v", err) 735 } 736 defer conn.Close() 737 go io.Copy(ioutil.Discard, conn) 738 for i := 0; i < 5; i++ { 739 _, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")) 740 if err != nil { 741 return fmt.Errorf("on write %d: %v", i, err) 742 } 743 time.Sleep(timeout / 2) 744 } 745 } 746 return nil 747 } 748 749 // Test that the HTTP/2 server handles Server.WriteTimeout (Issue 18437) 750 func TestHTTP2WriteDeadlineExtendedOnNewRequest(t *testing.T) { 751 if testing.Short() { 752 t.Skip("skipping in short mode") 753 } 754 setParallel(t) 755 defer afterTest(t) 756 ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {})) 757 ts.Config.WriteTimeout = 250 * time.Millisecond 758 ts.TLS = &tls.Config{NextProtos: []string{"h2"}} 759 ts.StartTLS() 760 defer ts.Close() 761 762 c := ts.Client() 763 if err := ExportHttp2ConfigureTransport(c.Transport.(*Transport)); err != nil { 764 t.Fatal(err) 765 } 766 767 for i := 1; i <= 3; i++ { 768 req, err := NewRequest("GET", ts.URL, nil) 769 if err != nil { 770 t.Fatal(err) 771 } 772 773 // fail test if no response after 1 second 774 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) 775 defer cancel() 776 req = req.WithContext(ctx) 777 778 r, err := c.Do(req) 779 if ctx.Err() == context.DeadlineExceeded { 780 t.Fatalf("http2 Get #%d response timed out", i) 781 } 782 if err != nil { 783 t.Fatalf("http2 Get #%d: %v", i, err) 784 } 785 r.Body.Close() 786 if r.ProtoMajor != 2 { 787 t.Fatalf("http2 Get expected HTTP/2.0, got %q", r.Proto) 788 } 789 time.Sleep(ts.Config.WriteTimeout / 2) 790 } 791 } 792 793 // tryTimeouts runs testFunc with increasing timeouts. Test passes on first success, 794 // and fails if all timeouts fail. 795 func tryTimeouts(t *testing.T, testFunc func(timeout time.Duration) error) { 796 tries := []time.Duration{250 * time.Millisecond, 500 * time.Millisecond, 1 * time.Second} 797 for i, timeout := range tries { 798 err := testFunc(timeout) 799 if err == nil { 800 return 801 } 802 t.Logf("failed at %v: %v", timeout, err) 803 if i != len(tries)-1 { 804 t.Logf("retrying at %v ...", tries[i+1]) 805 } 806 } 807 t.Fatal("all attempts failed") 808 } 809 810 // Test that the HTTP/2 server RSTs stream on slow write. 811 func TestHTTP2WriteDeadlineEnforcedPerStream(t *testing.T) { 812 if testing.Short() { 813 t.Skip("skipping in short mode") 814 } 815 setParallel(t) 816 defer afterTest(t) 817 tryTimeouts(t, testHTTP2WriteDeadlineEnforcedPerStream) 818 } 819 820 func testHTTP2WriteDeadlineEnforcedPerStream(timeout time.Duration) error { 821 reqNum := 0 822 ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) { 823 reqNum++ 824 if reqNum == 1 { 825 return // first request succeeds 826 } 827 time.Sleep(timeout) // second request times out 828 })) 829 ts.Config.WriteTimeout = timeout / 2 830 ts.TLS = &tls.Config{NextProtos: []string{"h2"}} 831 ts.StartTLS() 832 defer ts.Close() 833 834 c := ts.Client() 835 if err := ExportHttp2ConfigureTransport(c.Transport.(*Transport)); err != nil { 836 return fmt.Errorf("ExportHttp2ConfigureTransport: %v", err) 837 } 838 839 req, err := NewRequest("GET", ts.URL, nil) 840 if err != nil { 841 return fmt.Errorf("NewRequest: %v", err) 842 } 843 r, err := c.Do(req) 844 if err != nil { 845 return fmt.Errorf("http2 Get #1: %v", err) 846 } 847 r.Body.Close() 848 if r.ProtoMajor != 2 { 849 return fmt.Errorf("http2 Get expected HTTP/2.0, got %q", r.Proto) 850 } 851 852 req, err = NewRequest("GET", ts.URL, nil) 853 if err != nil { 854 return fmt.Errorf("NewRequest: %v", err) 855 } 856 r, err = c.Do(req) 857 if err == nil { 858 r.Body.Close() 859 if r.ProtoMajor != 2 { 860 return fmt.Errorf("http2 Get expected HTTP/2.0, got %q", r.Proto) 861 } 862 return fmt.Errorf("http2 Get #2 expected error, got nil") 863 } 864 expected := "stream ID 3; INTERNAL_ERROR" // client IDs are odd, second stream should be 3 865 if !strings.Contains(err.Error(), expected) { 866 return fmt.Errorf("http2 Get #2: expected error to contain %q, got %q", expected, err) 867 } 868 return nil 869 } 870 871 // Test that the HTTP/2 server does not send RST when WriteDeadline not set. 872 func TestHTTP2NoWriteDeadline(t *testing.T) { 873 if testing.Short() { 874 t.Skip("skipping in short mode") 875 } 876 setParallel(t) 877 defer afterTest(t) 878 tryTimeouts(t, testHTTP2NoWriteDeadline) 879 } 880 881 func testHTTP2NoWriteDeadline(timeout time.Duration) error { 882 reqNum := 0 883 ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) { 884 reqNum++ 885 if reqNum == 1 { 886 return // first request succeeds 887 } 888 time.Sleep(timeout) // second request timesout 889 })) 890 ts.TLS = &tls.Config{NextProtos: []string{"h2"}} 891 ts.StartTLS() 892 defer ts.Close() 893 894 c := ts.Client() 895 if err := ExportHttp2ConfigureTransport(c.Transport.(*Transport)); err != nil { 896 return fmt.Errorf("ExportHttp2ConfigureTransport: %v", err) 897 } 898 899 for i := 0; i < 2; i++ { 900 req, err := NewRequest("GET", ts.URL, nil) 901 if err != nil { 902 return fmt.Errorf("NewRequest: %v", err) 903 } 904 r, err := c.Do(req) 905 if err != nil { 906 return fmt.Errorf("http2 Get #%d: %v", i, err) 907 } 908 r.Body.Close() 909 if r.ProtoMajor != 2 { 910 return fmt.Errorf("http2 Get expected HTTP/2.0, got %q", r.Proto) 911 } 912 } 913 return nil 914 } 915 916 // golang.org/issue/4741 -- setting only a write timeout that triggers 917 // shouldn't cause a handler to block forever on reads (next HTTP 918 // request) that will never happen. 919 func TestOnlyWriteTimeout(t *testing.T) { 920 setParallel(t) 921 defer afterTest(t) 922 var ( 923 mu sync.RWMutex 924 conn net.Conn 925 ) 926 var afterTimeoutErrc = make(chan error, 1) 927 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, req *Request) { 928 buf := make([]byte, 512<<10) 929 _, err := w.Write(buf) 930 if err != nil { 931 t.Errorf("handler Write error: %v", err) 932 return 933 } 934 mu.RLock() 935 defer mu.RUnlock() 936 if conn == nil { 937 t.Error("no established connection found") 938 return 939 } 940 conn.SetWriteDeadline(time.Now().Add(-30 * time.Second)) 941 _, err = w.Write(buf) 942 afterTimeoutErrc <- err 943 })) 944 ts.Listener = trackLastConnListener{ts.Listener, &mu, &conn} 945 ts.Start() 946 defer ts.Close() 947 948 c := ts.Client() 949 950 errc := make(chan error) 951 go func() { 952 res, err := c.Get(ts.URL) 953 if err != nil { 954 errc <- err 955 return 956 } 957 _, err = io.Copy(ioutil.Discard, res.Body) 958 res.Body.Close() 959 errc <- err 960 }() 961 select { 962 case err := <-errc: 963 if err == nil { 964 t.Errorf("expected an error from Get request") 965 } 966 case <-time.After(10 * time.Second): 967 t.Fatal("timeout waiting for Get error") 968 } 969 if err := <-afterTimeoutErrc; err == nil { 970 t.Error("expected write error after timeout") 971 } 972 } 973 974 // trackLastConnListener tracks the last net.Conn that was accepted. 975 type trackLastConnListener struct { 976 net.Listener 977 978 mu *sync.RWMutex 979 last *net.Conn // destination 980 } 981 982 func (l trackLastConnListener) Accept() (c net.Conn, err error) { 983 c, err = l.Listener.Accept() 984 if err == nil { 985 l.mu.Lock() 986 *l.last = c 987 l.mu.Unlock() 988 } 989 return 990 } 991 992 // TestIdentityResponse verifies that a handler can unset 993 func TestIdentityResponse(t *testing.T) { 994 setParallel(t) 995 defer afterTest(t) 996 handler := HandlerFunc(func(rw ResponseWriter, req *Request) { 997 rw.Header().Set("Content-Length", "3") 998 rw.Header().Set("Transfer-Encoding", req.FormValue("te")) 999 switch { 1000 case req.FormValue("overwrite") == "1": 1001 _, err := rw.Write([]byte("foo TOO LONG")) 1002 if err != ErrContentLength { 1003 t.Errorf("expected ErrContentLength; got %v", err) 1004 } 1005 case req.FormValue("underwrite") == "1": 1006 rw.Header().Set("Content-Length", "500") 1007 rw.Write([]byte("too short")) 1008 default: 1009 rw.Write([]byte("foo")) 1010 } 1011 }) 1012 1013 ts := httptest.NewServer(handler) 1014 defer ts.Close() 1015 1016 c := ts.Client() 1017 1018 // Note: this relies on the assumption (which is true) that 1019 // Get sends HTTP/1.1 or greater requests. Otherwise the 1020 // server wouldn't have the choice to send back chunked 1021 // responses. 1022 for _, te := range []string{"", "identity"} { 1023 url := ts.URL + "/?te=" + te 1024 res, err := c.Get(url) 1025 if err != nil { 1026 t.Fatalf("error with Get of %s: %v", url, err) 1027 } 1028 if cl, expected := res.ContentLength, int64(3); cl != expected { 1029 t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl) 1030 } 1031 if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected { 1032 t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl) 1033 } 1034 if tl, expected := len(res.TransferEncoding), 0; tl != expected { 1035 t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)", 1036 url, expected, tl, res.TransferEncoding) 1037 } 1038 res.Body.Close() 1039 } 1040 1041 // Verify that ErrContentLength is returned 1042 url := ts.URL + "/?overwrite=1" 1043 res, err := c.Get(url) 1044 if err != nil { 1045 t.Fatalf("error with Get of %s: %v", url, err) 1046 } 1047 res.Body.Close() 1048 1049 // Verify that the connection is closed when the declared Content-Length 1050 // is larger than what the handler wrote. 1051 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 1052 if err != nil { 1053 t.Fatalf("error dialing: %v", err) 1054 } 1055 _, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n")) 1056 if err != nil { 1057 t.Fatalf("error writing: %v", err) 1058 } 1059 1060 // The ReadAll will hang for a failing test, so use a Timer to 1061 // fail explicitly. 1062 goTimeout(t, 2*time.Second, func() { 1063 got, _ := ioutil.ReadAll(conn) 1064 expectedSuffix := "\r\n\r\ntoo short" 1065 if !strings.HasSuffix(string(got), expectedSuffix) { 1066 t.Errorf("Expected output to end with %q; got response body %q", 1067 expectedSuffix, string(got)) 1068 } 1069 }) 1070 } 1071 1072 func testTCPConnectionCloses(t *testing.T, req string, h Handler) { 1073 setParallel(t) 1074 defer afterTest(t) 1075 s := httptest.NewServer(h) 1076 defer s.Close() 1077 1078 conn, err := net.Dial("tcp", s.Listener.Addr().String()) 1079 if err != nil { 1080 t.Fatal("dial error:", err) 1081 } 1082 defer conn.Close() 1083 1084 _, err = fmt.Fprint(conn, req) 1085 if err != nil { 1086 t.Fatal("print error:", err) 1087 } 1088 1089 r := bufio.NewReader(conn) 1090 res, err := ReadResponse(r, &Request{Method: "GET"}) 1091 if err != nil { 1092 t.Fatal("ReadResponse error:", err) 1093 } 1094 1095 didReadAll := make(chan bool, 1) 1096 go func() { 1097 select { 1098 case <-time.After(5 * time.Second): 1099 t.Error("body not closed after 5s") 1100 return 1101 case <-didReadAll: 1102 } 1103 }() 1104 1105 _, err = ioutil.ReadAll(r) 1106 if err != nil { 1107 t.Fatal("read error:", err) 1108 } 1109 didReadAll <- true 1110 1111 if !res.Close { 1112 t.Errorf("Response.Close = false; want true") 1113 } 1114 } 1115 1116 func testTCPConnectionStaysOpen(t *testing.T, req string, handler Handler) { 1117 setParallel(t) 1118 defer afterTest(t) 1119 ts := httptest.NewServer(handler) 1120 defer ts.Close() 1121 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 1122 if err != nil { 1123 t.Fatal(err) 1124 } 1125 defer conn.Close() 1126 br := bufio.NewReader(conn) 1127 for i := 0; i < 2; i++ { 1128 if _, err := io.WriteString(conn, req); err != nil { 1129 t.Fatal(err) 1130 } 1131 res, err := ReadResponse(br, nil) 1132 if err != nil { 1133 t.Fatalf("res %d: %v", i+1, err) 1134 } 1135 if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { 1136 t.Fatalf("res %d body copy: %v", i+1, err) 1137 } 1138 res.Body.Close() 1139 } 1140 } 1141 1142 // TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive. 1143 func TestServeHTTP10Close(t *testing.T) { 1144 testTCPConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 1145 ServeFile(w, r, "testdata/file") 1146 })) 1147 } 1148 1149 // TestClientCanClose verifies that clients can also force a connection to close. 1150 func TestClientCanClose(t *testing.T) { 1151 testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nHost: foo\r\nConnection: close\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 1152 // Nothing. 1153 })) 1154 } 1155 1156 // TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close, 1157 // even for HTTP/1.1 requests. 1158 func TestHandlersCanSetConnectionClose11(t *testing.T) { 1159 testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 1160 w.Header().Set("Connection", "close") 1161 })) 1162 } 1163 1164 func TestHandlersCanSetConnectionClose10(t *testing.T) { 1165 testTCPConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 1166 w.Header().Set("Connection", "close") 1167 })) 1168 } 1169 1170 func TestHTTP2UpgradeClosesConnection(t *testing.T) { 1171 testTCPConnectionCloses(t, "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { 1172 // Nothing. (if not hijacked, the server should close the connection 1173 // afterwards) 1174 })) 1175 } 1176 1177 func send204(w ResponseWriter, r *Request) { w.WriteHeader(204) } 1178 func send304(w ResponseWriter, r *Request) { w.WriteHeader(304) } 1179 1180 // Issue 15647: 204 responses can't have bodies, so HTTP/1.0 keep-alive conns should stay open. 1181 func TestHTTP10KeepAlive204Response(t *testing.T) { 1182 testTCPConnectionStaysOpen(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(send204)) 1183 } 1184 1185 func TestHTTP11KeepAlive204Response(t *testing.T) { 1186 testTCPConnectionStaysOpen(t, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n", HandlerFunc(send204)) 1187 } 1188 1189 func TestHTTP10KeepAlive304Response(t *testing.T) { 1190 testTCPConnectionStaysOpen(t, 1191 "GET / HTTP/1.0\r\nConnection: keep-alive\r\nIf-Modified-Since: Mon, 02 Jan 2006 15:04:05 GMT\r\n\r\n", 1192 HandlerFunc(send304)) 1193 } 1194 1195 // Issue 15703 1196 func TestKeepAliveFinalChunkWithEOF(t *testing.T) { 1197 setParallel(t) 1198 defer afterTest(t) 1199 cst := newClientServerTest(t, false /* h1 */, HandlerFunc(func(w ResponseWriter, r *Request) { 1200 w.(Flusher).Flush() // force chunked encoding 1201 w.Write([]byte("{\"Addr\": \"" + r.RemoteAddr + "\"}")) 1202 })) 1203 defer cst.close() 1204 type data struct { 1205 Addr string 1206 } 1207 var addrs [2]data 1208 for i := range addrs { 1209 res, err := cst.c.Get(cst.ts.URL) 1210 if err != nil { 1211 t.Fatal(err) 1212 } 1213 if err := json.NewDecoder(res.Body).Decode(&addrs[i]); err != nil { 1214 t.Fatal(err) 1215 } 1216 if addrs[i].Addr == "" { 1217 t.Fatal("no address") 1218 } 1219 res.Body.Close() 1220 } 1221 if addrs[0] != addrs[1] { 1222 t.Fatalf("connection not reused") 1223 } 1224 } 1225 1226 func TestSetsRemoteAddr_h1(t *testing.T) { testSetsRemoteAddr(t, h1Mode) } 1227 func TestSetsRemoteAddr_h2(t *testing.T) { testSetsRemoteAddr(t, h2Mode) } 1228 1229 func testSetsRemoteAddr(t *testing.T, h2 bool) { 1230 setParallel(t) 1231 defer afterTest(t) 1232 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 1233 fmt.Fprintf(w, "%s", r.RemoteAddr) 1234 })) 1235 defer cst.close() 1236 1237 res, err := cst.c.Get(cst.ts.URL) 1238 if err != nil { 1239 t.Fatalf("Get error: %v", err) 1240 } 1241 body, err := ioutil.ReadAll(res.Body) 1242 if err != nil { 1243 t.Fatalf("ReadAll error: %v", err) 1244 } 1245 ip := string(body) 1246 if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") { 1247 t.Fatalf("Expected local addr; got %q", ip) 1248 } 1249 } 1250 1251 type blockingRemoteAddrListener struct { 1252 net.Listener 1253 conns chan<- net.Conn 1254 } 1255 1256 func (l *blockingRemoteAddrListener) Accept() (net.Conn, error) { 1257 c, err := l.Listener.Accept() 1258 if err != nil { 1259 return nil, err 1260 } 1261 brac := &blockingRemoteAddrConn{ 1262 Conn: c, 1263 addrs: make(chan net.Addr, 1), 1264 } 1265 l.conns <- brac 1266 return brac, nil 1267 } 1268 1269 type blockingRemoteAddrConn struct { 1270 net.Conn 1271 addrs chan net.Addr 1272 } 1273 1274 func (c *blockingRemoteAddrConn) RemoteAddr() net.Addr { 1275 return <-c.addrs 1276 } 1277 1278 // Issue 12943 1279 func TestServerAllowsBlockingRemoteAddr(t *testing.T) { 1280 defer afterTest(t) 1281 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1282 fmt.Fprintf(w, "RA:%s", r.RemoteAddr) 1283 })) 1284 conns := make(chan net.Conn) 1285 ts.Listener = &blockingRemoteAddrListener{ 1286 Listener: ts.Listener, 1287 conns: conns, 1288 } 1289 ts.Start() 1290 defer ts.Close() 1291 1292 c := ts.Client() 1293 c.Timeout = time.Second 1294 // Force separate connection for each: 1295 c.Transport.(*Transport).DisableKeepAlives = true 1296 1297 fetch := func(num int, response chan<- string) { 1298 resp, err := c.Get(ts.URL) 1299 if err != nil { 1300 t.Errorf("Request %d: %v", num, err) 1301 response <- "" 1302 return 1303 } 1304 defer resp.Body.Close() 1305 body, err := ioutil.ReadAll(resp.Body) 1306 if err != nil { 1307 t.Errorf("Request %d: %v", num, err) 1308 response <- "" 1309 return 1310 } 1311 response <- string(body) 1312 } 1313 1314 // Start a request. The server will block on getting conn.RemoteAddr. 1315 response1c := make(chan string, 1) 1316 go fetch(1, response1c) 1317 1318 // Wait for the server to accept it; grab the connection. 1319 conn1 := <-conns 1320 1321 // Start another request and grab its connection 1322 response2c := make(chan string, 1) 1323 go fetch(2, response2c) 1324 var conn2 net.Conn 1325 1326 select { 1327 case conn2 = <-conns: 1328 case <-time.After(time.Second): 1329 t.Fatal("Second Accept didn't happen") 1330 } 1331 1332 // Send a response on connection 2. 1333 conn2.(*blockingRemoteAddrConn).addrs <- &net.TCPAddr{ 1334 IP: net.ParseIP("12.12.12.12"), Port: 12} 1335 1336 // ... and see it 1337 response2 := <-response2c 1338 if g, e := response2, "RA:12.12.12.12:12"; g != e { 1339 t.Fatalf("response 2 addr = %q; want %q", g, e) 1340 } 1341 1342 // Finish the first response. 1343 conn1.(*blockingRemoteAddrConn).addrs <- &net.TCPAddr{ 1344 IP: net.ParseIP("21.21.21.21"), Port: 21} 1345 1346 // ... and see it 1347 response1 := <-response1c 1348 if g, e := response1, "RA:21.21.21.21:21"; g != e { 1349 t.Fatalf("response 1 addr = %q; want %q", g, e) 1350 } 1351 } 1352 1353 func TestIdentityResponseHeaders(t *testing.T) { 1354 // Not parallel; changes log output. 1355 defer afterTest(t) 1356 log.SetOutput(ioutil.Discard) // is noisy otherwise 1357 defer log.SetOutput(os.Stderr) 1358 1359 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1360 w.Header().Set("Transfer-Encoding", "identity") 1361 w.(Flusher).Flush() 1362 fmt.Fprintf(w, "I am an identity response.") 1363 })) 1364 defer ts.Close() 1365 1366 c := ts.Client() 1367 res, err := c.Get(ts.URL) 1368 if err != nil { 1369 t.Fatalf("Get error: %v", err) 1370 } 1371 defer res.Body.Close() 1372 1373 if g, e := res.TransferEncoding, []string(nil); !reflect.DeepEqual(g, e) { 1374 t.Errorf("expected TransferEncoding of %v; got %v", e, g) 1375 } 1376 if _, haveCL := res.Header["Content-Length"]; haveCL { 1377 t.Errorf("Unexpected Content-Length") 1378 } 1379 if !res.Close { 1380 t.Errorf("expected Connection: close; got %v", res.Close) 1381 } 1382 } 1383 1384 // TestHeadResponses verifies that all MIME type sniffing and Content-Length 1385 // counting of GET requests also happens on HEAD requests. 1386 func TestHeadResponses_h1(t *testing.T) { testHeadResponses(t, h1Mode) } 1387 func TestHeadResponses_h2(t *testing.T) { testHeadResponses(t, h2Mode) } 1388 1389 func testHeadResponses(t *testing.T, h2 bool) { 1390 setParallel(t) 1391 defer afterTest(t) 1392 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 1393 _, err := w.Write([]byte("<html>")) 1394 if err != nil { 1395 t.Errorf("ResponseWriter.Write: %v", err) 1396 } 1397 1398 // Also exercise the ReaderFrom path 1399 _, err = io.Copy(w, strings.NewReader("789a")) 1400 if err != nil { 1401 t.Errorf("Copy(ResponseWriter, ...): %v", err) 1402 } 1403 })) 1404 defer cst.close() 1405 res, err := cst.c.Head(cst.ts.URL) 1406 if err != nil { 1407 t.Error(err) 1408 } 1409 if len(res.TransferEncoding) > 0 { 1410 t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding) 1411 } 1412 if ct := res.Header.Get("Content-Type"); ct != "text/html; charset=utf-8" { 1413 t.Errorf("Content-Type: %q; want text/html; charset=utf-8", ct) 1414 } 1415 if v := res.ContentLength; v != 10 { 1416 t.Errorf("Content-Length: %d; want 10", v) 1417 } 1418 body, err := ioutil.ReadAll(res.Body) 1419 if err != nil { 1420 t.Error(err) 1421 } 1422 if len(body) > 0 { 1423 t.Errorf("got unexpected body %q", string(body)) 1424 } 1425 } 1426 1427 func TestTLSHandshakeTimeout(t *testing.T) { 1428 setParallel(t) 1429 defer afterTest(t) 1430 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 1431 errc := make(chanWriter, 10) // but only expecting 1 1432 ts.Config.ReadTimeout = 250 * time.Millisecond 1433 ts.Config.ErrorLog = log.New(errc, "", 0) 1434 ts.StartTLS() 1435 defer ts.Close() 1436 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 1437 if err != nil { 1438 t.Fatalf("Dial: %v", err) 1439 } 1440 defer conn.Close() 1441 goTimeout(t, 10*time.Second, func() { 1442 var buf [1]byte 1443 n, err := conn.Read(buf[:]) 1444 if err == nil || n != 0 { 1445 t.Errorf("Read = %d, %v; want an error and no bytes", n, err) 1446 } 1447 }) 1448 select { 1449 case v := <-errc: 1450 if !strings.Contains(v, "timeout") && !strings.Contains(v, "TLS handshake") { 1451 t.Errorf("expected a TLS handshake timeout error; got %q", v) 1452 } 1453 case <-time.After(5 * time.Second): 1454 t.Errorf("timeout waiting for logged error") 1455 } 1456 } 1457 1458 func TestTLSServer(t *testing.T) { 1459 setParallel(t) 1460 defer afterTest(t) 1461 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1462 if r.TLS != nil { 1463 w.Header().Set("X-TLS-Set", "true") 1464 if r.TLS.HandshakeComplete { 1465 w.Header().Set("X-TLS-HandshakeComplete", "true") 1466 } 1467 } 1468 })) 1469 ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) 1470 defer ts.Close() 1471 1472 // Connect an idle TCP connection to this server before we run 1473 // our real tests. This idle connection used to block forever 1474 // in the TLS handshake, preventing future connections from 1475 // being accepted. It may prevent future accidental blocking 1476 // in newConn. 1477 idleConn, err := net.Dial("tcp", ts.Listener.Addr().String()) 1478 if err != nil { 1479 t.Fatalf("Dial: %v", err) 1480 } 1481 defer idleConn.Close() 1482 goTimeout(t, 10*time.Second, func() { 1483 if !strings.HasPrefix(ts.URL, "https://") { 1484 t.Errorf("expected test TLS server to start with https://, got %q", ts.URL) 1485 return 1486 } 1487 client := ts.Client() 1488 res, err := client.Get(ts.URL) 1489 if err != nil { 1490 t.Error(err) 1491 return 1492 } 1493 if res == nil { 1494 t.Errorf("got nil Response") 1495 return 1496 } 1497 defer res.Body.Close() 1498 if res.Header.Get("X-TLS-Set") != "true" { 1499 t.Errorf("expected X-TLS-Set response header") 1500 return 1501 } 1502 if res.Header.Get("X-TLS-HandshakeComplete") != "true" { 1503 t.Errorf("expected X-TLS-HandshakeComplete header") 1504 } 1505 }) 1506 } 1507 1508 func TestServeTLS(t *testing.T) { 1509 CondSkipHTTP2(t) 1510 // Not parallel: uses global test hooks. 1511 defer afterTest(t) 1512 defer SetTestHookServerServe(nil) 1513 1514 cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey) 1515 if err != nil { 1516 t.Fatal(err) 1517 } 1518 tlsConf := &tls.Config{ 1519 Certificates: []tls.Certificate{cert}, 1520 } 1521 1522 ln := newLocalListener(t) 1523 defer ln.Close() 1524 addr := ln.Addr().String() 1525 1526 serving := make(chan bool, 1) 1527 SetTestHookServerServe(func(s *Server, ln net.Listener) { 1528 serving <- true 1529 }) 1530 handler := HandlerFunc(func(w ResponseWriter, r *Request) {}) 1531 s := &Server{ 1532 Addr: addr, 1533 TLSConfig: tlsConf, 1534 Handler: handler, 1535 } 1536 errc := make(chan error, 1) 1537 go func() { errc <- s.ServeTLS(ln, "", "") }() 1538 select { 1539 case err := <-errc: 1540 t.Fatalf("ServeTLS: %v", err) 1541 case <-serving: 1542 case <-time.After(5 * time.Second): 1543 t.Fatal("timeout") 1544 } 1545 1546 c, err := tls.Dial("tcp", ln.Addr().String(), &tls.Config{ 1547 InsecureSkipVerify: true, 1548 NextProtos: []string{"h2", "http/1.1"}, 1549 }) 1550 if err != nil { 1551 t.Fatal(err) 1552 } 1553 defer c.Close() 1554 if got, want := c.ConnectionState().NegotiatedProtocol, "h2"; got != want { 1555 t.Errorf("NegotiatedProtocol = %q; want %q", got, want) 1556 } 1557 if got, want := c.ConnectionState().NegotiatedProtocolIsMutual, true; got != want { 1558 t.Errorf("NegotiatedProtocolIsMutual = %v; want %v", got, want) 1559 } 1560 } 1561 1562 // Test that the HTTPS server nicely rejects plaintext HTTP/1.x requests. 1563 func TestTLSServerRejectHTTPRequests(t *testing.T) { 1564 setParallel(t) 1565 defer afterTest(t) 1566 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1567 t.Error("unexpected HTTPS request") 1568 })) 1569 var errBuf bytes.Buffer 1570 ts.Config.ErrorLog = log.New(&errBuf, "", 0) 1571 defer ts.Close() 1572 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 1573 if err != nil { 1574 t.Fatal(err) 1575 } 1576 defer conn.Close() 1577 io.WriteString(conn, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n") 1578 slurp, err := ioutil.ReadAll(conn) 1579 if err != nil { 1580 t.Fatal(err) 1581 } 1582 const wantPrefix = "HTTP/1.0 400 Bad Request\r\n" 1583 if !strings.HasPrefix(string(slurp), wantPrefix) { 1584 t.Errorf("response = %q; wanted prefix %q", slurp, wantPrefix) 1585 } 1586 } 1587 1588 // Issue 15908 1589 func TestAutomaticHTTP2_Serve_NoTLSConfig(t *testing.T) { 1590 testAutomaticHTTP2_Serve(t, nil, true) 1591 } 1592 1593 func TestAutomaticHTTP2_Serve_NonH2TLSConfig(t *testing.T) { 1594 testAutomaticHTTP2_Serve(t, &tls.Config{}, false) 1595 } 1596 1597 func TestAutomaticHTTP2_Serve_H2TLSConfig(t *testing.T) { 1598 testAutomaticHTTP2_Serve(t, &tls.Config{NextProtos: []string{"h2"}}, true) 1599 } 1600 1601 func testAutomaticHTTP2_Serve(t *testing.T, tlsConf *tls.Config, wantH2 bool) { 1602 setParallel(t) 1603 defer afterTest(t) 1604 ln := newLocalListener(t) 1605 ln.Close() // immediately (not a defer!) 1606 var s Server 1607 s.TLSConfig = tlsConf 1608 if err := s.Serve(ln); err == nil { 1609 t.Fatal("expected an error") 1610 } 1611 gotH2 := s.TLSNextProto["h2"] != nil 1612 if gotH2 != wantH2 { 1613 t.Errorf("http2 configured = %v; want %v", gotH2, wantH2) 1614 } 1615 } 1616 1617 func TestAutomaticHTTP2_Serve_WithTLSConfig(t *testing.T) { 1618 setParallel(t) 1619 defer afterTest(t) 1620 ln := newLocalListener(t) 1621 ln.Close() // immediately (not a defer!) 1622 var s Server 1623 // Set the TLSConfig. In reality, this would be the 1624 // *tls.Config given to tls.NewListener. 1625 s.TLSConfig = &tls.Config{ 1626 NextProtos: []string{"h2"}, 1627 } 1628 if err := s.Serve(ln); err == nil { 1629 t.Fatal("expected an error") 1630 } 1631 on := s.TLSNextProto["h2"] != nil 1632 if !on { 1633 t.Errorf("http2 wasn't automatically enabled") 1634 } 1635 } 1636 1637 func TestAutomaticHTTP2_ListenAndServe(t *testing.T) { 1638 cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey) 1639 if err != nil { 1640 t.Fatal(err) 1641 } 1642 testAutomaticHTTP2_ListenAndServe(t, &tls.Config{ 1643 Certificates: []tls.Certificate{cert}, 1644 }) 1645 } 1646 1647 func TestAutomaticHTTP2_ListenAndServe_GetCertificate(t *testing.T) { 1648 cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey) 1649 if err != nil { 1650 t.Fatal(err) 1651 } 1652 testAutomaticHTTP2_ListenAndServe(t, &tls.Config{ 1653 GetCertificate: func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) { 1654 return &cert, nil 1655 }, 1656 }) 1657 } 1658 1659 func testAutomaticHTTP2_ListenAndServe(t *testing.T, tlsConf *tls.Config) { 1660 CondSkipHTTP2(t) 1661 // Not parallel: uses global test hooks. 1662 defer afterTest(t) 1663 defer SetTestHookServerServe(nil) 1664 var ok bool 1665 var s *Server 1666 const maxTries = 5 1667 var ln net.Listener 1668 Try: 1669 for try := 0; try < maxTries; try++ { 1670 ln = newLocalListener(t) 1671 addr := ln.Addr().String() 1672 ln.Close() 1673 t.Logf("Got %v", addr) 1674 lnc := make(chan net.Listener, 1) 1675 SetTestHookServerServe(func(s *Server, ln net.Listener) { 1676 lnc <- ln 1677 }) 1678 s = &Server{ 1679 Addr: addr, 1680 TLSConfig: tlsConf, 1681 } 1682 errc := make(chan error, 1) 1683 go func() { errc <- s.ListenAndServeTLS("", "") }() 1684 select { 1685 case err := <-errc: 1686 t.Logf("On try #%v: %v", try+1, err) 1687 continue 1688 case ln = <-lnc: 1689 ok = true 1690 t.Logf("Listening on %v", ln.Addr().String()) 1691 break Try 1692 } 1693 } 1694 if !ok { 1695 t.Fatalf("Failed to start up after %d tries", maxTries) 1696 } 1697 defer ln.Close() 1698 c, err := tls.Dial("tcp", ln.Addr().String(), &tls.Config{ 1699 InsecureSkipVerify: true, 1700 NextProtos: []string{"h2", "http/1.1"}, 1701 }) 1702 if err != nil { 1703 t.Fatal(err) 1704 } 1705 defer c.Close() 1706 if got, want := c.ConnectionState().NegotiatedProtocol, "h2"; got != want { 1707 t.Errorf("NegotiatedProtocol = %q; want %q", got, want) 1708 } 1709 if got, want := c.ConnectionState().NegotiatedProtocolIsMutual, true; got != want { 1710 t.Errorf("NegotiatedProtocolIsMutual = %v; want %v", got, want) 1711 } 1712 } 1713 1714 type serverExpectTest struct { 1715 contentLength int // of request body 1716 chunked bool 1717 expectation string // e.g. "100-continue" 1718 readBody bool // whether handler should read the body (if false, sends StatusUnauthorized) 1719 expectedResponse string // expected substring in first line of http response 1720 } 1721 1722 func expectTest(contentLength int, expectation string, readBody bool, expectedResponse string) serverExpectTest { 1723 return serverExpectTest{ 1724 contentLength: contentLength, 1725 expectation: expectation, 1726 readBody: readBody, 1727 expectedResponse: expectedResponse, 1728 } 1729 } 1730 1731 var serverExpectTests = []serverExpectTest{ 1732 // Normal 100-continues, case-insensitive. 1733 expectTest(100, "100-continue", true, "100 Continue"), 1734 expectTest(100, "100-cOntInUE", true, "100 Continue"), 1735 1736 // No 100-continue. 1737 expectTest(100, "", true, "200 OK"), 1738 1739 // 100-continue but requesting client to deny us, 1740 // so it never reads the body. 1741 expectTest(100, "100-continue", false, "401 Unauthorized"), 1742 // Likewise without 100-continue: 1743 expectTest(100, "", false, "401 Unauthorized"), 1744 1745 // Non-standard expectations are failures 1746 expectTest(0, "a-pony", false, "417 Expectation Failed"), 1747 1748 // Expect-100 requested but no body (is apparently okay: Issue 7625) 1749 expectTest(0, "100-continue", true, "200 OK"), 1750 // Expect-100 requested but handler doesn't read the body 1751 expectTest(0, "100-continue", false, "401 Unauthorized"), 1752 // Expect-100 continue with no body, but a chunked body. 1753 { 1754 expectation: "100-continue", 1755 readBody: true, 1756 chunked: true, 1757 expectedResponse: "100 Continue", 1758 }, 1759 } 1760 1761 // Tests that the server responds to the "Expect" request header 1762 // correctly. 1763 // http2 test: TestServer_Response_Automatic100Continue 1764 func TestServerExpect(t *testing.T) { 1765 setParallel(t) 1766 defer afterTest(t) 1767 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1768 // Note using r.FormValue("readbody") because for POST 1769 // requests that would read from r.Body, which we only 1770 // conditionally want to do. 1771 if strings.Contains(r.URL.RawQuery, "readbody=true") { 1772 ioutil.ReadAll(r.Body) 1773 w.Write([]byte("Hi")) 1774 } else { 1775 w.WriteHeader(StatusUnauthorized) 1776 } 1777 })) 1778 defer ts.Close() 1779 1780 runTest := func(test serverExpectTest) { 1781 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 1782 if err != nil { 1783 t.Fatalf("Dial: %v", err) 1784 } 1785 defer conn.Close() 1786 1787 // Only send the body immediately if we're acting like an HTTP client 1788 // that doesn't send 100-continue expectations. 1789 writeBody := test.contentLength != 0 && strings.ToLower(test.expectation) != "100-continue" 1790 1791 go func() { 1792 contentLen := fmt.Sprintf("Content-Length: %d", test.contentLength) 1793 if test.chunked { 1794 contentLen = "Transfer-Encoding: chunked" 1795 } 1796 _, err := fmt.Fprintf(conn, "POST /?readbody=%v HTTP/1.1\r\n"+ 1797 "Connection: close\r\n"+ 1798 "%s\r\n"+ 1799 "Expect: %s\r\nHost: foo\r\n\r\n", 1800 test.readBody, contentLen, test.expectation) 1801 if err != nil { 1802 t.Errorf("On test %#v, error writing request headers: %v", test, err) 1803 return 1804 } 1805 if writeBody { 1806 var targ io.WriteCloser = struct { 1807 io.Writer 1808 io.Closer 1809 }{ 1810 conn, 1811 ioutil.NopCloser(nil), 1812 } 1813 if test.chunked { 1814 targ = httputil.NewChunkedWriter(conn) 1815 } 1816 body := strings.Repeat("A", test.contentLength) 1817 _, err = fmt.Fprint(targ, body) 1818 if err == nil { 1819 err = targ.Close() 1820 } 1821 if err != nil { 1822 if !test.readBody { 1823 // Server likely already hung up on us. 1824 // See larger comment below. 1825 t.Logf("On test %#v, acceptable error writing request body: %v", test, err) 1826 return 1827 } 1828 t.Errorf("On test %#v, error writing request body: %v", test, err) 1829 } 1830 } 1831 }() 1832 bufr := bufio.NewReader(conn) 1833 line, err := bufr.ReadString('\n') 1834 if err != nil { 1835 if writeBody && !test.readBody { 1836 // This is an acceptable failure due to a possible TCP race: 1837 // We were still writing data and the server hung up on us. A TCP 1838 // implementation may send a RST if our request body data was known 1839 // to be lost, which may trigger our reads to fail. 1840 // See RFC 1122 page 88. 1841 t.Logf("On test %#v, acceptable error from ReadString: %v", test, err) 1842 return 1843 } 1844 t.Fatalf("On test %#v, ReadString: %v", test, err) 1845 } 1846 if !strings.Contains(line, test.expectedResponse) { 1847 t.Errorf("On test %#v, got first line = %q; want %q", test, line, test.expectedResponse) 1848 } 1849 } 1850 1851 for _, test := range serverExpectTests { 1852 runTest(test) 1853 } 1854 } 1855 1856 // Under a ~256KB (maxPostHandlerReadBytes) threshold, the server 1857 // should consume client request bodies that a handler didn't read. 1858 func TestServerUnreadRequestBodyLittle(t *testing.T) { 1859 setParallel(t) 1860 defer afterTest(t) 1861 conn := new(testConn) 1862 body := strings.Repeat("x", 100<<10) 1863 conn.readBuf.Write([]byte(fmt.Sprintf( 1864 "POST / HTTP/1.1\r\n"+ 1865 "Host: test\r\n"+ 1866 "Content-Length: %d\r\n"+ 1867 "\r\n", len(body)))) 1868 conn.readBuf.Write([]byte(body)) 1869 1870 done := make(chan bool) 1871 1872 readBufLen := func() int { 1873 conn.readMu.Lock() 1874 defer conn.readMu.Unlock() 1875 return conn.readBuf.Len() 1876 } 1877 1878 ls := &oneConnListener{conn} 1879 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 1880 defer close(done) 1881 if bufLen := readBufLen(); bufLen < len(body)/2 { 1882 t.Errorf("on request, read buffer length is %d; expected about 100 KB", bufLen) 1883 } 1884 rw.WriteHeader(200) 1885 rw.(Flusher).Flush() 1886 if g, e := readBufLen(), 0; g != e { 1887 t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e) 1888 } 1889 if c := rw.Header().Get("Connection"); c != "" { 1890 t.Errorf(`Connection header = %q; want ""`, c) 1891 } 1892 })) 1893 <-done 1894 } 1895 1896 // Over a ~256KB (maxPostHandlerReadBytes) threshold, the server 1897 // should ignore client request bodies that a handler didn't read 1898 // and close the connection. 1899 func TestServerUnreadRequestBodyLarge(t *testing.T) { 1900 setParallel(t) 1901 if testing.Short() && testenv.Builder() == "" { 1902 t.Log("skipping in short mode") 1903 } 1904 conn := new(testConn) 1905 body := strings.Repeat("x", 1<<20) 1906 conn.readBuf.Write([]byte(fmt.Sprintf( 1907 "POST / HTTP/1.1\r\n"+ 1908 "Host: test\r\n"+ 1909 "Content-Length: %d\r\n"+ 1910 "\r\n", len(body)))) 1911 conn.readBuf.Write([]byte(body)) 1912 conn.closec = make(chan bool, 1) 1913 1914 ls := &oneConnListener{conn} 1915 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 1916 if conn.readBuf.Len() < len(body)/2 { 1917 t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len()) 1918 } 1919 rw.WriteHeader(200) 1920 rw.(Flusher).Flush() 1921 if conn.readBuf.Len() < len(body)/2 { 1922 t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len()) 1923 } 1924 })) 1925 <-conn.closec 1926 1927 if res := conn.writeBuf.String(); !strings.Contains(res, "Connection: close") { 1928 t.Errorf("Expected a Connection: close header; got response: %s", res) 1929 } 1930 } 1931 1932 type handlerBodyCloseTest struct { 1933 bodySize int 1934 bodyChunked bool 1935 reqConnClose bool 1936 1937 wantEOFSearch bool // should Handler's Body.Close do Reads, looking for EOF? 1938 wantNextReq bool // should it find the next request on the same conn? 1939 } 1940 1941 func (t handlerBodyCloseTest) connectionHeader() string { 1942 if t.reqConnClose { 1943 return "Connection: close\r\n" 1944 } 1945 return "" 1946 } 1947 1948 var handlerBodyCloseTests = [...]handlerBodyCloseTest{ 1949 // Small enough to slurp past to the next request + 1950 // has Content-Length. 1951 0: { 1952 bodySize: 20 << 10, 1953 bodyChunked: false, 1954 reqConnClose: false, 1955 wantEOFSearch: true, 1956 wantNextReq: true, 1957 }, 1958 1959 // Small enough to slurp past to the next request + 1960 // is chunked. 1961 1: { 1962 bodySize: 20 << 10, 1963 bodyChunked: true, 1964 reqConnClose: false, 1965 wantEOFSearch: true, 1966 wantNextReq: true, 1967 }, 1968 1969 // Small enough to slurp past to the next request + 1970 // has Content-Length + 1971 // declares Connection: close (so pointless to read more). 1972 2: { 1973 bodySize: 20 << 10, 1974 bodyChunked: false, 1975 reqConnClose: true, 1976 wantEOFSearch: false, 1977 wantNextReq: false, 1978 }, 1979 1980 // Small enough to slurp past to the next request + 1981 // declares Connection: close, 1982 // but chunked, so it might have trailers. 1983 // TODO: maybe skip this search if no trailers were declared 1984 // in the headers. 1985 3: { 1986 bodySize: 20 << 10, 1987 bodyChunked: true, 1988 reqConnClose: true, 1989 wantEOFSearch: true, 1990 wantNextReq: false, 1991 }, 1992 1993 // Big with Content-Length, so give up immediately if we know it's too big. 1994 4: { 1995 bodySize: 1 << 20, 1996 bodyChunked: false, // has a Content-Length 1997 reqConnClose: false, 1998 wantEOFSearch: false, 1999 wantNextReq: false, 2000 }, 2001 2002 // Big chunked, so read a bit before giving up. 2003 5: { 2004 bodySize: 1 << 20, 2005 bodyChunked: true, 2006 reqConnClose: false, 2007 wantEOFSearch: true, 2008 wantNextReq: false, 2009 }, 2010 2011 // Big with Connection: close, but chunked, so search for trailers. 2012 // TODO: maybe skip this search if no trailers were declared 2013 // in the headers. 2014 6: { 2015 bodySize: 1 << 20, 2016 bodyChunked: true, 2017 reqConnClose: true, 2018 wantEOFSearch: true, 2019 wantNextReq: false, 2020 }, 2021 2022 // Big with Connection: close, so don't do any reads on Close. 2023 // With Content-Length. 2024 7: { 2025 bodySize: 1 << 20, 2026 bodyChunked: false, 2027 reqConnClose: true, 2028 wantEOFSearch: false, 2029 wantNextReq: false, 2030 }, 2031 } 2032 2033 func TestHandlerBodyClose(t *testing.T) { 2034 setParallel(t) 2035 if testing.Short() && testenv.Builder() == "" { 2036 t.Skip("skipping in -short mode") 2037 } 2038 for i, tt := range handlerBodyCloseTests { 2039 testHandlerBodyClose(t, i, tt) 2040 } 2041 } 2042 2043 func testHandlerBodyClose(t *testing.T, i int, tt handlerBodyCloseTest) { 2044 conn := new(testConn) 2045 body := strings.Repeat("x", tt.bodySize) 2046 if tt.bodyChunked { 2047 conn.readBuf.WriteString("POST / HTTP/1.1\r\n" + 2048 "Host: test\r\n" + 2049 tt.connectionHeader() + 2050 "Transfer-Encoding: chunked\r\n" + 2051 "\r\n") 2052 cw := internal.NewChunkedWriter(&conn.readBuf) 2053 io.WriteString(cw, body) 2054 cw.Close() 2055 conn.readBuf.WriteString("\r\n") 2056 } else { 2057 conn.readBuf.Write([]byte(fmt.Sprintf( 2058 "POST / HTTP/1.1\r\n"+ 2059 "Host: test\r\n"+ 2060 tt.connectionHeader()+ 2061 "Content-Length: %d\r\n"+ 2062 "\r\n", len(body)))) 2063 conn.readBuf.Write([]byte(body)) 2064 } 2065 if !tt.reqConnClose { 2066 conn.readBuf.WriteString("GET / HTTP/1.1\r\nHost: test\r\n\r\n") 2067 } 2068 conn.closec = make(chan bool, 1) 2069 2070 readBufLen := func() int { 2071 conn.readMu.Lock() 2072 defer conn.readMu.Unlock() 2073 return conn.readBuf.Len() 2074 } 2075 2076 ls := &oneConnListener{conn} 2077 var numReqs int 2078 var size0, size1 int 2079 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 2080 numReqs++ 2081 if numReqs == 1 { 2082 size0 = readBufLen() 2083 req.Body.Close() 2084 size1 = readBufLen() 2085 } 2086 })) 2087 <-conn.closec 2088 if numReqs < 1 || numReqs > 2 { 2089 t.Fatalf("%d. bug in test. unexpected number of requests = %d", i, numReqs) 2090 } 2091 didSearch := size0 != size1 2092 if didSearch != tt.wantEOFSearch { 2093 t.Errorf("%d. did EOF search = %v; want %v (size went from %d to %d)", i, didSearch, !didSearch, size0, size1) 2094 } 2095 if tt.wantNextReq && numReqs != 2 { 2096 t.Errorf("%d. numReq = %d; want 2", i, numReqs) 2097 } 2098 } 2099 2100 // testHandlerBodyConsumer represents a function injected into a test handler to 2101 // vary work done on a request Body. 2102 type testHandlerBodyConsumer struct { 2103 name string 2104 f func(io.ReadCloser) 2105 } 2106 2107 var testHandlerBodyConsumers = []testHandlerBodyConsumer{ 2108 {"nil", func(io.ReadCloser) {}}, 2109 {"close", func(r io.ReadCloser) { r.Close() }}, 2110 {"discard", func(r io.ReadCloser) { io.Copy(ioutil.Discard, r) }}, 2111 } 2112 2113 func TestRequestBodyReadErrorClosesConnection(t *testing.T) { 2114 setParallel(t) 2115 defer afterTest(t) 2116 for _, handler := range testHandlerBodyConsumers { 2117 conn := new(testConn) 2118 conn.readBuf.WriteString("POST /public HTTP/1.1\r\n" + 2119 "Host: test\r\n" + 2120 "Transfer-Encoding: chunked\r\n" + 2121 "\r\n" + 2122 "hax\r\n" + // Invalid chunked encoding 2123 "GET /secret HTTP/1.1\r\n" + 2124 "Host: test\r\n" + 2125 "\r\n") 2126 2127 conn.closec = make(chan bool, 1) 2128 ls := &oneConnListener{conn} 2129 var numReqs int 2130 go Serve(ls, HandlerFunc(func(_ ResponseWriter, req *Request) { 2131 numReqs++ 2132 if strings.Contains(req.URL.Path, "secret") { 2133 t.Error("Request for /secret encountered, should not have happened.") 2134 } 2135 handler.f(req.Body) 2136 })) 2137 <-conn.closec 2138 if numReqs != 1 { 2139 t.Errorf("Handler %v: got %d reqs; want 1", handler.name, numReqs) 2140 } 2141 } 2142 } 2143 2144 func TestInvalidTrailerClosesConnection(t *testing.T) { 2145 setParallel(t) 2146 defer afterTest(t) 2147 for _, handler := range testHandlerBodyConsumers { 2148 conn := new(testConn) 2149 conn.readBuf.WriteString("POST /public HTTP/1.1\r\n" + 2150 "Host: test\r\n" + 2151 "Trailer: hack\r\n" + 2152 "Transfer-Encoding: chunked\r\n" + 2153 "\r\n" + 2154 "3\r\n" + 2155 "hax\r\n" + 2156 "0\r\n" + 2157 "I'm not a valid trailer\r\n" + 2158 "GET /secret HTTP/1.1\r\n" + 2159 "Host: test\r\n" + 2160 "\r\n") 2161 2162 conn.closec = make(chan bool, 1) 2163 ln := &oneConnListener{conn} 2164 var numReqs int 2165 go Serve(ln, HandlerFunc(func(_ ResponseWriter, req *Request) { 2166 numReqs++ 2167 if strings.Contains(req.URL.Path, "secret") { 2168 t.Errorf("Handler %s, Request for /secret encountered, should not have happened.", handler.name) 2169 } 2170 handler.f(req.Body) 2171 })) 2172 <-conn.closec 2173 if numReqs != 1 { 2174 t.Errorf("Handler %s: got %d reqs; want 1", handler.name, numReqs) 2175 } 2176 } 2177 } 2178 2179 // slowTestConn is a net.Conn that provides a means to simulate parts of a 2180 // request being received piecemeal. Deadlines can be set and enforced in both 2181 // Read and Write. 2182 type slowTestConn struct { 2183 // over multiple calls to Read, time.Durations are slept, strings are read. 2184 script []interface{} 2185 closec chan bool 2186 2187 mu sync.Mutex // guards rd/wd 2188 rd, wd time.Time // read, write deadline 2189 noopConn 2190 } 2191 2192 func (c *slowTestConn) SetDeadline(t time.Time) error { 2193 c.SetReadDeadline(t) 2194 c.SetWriteDeadline(t) 2195 return nil 2196 } 2197 2198 func (c *slowTestConn) SetReadDeadline(t time.Time) error { 2199 c.mu.Lock() 2200 defer c.mu.Unlock() 2201 c.rd = t 2202 return nil 2203 } 2204 2205 func (c *slowTestConn) SetWriteDeadline(t time.Time) error { 2206 c.mu.Lock() 2207 defer c.mu.Unlock() 2208 c.wd = t 2209 return nil 2210 } 2211 2212 func (c *slowTestConn) Read(b []byte) (n int, err error) { 2213 c.mu.Lock() 2214 defer c.mu.Unlock() 2215 restart: 2216 if !c.rd.IsZero() && time.Now().After(c.rd) { 2217 return 0, syscall.ETIMEDOUT 2218 } 2219 if len(c.script) == 0 { 2220 return 0, io.EOF 2221 } 2222 2223 switch cue := c.script[0].(type) { 2224 case time.Duration: 2225 if !c.rd.IsZero() { 2226 // If the deadline falls in the middle of our sleep window, deduct 2227 // part of the sleep, then return a timeout. 2228 if remaining := time.Until(c.rd); remaining < cue { 2229 c.script[0] = cue - remaining 2230 time.Sleep(remaining) 2231 return 0, syscall.ETIMEDOUT 2232 } 2233 } 2234 c.script = c.script[1:] 2235 time.Sleep(cue) 2236 goto restart 2237 2238 case string: 2239 n = copy(b, cue) 2240 // If cue is too big for the buffer, leave the end for the next Read. 2241 if len(cue) > n { 2242 c.script[0] = cue[n:] 2243 } else { 2244 c.script = c.script[1:] 2245 } 2246 2247 default: 2248 panic("unknown cue in slowTestConn script") 2249 } 2250 2251 return 2252 } 2253 2254 func (c *slowTestConn) Close() error { 2255 select { 2256 case c.closec <- true: 2257 default: 2258 } 2259 return nil 2260 } 2261 2262 func (c *slowTestConn) Write(b []byte) (int, error) { 2263 if !c.wd.IsZero() && time.Now().After(c.wd) { 2264 return 0, syscall.ETIMEDOUT 2265 } 2266 return len(b), nil 2267 } 2268 2269 func TestRequestBodyTimeoutClosesConnection(t *testing.T) { 2270 if testing.Short() { 2271 t.Skip("skipping in -short mode") 2272 } 2273 defer afterTest(t) 2274 for _, handler := range testHandlerBodyConsumers { 2275 conn := &slowTestConn{ 2276 script: []interface{}{ 2277 "POST /public HTTP/1.1\r\n" + 2278 "Host: test\r\n" + 2279 "Content-Length: 10000\r\n" + 2280 "\r\n", 2281 "foo bar baz", 2282 600 * time.Millisecond, // Request deadline should hit here 2283 "GET /secret HTTP/1.1\r\n" + 2284 "Host: test\r\n" + 2285 "\r\n", 2286 }, 2287 closec: make(chan bool, 1), 2288 } 2289 ls := &oneConnListener{conn} 2290 2291 var numReqs int 2292 s := Server{ 2293 Handler: HandlerFunc(func(_ ResponseWriter, req *Request) { 2294 numReqs++ 2295 if strings.Contains(req.URL.Path, "secret") { 2296 t.Error("Request for /secret encountered, should not have happened.") 2297 } 2298 handler.f(req.Body) 2299 }), 2300 ReadTimeout: 400 * time.Millisecond, 2301 } 2302 go s.Serve(ls) 2303 <-conn.closec 2304 2305 if numReqs != 1 { 2306 t.Errorf("Handler %v: got %d reqs; want 1", handler.name, numReqs) 2307 } 2308 } 2309 } 2310 2311 func TestTimeoutHandler_h1(t *testing.T) { testTimeoutHandler(t, h1Mode) } 2312 func TestTimeoutHandler_h2(t *testing.T) { testTimeoutHandler(t, h2Mode) } 2313 func testTimeoutHandler(t *testing.T, h2 bool) { 2314 setParallel(t) 2315 defer afterTest(t) 2316 sendHi := make(chan bool, 1) 2317 writeErrors := make(chan error, 1) 2318 sayHi := HandlerFunc(func(w ResponseWriter, r *Request) { 2319 <-sendHi 2320 _, werr := w.Write([]byte("hi")) 2321 writeErrors <- werr 2322 }) 2323 timeout := make(chan time.Time, 1) // write to this to force timeouts 2324 cst := newClientServerTest(t, h2, NewTestTimeoutHandler(sayHi, timeout)) 2325 defer cst.close() 2326 2327 // Succeed without timing out: 2328 sendHi <- true 2329 res, err := cst.c.Get(cst.ts.URL) 2330 if err != nil { 2331 t.Error(err) 2332 } 2333 if g, e := res.StatusCode, StatusOK; g != e { 2334 t.Errorf("got res.StatusCode %d; expected %d", g, e) 2335 } 2336 body, _ := ioutil.ReadAll(res.Body) 2337 if g, e := string(body), "hi"; g != e { 2338 t.Errorf("got body %q; expected %q", g, e) 2339 } 2340 if g := <-writeErrors; g != nil { 2341 t.Errorf("got unexpected Write error on first request: %v", g) 2342 } 2343 2344 // Times out: 2345 timeout <- time.Time{} 2346 res, err = cst.c.Get(cst.ts.URL) 2347 if err != nil { 2348 t.Error(err) 2349 } 2350 if g, e := res.StatusCode, StatusServiceUnavailable; g != e { 2351 t.Errorf("got res.StatusCode %d; expected %d", g, e) 2352 } 2353 body, _ = ioutil.ReadAll(res.Body) 2354 if !strings.Contains(string(body), "<title>Timeout</title>") { 2355 t.Errorf("expected timeout body; got %q", string(body)) 2356 } 2357 if g, w := res.Header.Get("Content-Type"), "text/html; charset=utf-8"; g != w { 2358 t.Errorf("response content-type = %q; want %q", g, w) 2359 } 2360 2361 // Now make the previously-timed out handler speak again, 2362 // which verifies the panic is handled: 2363 sendHi <- true 2364 if g, e := <-writeErrors, ErrHandlerTimeout; g != e { 2365 t.Errorf("expected Write error of %v; got %v", e, g) 2366 } 2367 } 2368 2369 // See issues 8209 and 8414. 2370 func TestTimeoutHandlerRace(t *testing.T) { 2371 setParallel(t) 2372 defer afterTest(t) 2373 2374 delayHi := HandlerFunc(func(w ResponseWriter, r *Request) { 2375 ms, _ := strconv.Atoi(r.URL.Path[1:]) 2376 if ms == 0 { 2377 ms = 1 2378 } 2379 for i := 0; i < ms; i++ { 2380 w.Write([]byte("hi")) 2381 time.Sleep(time.Millisecond) 2382 } 2383 }) 2384 2385 ts := httptest.NewServer(TimeoutHandler(delayHi, 20*time.Millisecond, "")) 2386 defer ts.Close() 2387 2388 c := ts.Client() 2389 2390 var wg sync.WaitGroup 2391 gate := make(chan bool, 10) 2392 n := 50 2393 if testing.Short() { 2394 n = 10 2395 gate = make(chan bool, 3) 2396 } 2397 for i := 0; i < n; i++ { 2398 gate <- true 2399 wg.Add(1) 2400 go func() { 2401 defer wg.Done() 2402 defer func() { <-gate }() 2403 res, err := c.Get(fmt.Sprintf("%s/%d", ts.URL, rand.Intn(50))) 2404 if err == nil { 2405 io.Copy(ioutil.Discard, res.Body) 2406 res.Body.Close() 2407 } 2408 }() 2409 } 2410 wg.Wait() 2411 } 2412 2413 // See issues 8209 and 8414. 2414 // Both issues involved panics in the implementation of TimeoutHandler. 2415 func TestTimeoutHandlerRaceHeader(t *testing.T) { 2416 setParallel(t) 2417 defer afterTest(t) 2418 2419 delay204 := HandlerFunc(func(w ResponseWriter, r *Request) { 2420 w.WriteHeader(204) 2421 }) 2422 2423 ts := httptest.NewServer(TimeoutHandler(delay204, time.Nanosecond, "")) 2424 defer ts.Close() 2425 2426 var wg sync.WaitGroup 2427 gate := make(chan bool, 50) 2428 n := 500 2429 if testing.Short() { 2430 n = 10 2431 } 2432 2433 c := ts.Client() 2434 for i := 0; i < n; i++ { 2435 gate <- true 2436 wg.Add(1) 2437 go func() { 2438 defer wg.Done() 2439 defer func() { <-gate }() 2440 res, err := c.Get(ts.URL) 2441 if err != nil { 2442 // We see ECONNRESET from the connection occasionally, 2443 // and that's OK: this test is checking that the server does not panic. 2444 t.Log(err) 2445 return 2446 } 2447 defer res.Body.Close() 2448 io.Copy(ioutil.Discard, res.Body) 2449 }() 2450 } 2451 wg.Wait() 2452 } 2453 2454 // Issue 9162 2455 func TestTimeoutHandlerRaceHeaderTimeout(t *testing.T) { 2456 setParallel(t) 2457 defer afterTest(t) 2458 sendHi := make(chan bool, 1) 2459 writeErrors := make(chan error, 1) 2460 sayHi := HandlerFunc(func(w ResponseWriter, r *Request) { 2461 w.Header().Set("Content-Type", "text/plain") 2462 <-sendHi 2463 _, werr := w.Write([]byte("hi")) 2464 writeErrors <- werr 2465 }) 2466 timeout := make(chan time.Time, 1) // write to this to force timeouts 2467 cst := newClientServerTest(t, h1Mode, NewTestTimeoutHandler(sayHi, timeout)) 2468 defer cst.close() 2469 2470 // Succeed without timing out: 2471 sendHi <- true 2472 res, err := cst.c.Get(cst.ts.URL) 2473 if err != nil { 2474 t.Error(err) 2475 } 2476 if g, e := res.StatusCode, StatusOK; g != e { 2477 t.Errorf("got res.StatusCode %d; expected %d", g, e) 2478 } 2479 body, _ := ioutil.ReadAll(res.Body) 2480 if g, e := string(body), "hi"; g != e { 2481 t.Errorf("got body %q; expected %q", g, e) 2482 } 2483 if g := <-writeErrors; g != nil { 2484 t.Errorf("got unexpected Write error on first request: %v", g) 2485 } 2486 2487 // Times out: 2488 timeout <- time.Time{} 2489 res, err = cst.c.Get(cst.ts.URL) 2490 if err != nil { 2491 t.Error(err) 2492 } 2493 if g, e := res.StatusCode, StatusServiceUnavailable; g != e { 2494 t.Errorf("got res.StatusCode %d; expected %d", g, e) 2495 } 2496 body, _ = ioutil.ReadAll(res.Body) 2497 if !strings.Contains(string(body), "<title>Timeout</title>") { 2498 t.Errorf("expected timeout body; got %q", string(body)) 2499 } 2500 2501 // Now make the previously-timed out handler speak again, 2502 // which verifies the panic is handled: 2503 sendHi <- true 2504 if g, e := <-writeErrors, ErrHandlerTimeout; g != e { 2505 t.Errorf("expected Write error of %v; got %v", e, g) 2506 } 2507 } 2508 2509 // Issue 14568. 2510 func TestTimeoutHandlerStartTimerWhenServing(t *testing.T) { 2511 if testing.Short() { 2512 t.Skip("skipping sleeping test in -short mode") 2513 } 2514 defer afterTest(t) 2515 var handler HandlerFunc = func(w ResponseWriter, _ *Request) { 2516 w.WriteHeader(StatusNoContent) 2517 } 2518 timeout := 300 * time.Millisecond 2519 ts := httptest.NewServer(TimeoutHandler(handler, timeout, "")) 2520 defer ts.Close() 2521 2522 c := ts.Client() 2523 2524 // Issue was caused by the timeout handler starting the timer when 2525 // was created, not when the request. So wait for more than the timeout 2526 // to ensure that's not the case. 2527 time.Sleep(2 * timeout) 2528 res, err := c.Get(ts.URL) 2529 if err != nil { 2530 t.Fatal(err) 2531 } 2532 defer res.Body.Close() 2533 if res.StatusCode != StatusNoContent { 2534 t.Errorf("got res.StatusCode %d, want %v", res.StatusCode, StatusNoContent) 2535 } 2536 } 2537 2538 // https://golang.org/issue/15948 2539 func TestTimeoutHandlerEmptyResponse(t *testing.T) { 2540 setParallel(t) 2541 defer afterTest(t) 2542 var handler HandlerFunc = func(w ResponseWriter, _ *Request) { 2543 // No response. 2544 } 2545 timeout := 300 * time.Millisecond 2546 ts := httptest.NewServer(TimeoutHandler(handler, timeout, "")) 2547 defer ts.Close() 2548 2549 c := ts.Client() 2550 2551 res, err := c.Get(ts.URL) 2552 if err != nil { 2553 t.Fatal(err) 2554 } 2555 defer res.Body.Close() 2556 if res.StatusCode != StatusOK { 2557 t.Errorf("got res.StatusCode %d, want %v", res.StatusCode, StatusOK) 2558 } 2559 } 2560 2561 // https://golang.org/issues/22084 2562 func TestTimeoutHandlerPanicRecovery(t *testing.T) { 2563 wrapper := func(h Handler) Handler { 2564 return TimeoutHandler(h, time.Second, "") 2565 } 2566 testHandlerPanic(t, false, false, wrapper, "intentional death for testing") 2567 } 2568 2569 func TestRedirectBadPath(t *testing.T) { 2570 // This used to crash. It's not valid input (bad path), but it 2571 // shouldn't crash. 2572 rr := httptest.NewRecorder() 2573 req := &Request{ 2574 Method: "GET", 2575 URL: &url.URL{ 2576 Scheme: "http", 2577 Path: "not-empty-but-no-leading-slash", // bogus 2578 }, 2579 } 2580 Redirect(rr, req, "", 304) 2581 if rr.Code != 304 { 2582 t.Errorf("Code = %d; want 304", rr.Code) 2583 } 2584 } 2585 2586 // Test different URL formats and schemes 2587 func TestRedirect(t *testing.T) { 2588 req, _ := NewRequest("GET", "http://example.com/qux/", nil) 2589 2590 var tests = []struct { 2591 in string 2592 want string 2593 }{ 2594 // normal http 2595 {"http://foobar.com/baz", "http://foobar.com/baz"}, 2596 // normal https 2597 {"https://foobar.com/baz", "https://foobar.com/baz"}, 2598 // custom scheme 2599 {"test://foobar.com/baz", "test://foobar.com/baz"}, 2600 // schemeless 2601 {"//foobar.com/baz", "//foobar.com/baz"}, 2602 // relative to the root 2603 {"/foobar.com/baz", "/foobar.com/baz"}, 2604 // relative to the current path 2605 {"foobar.com/baz", "/qux/foobar.com/baz"}, 2606 // relative to the current path (+ going upwards) 2607 {"../quux/foobar.com/baz", "/quux/foobar.com/baz"}, 2608 // incorrect number of slashes 2609 {"///foobar.com/baz", "/foobar.com/baz"}, 2610 2611 // Verifies we don't path.Clean() on the wrong parts in redirects: 2612 {"/foo?next=http://bar.com/", "/foo?next=http://bar.com/"}, 2613 {"http://localhost:8080/_ah/login?continue=http://localhost:8080/", 2614 "http://localhost:8080/_ah/login?continue=http://localhost:8080/"}, 2615 2616 {"/фубар", "/%d1%84%d1%83%d0%b1%d0%b0%d1%80"}, 2617 {"http://foo.com/фубар", "http://foo.com/%d1%84%d1%83%d0%b1%d0%b0%d1%80"}, 2618 } 2619 2620 for _, tt := range tests { 2621 rec := httptest.NewRecorder() 2622 Redirect(rec, req, tt.in, 302) 2623 if got, want := rec.Code, 302; got != want { 2624 t.Errorf("Redirect(%q) generated status code %v; want %v", tt.in, got, want) 2625 } 2626 if got := rec.Header().Get("Location"); got != tt.want { 2627 t.Errorf("Redirect(%q) generated Location header %q; want %q", tt.in, got, tt.want) 2628 } 2629 } 2630 } 2631 2632 // Test that Redirect sets Content-Type header for GET and HEAD requests 2633 // and writes a short HTML body, unless the request already has a Content-Type header. 2634 func TestRedirectContentTypeAndBody(t *testing.T) { 2635 type ctHeader struct { 2636 Values []string 2637 } 2638 2639 var tests = []struct { 2640 method string 2641 ct *ctHeader // Optional Content-Type header to set. 2642 wantCT string 2643 wantBody string 2644 }{ 2645 {MethodGet, nil, "text/html; charset=utf-8", "<a href=\"/foo\">Found</a>.\n\n"}, 2646 {MethodHead, nil, "text/html; charset=utf-8", ""}, 2647 {MethodPost, nil, "", ""}, 2648 {MethodDelete, nil, "", ""}, 2649 {"foo", nil, "", ""}, 2650 {MethodGet, &ctHeader{[]string{"application/test"}}, "application/test", ""}, 2651 {MethodGet, &ctHeader{[]string{}}, "", ""}, 2652 {MethodGet, &ctHeader{nil}, "", ""}, 2653 } 2654 for _, tt := range tests { 2655 req := httptest.NewRequest(tt.method, "http://example.com/qux/", nil) 2656 rec := httptest.NewRecorder() 2657 if tt.ct != nil { 2658 rec.Header()["Content-Type"] = tt.ct.Values 2659 } 2660 Redirect(rec, req, "/foo", 302) 2661 if got, want := rec.Code, 302; got != want { 2662 t.Errorf("Redirect(%q, %#v) generated status code %v; want %v", tt.method, tt.ct, got, want) 2663 } 2664 if got, want := rec.Header().Get("Content-Type"), tt.wantCT; got != want { 2665 t.Errorf("Redirect(%q, %#v) generated Content-Type header %q; want %q", tt.method, tt.ct, got, want) 2666 } 2667 resp := rec.Result() 2668 body, err := ioutil.ReadAll(resp.Body) 2669 if err != nil { 2670 t.Fatal(err) 2671 } 2672 if got, want := string(body), tt.wantBody; got != want { 2673 t.Errorf("Redirect(%q, %#v) generated Body %q; want %q", tt.method, tt.ct, got, want) 2674 } 2675 } 2676 } 2677 2678 // TestZeroLengthPostAndResponse exercises an optimization done by the Transport: 2679 // when there is no body (either because the method doesn't permit a body, or an 2680 // explicit Content-Length of zero is present), then the transport can re-use the 2681 // connection immediately. But when it re-uses the connection, it typically closes 2682 // the previous request's body, which is not optimal for zero-lengthed bodies, 2683 // as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF. 2684 func TestZeroLengthPostAndResponse_h1(t *testing.T) { 2685 testZeroLengthPostAndResponse(t, h1Mode) 2686 } 2687 func TestZeroLengthPostAndResponse_h2(t *testing.T) { 2688 testZeroLengthPostAndResponse(t, h2Mode) 2689 } 2690 2691 func testZeroLengthPostAndResponse(t *testing.T, h2 bool) { 2692 setParallel(t) 2693 defer afterTest(t) 2694 cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, r *Request) { 2695 all, err := ioutil.ReadAll(r.Body) 2696 if err != nil { 2697 t.Fatalf("handler ReadAll: %v", err) 2698 } 2699 if len(all) != 0 { 2700 t.Errorf("handler got %d bytes; expected 0", len(all)) 2701 } 2702 rw.Header().Set("Content-Length", "0") 2703 })) 2704 defer cst.close() 2705 2706 req, err := NewRequest("POST", cst.ts.URL, strings.NewReader("")) 2707 if err != nil { 2708 t.Fatal(err) 2709 } 2710 req.ContentLength = 0 2711 2712 var resp [5]*Response 2713 for i := range resp { 2714 resp[i], err = cst.c.Do(req) 2715 if err != nil { 2716 t.Fatalf("client post #%d: %v", i, err) 2717 } 2718 } 2719 2720 for i := range resp { 2721 all, err := ioutil.ReadAll(resp[i].Body) 2722 if err != nil { 2723 t.Fatalf("req #%d: client ReadAll: %v", i, err) 2724 } 2725 if len(all) != 0 { 2726 t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all)) 2727 } 2728 } 2729 } 2730 2731 func TestHandlerPanicNil_h1(t *testing.T) { testHandlerPanic(t, false, h1Mode, nil, nil) } 2732 func TestHandlerPanicNil_h2(t *testing.T) { testHandlerPanic(t, false, h2Mode, nil, nil) } 2733 2734 func TestHandlerPanic_h1(t *testing.T) { 2735 testHandlerPanic(t, false, h1Mode, nil, "intentional death for testing") 2736 } 2737 func TestHandlerPanic_h2(t *testing.T) { 2738 testHandlerPanic(t, false, h2Mode, nil, "intentional death for testing") 2739 } 2740 2741 func TestHandlerPanicWithHijack(t *testing.T) { 2742 // Only testing HTTP/1, and our http2 server doesn't support hijacking. 2743 testHandlerPanic(t, true, h1Mode, nil, "intentional death for testing") 2744 } 2745 2746 func testHandlerPanic(t *testing.T, withHijack, h2 bool, wrapper func(Handler) Handler, panicValue interface{}) { 2747 defer afterTest(t) 2748 // Unlike the other tests that set the log output to ioutil.Discard 2749 // to quiet the output, this test uses a pipe. The pipe serves three 2750 // purposes: 2751 // 2752 // 1) The log.Print from the http server (generated by the caught 2753 // panic) will go to the pipe instead of stderr, making the 2754 // output quiet. 2755 // 2756 // 2) We read from the pipe to verify that the handler 2757 // actually caught the panic and logged something. 2758 // 2759 // 3) The blocking Read call prevents this TestHandlerPanic 2760 // function from exiting before the HTTP server handler 2761 // finishes crashing. If this text function exited too 2762 // early (and its defer log.SetOutput(os.Stderr) ran), 2763 // then the crash output could spill into the next test. 2764 pr, pw := io.Pipe() 2765 log.SetOutput(pw) 2766 defer log.SetOutput(os.Stderr) 2767 defer pw.Close() 2768 2769 var handler Handler = HandlerFunc(func(w ResponseWriter, r *Request) { 2770 if withHijack { 2771 rwc, _, err := w.(Hijacker).Hijack() 2772 if err != nil { 2773 t.Logf("unexpected error: %v", err) 2774 } 2775 defer rwc.Close() 2776 } 2777 panic(panicValue) 2778 }) 2779 if wrapper != nil { 2780 handler = wrapper(handler) 2781 } 2782 cst := newClientServerTest(t, h2, handler) 2783 defer cst.close() 2784 2785 // Do a blocking read on the log output pipe so its logging 2786 // doesn't bleed into the next test. But wait only 5 seconds 2787 // for it. 2788 done := make(chan bool, 1) 2789 go func() { 2790 buf := make([]byte, 4<<10) 2791 _, err := pr.Read(buf) 2792 pr.Close() 2793 if err != nil && err != io.EOF { 2794 t.Error(err) 2795 } 2796 done <- true 2797 }() 2798 2799 _, err := cst.c.Get(cst.ts.URL) 2800 if err == nil { 2801 t.Logf("expected an error") 2802 } 2803 2804 if panicValue == nil { 2805 return 2806 } 2807 2808 select { 2809 case <-done: 2810 return 2811 case <-time.After(5 * time.Second): 2812 t.Fatal("expected server handler to log an error") 2813 } 2814 } 2815 2816 type terrorWriter struct{ t *testing.T } 2817 2818 func (w terrorWriter) Write(p []byte) (int, error) { 2819 w.t.Errorf("%s", p) 2820 return len(p), nil 2821 } 2822 2823 // Issue 16456: allow writing 0 bytes on hijacked conn to test hijack 2824 // without any log spam. 2825 func TestServerWriteHijackZeroBytes(t *testing.T) { 2826 defer afterTest(t) 2827 done := make(chan struct{}) 2828 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2829 defer close(done) 2830 w.(Flusher).Flush() 2831 conn, _, err := w.(Hijacker).Hijack() 2832 if err != nil { 2833 t.Errorf("Hijack: %v", err) 2834 return 2835 } 2836 defer conn.Close() 2837 _, err = w.Write(nil) 2838 if err != ErrHijacked { 2839 t.Errorf("Write error = %v; want ErrHijacked", err) 2840 } 2841 })) 2842 ts.Config.ErrorLog = log.New(terrorWriter{t}, "Unexpected write: ", 0) 2843 ts.Start() 2844 defer ts.Close() 2845 2846 c := ts.Client() 2847 res, err := c.Get(ts.URL) 2848 if err != nil { 2849 t.Fatal(err) 2850 } 2851 res.Body.Close() 2852 select { 2853 case <-done: 2854 case <-time.After(5 * time.Second): 2855 t.Fatal("timeout") 2856 } 2857 } 2858 2859 func TestServerNoDate_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Date") } 2860 func TestServerNoDate_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Date") } 2861 func TestServerNoContentType_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Content-Type") } 2862 func TestServerNoContentType_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Content-Type") } 2863 2864 func testServerNoHeader(t *testing.T, h2 bool, header string) { 2865 setParallel(t) 2866 defer afterTest(t) 2867 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 2868 w.Header()[header] = nil 2869 io.WriteString(w, "<html>foo</html>") // non-empty 2870 })) 2871 defer cst.close() 2872 res, err := cst.c.Get(cst.ts.URL) 2873 if err != nil { 2874 t.Fatal(err) 2875 } 2876 res.Body.Close() 2877 if got, ok := res.Header[header]; ok { 2878 t.Fatalf("Expected no %s header; got %q", header, got) 2879 } 2880 } 2881 2882 func TestStripPrefix(t *testing.T) { 2883 setParallel(t) 2884 defer afterTest(t) 2885 h := HandlerFunc(func(w ResponseWriter, r *Request) { 2886 w.Header().Set("X-Path", r.URL.Path) 2887 }) 2888 ts := httptest.NewServer(StripPrefix("/foo", h)) 2889 defer ts.Close() 2890 2891 c := ts.Client() 2892 2893 res, err := c.Get(ts.URL + "/foo/bar") 2894 if err != nil { 2895 t.Fatal(err) 2896 } 2897 if g, e := res.Header.Get("X-Path"), "/bar"; g != e { 2898 t.Errorf("test 1: got %s, want %s", g, e) 2899 } 2900 res.Body.Close() 2901 2902 res, err = Get(ts.URL + "/bar") 2903 if err != nil { 2904 t.Fatal(err) 2905 } 2906 if g, e := res.StatusCode, 404; g != e { 2907 t.Errorf("test 2: got status %v, want %v", g, e) 2908 } 2909 res.Body.Close() 2910 } 2911 2912 // https://golang.org/issue/18952. 2913 func TestStripPrefixNotModifyRequest(t *testing.T) { 2914 h := StripPrefix("/foo", NotFoundHandler()) 2915 req := httptest.NewRequest("GET", "/foo/bar", nil) 2916 h.ServeHTTP(httptest.NewRecorder(), req) 2917 if req.URL.Path != "/foo/bar" { 2918 t.Errorf("StripPrefix should not modify the provided Request, but it did") 2919 } 2920 } 2921 2922 func TestRequestLimit_h1(t *testing.T) { testRequestLimit(t, h1Mode) } 2923 func TestRequestLimit_h2(t *testing.T) { testRequestLimit(t, h2Mode) } 2924 func testRequestLimit(t *testing.T, h2 bool) { 2925 setParallel(t) 2926 defer afterTest(t) 2927 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 2928 t.Fatalf("didn't expect to get request in Handler") 2929 }), optQuietLog) 2930 defer cst.close() 2931 req, _ := NewRequest("GET", cst.ts.URL, nil) 2932 var bytesPerHeader = len("header12345: val12345\r\n") 2933 for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ { 2934 req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i)) 2935 } 2936 res, err := cst.c.Do(req) 2937 if res != nil { 2938 defer res.Body.Close() 2939 } 2940 if h2 { 2941 // In HTTP/2, the result depends on a race. If the client has received the 2942 // server's SETTINGS before RoundTrip starts sending the request, then RoundTrip 2943 // will fail with an error. Otherwise, the client should receive a 431 from the 2944 // server. 2945 if err == nil && res.StatusCode != 431 { 2946 t.Fatalf("expected 431 response status; got: %d %s", res.StatusCode, res.Status) 2947 } 2948 } else { 2949 // In HTTP/1, we expect a 431 from the server. 2950 // Some HTTP clients may fail on this undefined behavior (server replying and 2951 // closing the connection while the request is still being written), but 2952 // we do support it (at least currently), so we expect a response below. 2953 if err != nil { 2954 t.Fatalf("Do: %v", err) 2955 } 2956 if res.StatusCode != 431 { 2957 t.Fatalf("expected 431 response status; got: %d %s", res.StatusCode, res.Status) 2958 } 2959 } 2960 } 2961 2962 type neverEnding byte 2963 2964 func (b neverEnding) Read(p []byte) (n int, err error) { 2965 for i := range p { 2966 p[i] = byte(b) 2967 } 2968 return len(p), nil 2969 } 2970 2971 type countReader struct { 2972 r io.Reader 2973 n *int64 2974 } 2975 2976 func (cr countReader) Read(p []byte) (n int, err error) { 2977 n, err = cr.r.Read(p) 2978 atomic.AddInt64(cr.n, int64(n)) 2979 return 2980 } 2981 2982 func TestRequestBodyLimit_h1(t *testing.T) { testRequestBodyLimit(t, h1Mode) } 2983 func TestRequestBodyLimit_h2(t *testing.T) { testRequestBodyLimit(t, h2Mode) } 2984 func testRequestBodyLimit(t *testing.T, h2 bool) { 2985 setParallel(t) 2986 defer afterTest(t) 2987 const limit = 1 << 20 2988 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 2989 r.Body = MaxBytesReader(w, r.Body, limit) 2990 n, err := io.Copy(ioutil.Discard, r.Body) 2991 if err == nil { 2992 t.Errorf("expected error from io.Copy") 2993 } 2994 if n != limit { 2995 t.Errorf("io.Copy = %d, want %d", n, limit) 2996 } 2997 })) 2998 defer cst.close() 2999 3000 nWritten := new(int64) 3001 req, _ := NewRequest("POST", cst.ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200)) 3002 3003 // Send the POST, but don't care it succeeds or not. The 3004 // remote side is going to reply and then close the TCP 3005 // connection, and HTTP doesn't really define if that's 3006 // allowed or not. Some HTTP clients will get the response 3007 // and some (like ours, currently) will complain that the 3008 // request write failed, without reading the response. 3009 // 3010 // But that's okay, since what we're really testing is that 3011 // the remote side hung up on us before we wrote too much. 3012 _, _ = cst.c.Do(req) 3013 3014 if atomic.LoadInt64(nWritten) > limit*100 { 3015 t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d", 3016 limit, nWritten) 3017 } 3018 } 3019 3020 // TestClientWriteShutdown tests that if the client shuts down the write 3021 // side of their TCP connection, the server doesn't send a 400 Bad Request. 3022 func TestClientWriteShutdown(t *testing.T) { 3023 if runtime.GOOS == "plan9" { 3024 t.Skip("skipping test; see https://golang.org/issue/17906") 3025 } 3026 defer afterTest(t) 3027 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 3028 defer ts.Close() 3029 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3030 if err != nil { 3031 t.Fatalf("Dial: %v", err) 3032 } 3033 err = conn.(*net.TCPConn).CloseWrite() 3034 if err != nil { 3035 t.Fatalf("CloseWrite: %v", err) 3036 } 3037 donec := make(chan bool) 3038 go func() { 3039 defer close(donec) 3040 bs, err := ioutil.ReadAll(conn) 3041 if err != nil { 3042 t.Errorf("ReadAll: %v", err) 3043 } 3044 got := string(bs) 3045 if got != "" { 3046 t.Errorf("read %q from server; want nothing", got) 3047 } 3048 }() 3049 select { 3050 case <-donec: 3051 case <-time.After(10 * time.Second): 3052 t.Fatalf("timeout") 3053 } 3054 } 3055 3056 // Tests that chunked server responses that write 1 byte at a time are 3057 // buffered before chunk headers are added, not after chunk headers. 3058 func TestServerBufferedChunking(t *testing.T) { 3059 conn := new(testConn) 3060 conn.readBuf.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")) 3061 conn.closec = make(chan bool, 1) 3062 ls := &oneConnListener{conn} 3063 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 3064 rw.(Flusher).Flush() // force the Header to be sent, in chunking mode, not counting the length 3065 rw.Write([]byte{'x'}) 3066 rw.Write([]byte{'y'}) 3067 rw.Write([]byte{'z'}) 3068 })) 3069 <-conn.closec 3070 if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) { 3071 t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q", 3072 conn.writeBuf.Bytes()) 3073 } 3074 } 3075 3076 // Tests that the server flushes its response headers out when it's 3077 // ignoring the response body and waits a bit before forcefully 3078 // closing the TCP connection, causing the client to get a RST. 3079 // See https://golang.org/issue/3595 3080 func TestServerGracefulClose(t *testing.T) { 3081 setParallel(t) 3082 defer afterTest(t) 3083 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3084 Error(w, "bye", StatusUnauthorized) 3085 })) 3086 defer ts.Close() 3087 3088 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3089 if err != nil { 3090 t.Fatal(err) 3091 } 3092 defer conn.Close() 3093 const bodySize = 5 << 20 3094 req := []byte(fmt.Sprintf("POST / HTTP/1.1\r\nHost: foo.com\r\nContent-Length: %d\r\n\r\n", bodySize)) 3095 for i := 0; i < bodySize; i++ { 3096 req = append(req, 'x') 3097 } 3098 writeErr := make(chan error) 3099 go func() { 3100 _, err := conn.Write(req) 3101 writeErr <- err 3102 }() 3103 br := bufio.NewReader(conn) 3104 lineNum := 0 3105 for { 3106 line, err := br.ReadString('\n') 3107 if err == io.EOF { 3108 break 3109 } 3110 if err != nil { 3111 t.Fatalf("ReadLine: %v", err) 3112 } 3113 lineNum++ 3114 if lineNum == 1 && !strings.Contains(line, "401 Unauthorized") { 3115 t.Errorf("Response line = %q; want a 401", line) 3116 } 3117 } 3118 // Wait for write to finish. This is a broken pipe on both 3119 // Darwin and Linux, but checking this isn't the point of 3120 // the test. 3121 <-writeErr 3122 } 3123 3124 func TestCaseSensitiveMethod_h1(t *testing.T) { testCaseSensitiveMethod(t, h1Mode) } 3125 func TestCaseSensitiveMethod_h2(t *testing.T) { testCaseSensitiveMethod(t, h2Mode) } 3126 func testCaseSensitiveMethod(t *testing.T, h2 bool) { 3127 defer afterTest(t) 3128 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 3129 if r.Method != "get" { 3130 t.Errorf(`Got method %q; want "get"`, r.Method) 3131 } 3132 })) 3133 defer cst.close() 3134 req, _ := NewRequest("get", cst.ts.URL, nil) 3135 res, err := cst.c.Do(req) 3136 if err != nil { 3137 t.Error(err) 3138 return 3139 } 3140 3141 res.Body.Close() 3142 } 3143 3144 // TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1 3145 // request (both keep-alive), when a Handler never writes any 3146 // response, the net/http package adds a "Content-Length: 0" response 3147 // header. 3148 func TestContentLengthZero(t *testing.T) { 3149 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {})) 3150 defer ts.Close() 3151 3152 for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} { 3153 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3154 if err != nil { 3155 t.Fatalf("error dialing: %v", err) 3156 } 3157 _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version) 3158 if err != nil { 3159 t.Fatalf("error writing: %v", err) 3160 } 3161 req, _ := NewRequest("GET", "/", nil) 3162 res, err := ReadResponse(bufio.NewReader(conn), req) 3163 if err != nil { 3164 t.Fatalf("error reading response: %v", err) 3165 } 3166 if te := res.TransferEncoding; len(te) > 0 { 3167 t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te) 3168 } 3169 if cl := res.ContentLength; cl != 0 { 3170 t.Errorf("For version %q, Content-Length = %v; want 0", version, cl) 3171 } 3172 conn.Close() 3173 } 3174 } 3175 3176 func TestCloseNotifier(t *testing.T) { 3177 defer afterTest(t) 3178 gotReq := make(chan bool, 1) 3179 sawClose := make(chan bool, 1) 3180 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 3181 gotReq <- true 3182 cc := rw.(CloseNotifier).CloseNotify() 3183 <-cc 3184 sawClose <- true 3185 })) 3186 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3187 if err != nil { 3188 t.Fatalf("error dialing: %v", err) 3189 } 3190 diec := make(chan bool) 3191 go func() { 3192 _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n") 3193 if err != nil { 3194 t.Error(err) 3195 return 3196 } 3197 <-diec 3198 conn.Close() 3199 }() 3200 For: 3201 for { 3202 select { 3203 case <-gotReq: 3204 diec <- true 3205 case <-sawClose: 3206 break For 3207 case <-time.After(5 * time.Second): 3208 t.Fatal("timeout") 3209 } 3210 } 3211 ts.Close() 3212 } 3213 3214 // Tests that a pipelined request does not cause the first request's 3215 // Handler's CloseNotify channel to fire. 3216 // 3217 // Issue 13165 (where it used to deadlock), but behavior changed in Issue 23921. 3218 func TestCloseNotifierPipelined(t *testing.T) { 3219 setParallel(t) 3220 defer afterTest(t) 3221 gotReq := make(chan bool, 2) 3222 sawClose := make(chan bool, 2) 3223 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 3224 gotReq <- true 3225 cc := rw.(CloseNotifier).CloseNotify() 3226 select { 3227 case <-cc: 3228 t.Error("unexpected CloseNotify") 3229 case <-time.After(100 * time.Millisecond): 3230 } 3231 sawClose <- true 3232 })) 3233 defer ts.Close() 3234 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3235 if err != nil { 3236 t.Fatalf("error dialing: %v", err) 3237 } 3238 diec := make(chan bool, 1) 3239 defer close(diec) 3240 go func() { 3241 const req = "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n" 3242 _, err = io.WriteString(conn, req+req) // two requests 3243 if err != nil { 3244 t.Error(err) 3245 return 3246 } 3247 <-diec 3248 conn.Close() 3249 }() 3250 reqs := 0 3251 closes := 0 3252 for { 3253 select { 3254 case <-gotReq: 3255 reqs++ 3256 if reqs > 2 { 3257 t.Fatal("too many requests") 3258 } 3259 case <-sawClose: 3260 closes++ 3261 if closes > 1 { 3262 return 3263 } 3264 case <-time.After(5 * time.Second): 3265 ts.CloseClientConnections() 3266 t.Fatal("timeout") 3267 } 3268 } 3269 } 3270 3271 func TestCloseNotifierChanLeak(t *testing.T) { 3272 defer afterTest(t) 3273 req := reqBytes("GET / HTTP/1.0\nHost: golang.org") 3274 for i := 0; i < 20; i++ { 3275 var output bytes.Buffer 3276 conn := &rwTestConn{ 3277 Reader: bytes.NewReader(req), 3278 Writer: &output, 3279 closec: make(chan bool, 1), 3280 } 3281 ln := &oneConnListener{conn: conn} 3282 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3283 // Ignore the return value and never read from 3284 // it, testing that we don't leak goroutines 3285 // on the sending side: 3286 _ = rw.(CloseNotifier).CloseNotify() 3287 }) 3288 go Serve(ln, handler) 3289 <-conn.closec 3290 } 3291 } 3292 3293 // Tests that we can use CloseNotifier in one request, and later call Hijack 3294 // on a second request on the same connection. 3295 // 3296 // It also tests that the connReader stitches together its background 3297 // 1-byte read for CloseNotifier when CloseNotifier doesn't fire with 3298 // the rest of the second HTTP later. 3299 // 3300 // Issue 9763. 3301 // HTTP/1-only test. (http2 doesn't have Hijack) 3302 func TestHijackAfterCloseNotifier(t *testing.T) { 3303 defer afterTest(t) 3304 script := make(chan string, 2) 3305 script <- "closenotify" 3306 script <- "hijack" 3307 close(script) 3308 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3309 plan := <-script 3310 switch plan { 3311 default: 3312 panic("bogus plan; too many requests") 3313 case "closenotify": 3314 w.(CloseNotifier).CloseNotify() // discard result 3315 w.Header().Set("X-Addr", r.RemoteAddr) 3316 case "hijack": 3317 c, _, err := w.(Hijacker).Hijack() 3318 if err != nil { 3319 t.Errorf("Hijack in Handler: %v", err) 3320 return 3321 } 3322 if _, ok := c.(*net.TCPConn); !ok { 3323 // Verify it's not wrapped in some type. 3324 // Not strictly a go1 compat issue, but in practice it probably is. 3325 t.Errorf("type of hijacked conn is %T; want *net.TCPConn", c) 3326 } 3327 fmt.Fprintf(c, "HTTP/1.0 200 OK\r\nX-Addr: %v\r\nContent-Length: 0\r\n\r\n", r.RemoteAddr) 3328 c.Close() 3329 return 3330 } 3331 })) 3332 defer ts.Close() 3333 res1, err := Get(ts.URL) 3334 if err != nil { 3335 log.Fatal(err) 3336 } 3337 res2, err := Get(ts.URL) 3338 if err != nil { 3339 log.Fatal(err) 3340 } 3341 addr1 := res1.Header.Get("X-Addr") 3342 addr2 := res2.Header.Get("X-Addr") 3343 if addr1 == "" || addr1 != addr2 { 3344 t.Errorf("addr1, addr2 = %q, %q; want same", addr1, addr2) 3345 } 3346 } 3347 3348 func TestHijackBeforeRequestBodyRead(t *testing.T) { 3349 setParallel(t) 3350 defer afterTest(t) 3351 var requestBody = bytes.Repeat([]byte("a"), 1<<20) 3352 bodyOkay := make(chan bool, 1) 3353 gotCloseNotify := make(chan bool, 1) 3354 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3355 defer close(bodyOkay) // caller will read false if nothing else 3356 3357 reqBody := r.Body 3358 r.Body = nil // to test that server.go doesn't use this value. 3359 3360 gone := w.(CloseNotifier).CloseNotify() 3361 slurp, err := ioutil.ReadAll(reqBody) 3362 if err != nil { 3363 t.Errorf("Body read: %v", err) 3364 return 3365 } 3366 if len(slurp) != len(requestBody) { 3367 t.Errorf("Backend read %d request body bytes; want %d", len(slurp), len(requestBody)) 3368 return 3369 } 3370 if !bytes.Equal(slurp, requestBody) { 3371 t.Error("Backend read wrong request body.") // 1MB; omitting details 3372 return 3373 } 3374 bodyOkay <- true 3375 select { 3376 case <-gone: 3377 gotCloseNotify <- true 3378 case <-time.After(5 * time.Second): 3379 gotCloseNotify <- false 3380 } 3381 })) 3382 defer ts.Close() 3383 3384 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3385 if err != nil { 3386 t.Fatal(err) 3387 } 3388 defer conn.Close() 3389 3390 fmt.Fprintf(conn, "POST / HTTP/1.1\r\nHost: foo\r\nContent-Length: %d\r\n\r\n%s", 3391 len(requestBody), requestBody) 3392 if !<-bodyOkay { 3393 // already failed. 3394 return 3395 } 3396 conn.Close() 3397 if !<-gotCloseNotify { 3398 t.Error("timeout waiting for CloseNotify") 3399 } 3400 } 3401 3402 func TestOptions(t *testing.T) { 3403 uric := make(chan string, 2) // only expect 1, but leave space for 2 3404 mux := NewServeMux() 3405 mux.HandleFunc("/", func(w ResponseWriter, r *Request) { 3406 uric <- r.RequestURI 3407 }) 3408 ts := httptest.NewServer(mux) 3409 defer ts.Close() 3410 3411 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3412 if err != nil { 3413 t.Fatal(err) 3414 } 3415 defer conn.Close() 3416 3417 // An OPTIONS * request should succeed. 3418 _, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n")) 3419 if err != nil { 3420 t.Fatal(err) 3421 } 3422 br := bufio.NewReader(conn) 3423 res, err := ReadResponse(br, &Request{Method: "OPTIONS"}) 3424 if err != nil { 3425 t.Fatal(err) 3426 } 3427 if res.StatusCode != 200 { 3428 t.Errorf("Got non-200 response to OPTIONS *: %#v", res) 3429 } 3430 3431 // A GET * request on a ServeMux should fail. 3432 _, err = conn.Write([]byte("GET * HTTP/1.1\r\nHost: foo.com\r\n\r\n")) 3433 if err != nil { 3434 t.Fatal(err) 3435 } 3436 res, err = ReadResponse(br, &Request{Method: "GET"}) 3437 if err != nil { 3438 t.Fatal(err) 3439 } 3440 if res.StatusCode != 400 { 3441 t.Errorf("Got non-400 response to GET *: %#v", res) 3442 } 3443 3444 res, err = Get(ts.URL + "/second") 3445 if err != nil { 3446 t.Fatal(err) 3447 } 3448 res.Body.Close() 3449 if got := <-uric; got != "/second" { 3450 t.Errorf("Handler saw request for %q; want /second", got) 3451 } 3452 } 3453 3454 // Tests regarding the ordering of Write, WriteHeader, Header, and 3455 // Flush calls. In Go 1.0, rw.WriteHeader immediately flushed the 3456 // (*response).header to the wire. In Go 1.1, the actual wire flush is 3457 // delayed, so we could maybe tack on a Content-Length and better 3458 // Content-Type after we see more (or all) of the output. To preserve 3459 // compatibility with Go 1, we need to be careful to track which 3460 // headers were live at the time of WriteHeader, so we write the same 3461 // ones, even if the handler modifies them (~erroneously) after the 3462 // first Write. 3463 func TestHeaderToWire(t *testing.T) { 3464 tests := []struct { 3465 name string 3466 handler func(ResponseWriter, *Request) 3467 check func(got, logs string) error 3468 }{ 3469 { 3470 name: "write without Header", 3471 handler: func(rw ResponseWriter, r *Request) { 3472 rw.Write([]byte("hello world")) 3473 }, 3474 check: func(got, logs string) error { 3475 if !strings.Contains(got, "Content-Length:") { 3476 return errors.New("no content-length") 3477 } 3478 if !strings.Contains(got, "Content-Type: text/plain") { 3479 return errors.New("no content-type") 3480 } 3481 return nil 3482 }, 3483 }, 3484 { 3485 name: "Header mutation before write", 3486 handler: func(rw ResponseWriter, r *Request) { 3487 h := rw.Header() 3488 h.Set("Content-Type", "some/type") 3489 rw.Write([]byte("hello world")) 3490 h.Set("Too-Late", "bogus") 3491 }, 3492 check: func(got, logs string) error { 3493 if !strings.Contains(got, "Content-Length:") { 3494 return errors.New("no content-length") 3495 } 3496 if !strings.Contains(got, "Content-Type: some/type") { 3497 return errors.New("wrong content-type") 3498 } 3499 if strings.Contains(got, "Too-Late") { 3500 return errors.New("don't want too-late header") 3501 } 3502 return nil 3503 }, 3504 }, 3505 { 3506 name: "write then useless Header mutation", 3507 handler: func(rw ResponseWriter, r *Request) { 3508 rw.Write([]byte("hello world")) 3509 rw.Header().Set("Too-Late", "Write already wrote headers") 3510 }, 3511 check: func(got, logs string) error { 3512 if strings.Contains(got, "Too-Late") { 3513 return errors.New("header appeared from after WriteHeader") 3514 } 3515 return nil 3516 }, 3517 }, 3518 { 3519 name: "flush then write", 3520 handler: func(rw ResponseWriter, r *Request) { 3521 rw.(Flusher).Flush() 3522 rw.Write([]byte("post-flush")) 3523 rw.Header().Set("Too-Late", "Write already wrote headers") 3524 }, 3525 check: func(got, logs string) error { 3526 if !strings.Contains(got, "Transfer-Encoding: chunked") { 3527 return errors.New("not chunked") 3528 } 3529 if strings.Contains(got, "Too-Late") { 3530 return errors.New("header appeared from after WriteHeader") 3531 } 3532 return nil 3533 }, 3534 }, 3535 { 3536 name: "header then flush", 3537 handler: func(rw ResponseWriter, r *Request) { 3538 rw.Header().Set("Content-Type", "some/type") 3539 rw.(Flusher).Flush() 3540 rw.Write([]byte("post-flush")) 3541 rw.Header().Set("Too-Late", "Write already wrote headers") 3542 }, 3543 check: func(got, logs string) error { 3544 if !strings.Contains(got, "Transfer-Encoding: chunked") { 3545 return errors.New("not chunked") 3546 } 3547 if strings.Contains(got, "Too-Late") { 3548 return errors.New("header appeared from after WriteHeader") 3549 } 3550 if !strings.Contains(got, "Content-Type: some/type") { 3551 return errors.New("wrong content-type") 3552 } 3553 return nil 3554 }, 3555 }, 3556 { 3557 name: "sniff-on-first-write content-type", 3558 handler: func(rw ResponseWriter, r *Request) { 3559 rw.Write([]byte("<html><head></head><body>some html</body></html>")) 3560 rw.Header().Set("Content-Type", "x/wrong") 3561 }, 3562 check: func(got, logs string) error { 3563 if !strings.Contains(got, "Content-Type: text/html") { 3564 return errors.New("wrong content-type; want html") 3565 } 3566 return nil 3567 }, 3568 }, 3569 { 3570 name: "explicit content-type wins", 3571 handler: func(rw ResponseWriter, r *Request) { 3572 rw.Header().Set("Content-Type", "some/type") 3573 rw.Write([]byte("<html><head></head><body>some html</body></html>")) 3574 }, 3575 check: func(got, logs string) error { 3576 if !strings.Contains(got, "Content-Type: some/type") { 3577 return errors.New("wrong content-type; want html") 3578 } 3579 return nil 3580 }, 3581 }, 3582 { 3583 name: "empty handler", 3584 handler: func(rw ResponseWriter, r *Request) { 3585 }, 3586 check: func(got, logs string) error { 3587 if !strings.Contains(got, "Content-Length: 0") { 3588 return errors.New("want 0 content-length") 3589 } 3590 return nil 3591 }, 3592 }, 3593 { 3594 name: "only Header, no write", 3595 handler: func(rw ResponseWriter, r *Request) { 3596 rw.Header().Set("Some-Header", "some-value") 3597 }, 3598 check: func(got, logs string) error { 3599 if !strings.Contains(got, "Some-Header") { 3600 return errors.New("didn't get header") 3601 } 3602 return nil 3603 }, 3604 }, 3605 { 3606 name: "WriteHeader call", 3607 handler: func(rw ResponseWriter, r *Request) { 3608 rw.WriteHeader(404) 3609 rw.Header().Set("Too-Late", "some-value") 3610 }, 3611 check: func(got, logs string) error { 3612 if !strings.Contains(got, "404") { 3613 return errors.New("wrong status") 3614 } 3615 if strings.Contains(got, "Too-Late") { 3616 return errors.New("shouldn't have seen Too-Late") 3617 } 3618 return nil 3619 }, 3620 }, 3621 } 3622 for _, tc := range tests { 3623 ht := newHandlerTest(HandlerFunc(tc.handler)) 3624 got := ht.rawResponse("GET / HTTP/1.1\nHost: golang.org") 3625 logs := ht.logbuf.String() 3626 if err := tc.check(got, logs); err != nil { 3627 t.Errorf("%s: %v\nGot response:\n%s\n\n%s", tc.name, err, got, logs) 3628 } 3629 } 3630 } 3631 3632 // goTimeout runs f, failing t if f takes more than ns to complete. 3633 func goTimeout(t *testing.T, d time.Duration, f func()) { 3634 ch := make(chan bool, 2) 3635 timer := time.AfterFunc(d, func() { 3636 t.Errorf("Timeout expired after %v", d) 3637 ch <- true 3638 }) 3639 defer timer.Stop() 3640 go func() { 3641 defer func() { ch <- true }() 3642 f() 3643 }() 3644 <-ch 3645 } 3646 3647 type errorListener struct { 3648 errs []error 3649 } 3650 3651 func (l *errorListener) Accept() (c net.Conn, err error) { 3652 if len(l.errs) == 0 { 3653 return nil, io.EOF 3654 } 3655 err = l.errs[0] 3656 l.errs = l.errs[1:] 3657 return 3658 } 3659 3660 func (l *errorListener) Close() error { 3661 return nil 3662 } 3663 3664 func (l *errorListener) Addr() net.Addr { 3665 return dummyAddr("test-address") 3666 } 3667 3668 func TestAcceptMaxFds(t *testing.T) { 3669 setParallel(t) 3670 3671 ln := &errorListener{[]error{ 3672 &net.OpError{ 3673 Op: "accept", 3674 Err: syscall.EMFILE, 3675 }}} 3676 server := &Server{ 3677 Handler: HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {})), 3678 ErrorLog: log.New(ioutil.Discard, "", 0), // noisy otherwise 3679 } 3680 err := server.Serve(ln) 3681 if err != io.EOF { 3682 t.Errorf("got error %v, want EOF", err) 3683 } 3684 } 3685 3686 func TestWriteAfterHijack(t *testing.T) { 3687 req := reqBytes("GET / HTTP/1.1\nHost: golang.org") 3688 var buf bytes.Buffer 3689 wrotec := make(chan bool, 1) 3690 conn := &rwTestConn{ 3691 Reader: bytes.NewReader(req), 3692 Writer: &buf, 3693 closec: make(chan bool, 1), 3694 } 3695 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3696 conn, bufrw, err := rw.(Hijacker).Hijack() 3697 if err != nil { 3698 t.Error(err) 3699 return 3700 } 3701 go func() { 3702 bufrw.Write([]byte("[hijack-to-bufw]")) 3703 bufrw.Flush() 3704 conn.Write([]byte("[hijack-to-conn]")) 3705 conn.Close() 3706 wrotec <- true 3707 }() 3708 }) 3709 ln := &oneConnListener{conn: conn} 3710 go Serve(ln, handler) 3711 <-conn.closec 3712 <-wrotec 3713 if g, w := buf.String(), "[hijack-to-bufw][hijack-to-conn]"; g != w { 3714 t.Errorf("wrote %q; want %q", g, w) 3715 } 3716 } 3717 3718 func TestDoubleHijack(t *testing.T) { 3719 req := reqBytes("GET / HTTP/1.1\nHost: golang.org") 3720 var buf bytes.Buffer 3721 conn := &rwTestConn{ 3722 Reader: bytes.NewReader(req), 3723 Writer: &buf, 3724 closec: make(chan bool, 1), 3725 } 3726 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3727 conn, _, err := rw.(Hijacker).Hijack() 3728 if err != nil { 3729 t.Error(err) 3730 return 3731 } 3732 _, _, err = rw.(Hijacker).Hijack() 3733 if err == nil { 3734 t.Errorf("got err = nil; want err != nil") 3735 } 3736 conn.Close() 3737 }) 3738 ln := &oneConnListener{conn: conn} 3739 go Serve(ln, handler) 3740 <-conn.closec 3741 } 3742 3743 // https://golang.org/issue/5955 3744 // Note that this does not test the "request too large" 3745 // exit path from the http server. This is intentional; 3746 // not sending Connection: close is just a minor wire 3747 // optimization and is pointless if dealing with a 3748 // badly behaved client. 3749 func TestHTTP10ConnectionHeader(t *testing.T) { 3750 defer afterTest(t) 3751 3752 mux := NewServeMux() 3753 mux.Handle("/", HandlerFunc(func(ResponseWriter, *Request) {})) 3754 ts := httptest.NewServer(mux) 3755 defer ts.Close() 3756 3757 // net/http uses HTTP/1.1 for requests, so write requests manually 3758 tests := []struct { 3759 req string // raw http request 3760 expect []string // expected Connection header(s) 3761 }{ 3762 { 3763 req: "GET / HTTP/1.0\r\n\r\n", 3764 expect: nil, 3765 }, 3766 { 3767 req: "OPTIONS * HTTP/1.0\r\n\r\n", 3768 expect: nil, 3769 }, 3770 { 3771 req: "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", 3772 expect: []string{"keep-alive"}, 3773 }, 3774 } 3775 3776 for _, tt := range tests { 3777 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3778 if err != nil { 3779 t.Fatal("dial err:", err) 3780 } 3781 3782 _, err = fmt.Fprint(conn, tt.req) 3783 if err != nil { 3784 t.Fatal("conn write err:", err) 3785 } 3786 3787 resp, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "GET"}) 3788 if err != nil { 3789 t.Fatal("ReadResponse err:", err) 3790 } 3791 conn.Close() 3792 resp.Body.Close() 3793 3794 got := resp.Header["Connection"] 3795 if !reflect.DeepEqual(got, tt.expect) { 3796 t.Errorf("wrong Connection headers for request %q. Got %q expect %q", tt.req, got, tt.expect) 3797 } 3798 } 3799 } 3800 3801 // See golang.org/issue/5660 3802 func TestServerReaderFromOrder_h1(t *testing.T) { testServerReaderFromOrder(t, h1Mode) } 3803 func TestServerReaderFromOrder_h2(t *testing.T) { testServerReaderFromOrder(t, h2Mode) } 3804 func testServerReaderFromOrder(t *testing.T, h2 bool) { 3805 setParallel(t) 3806 defer afterTest(t) 3807 pr, pw := io.Pipe() 3808 const size = 3 << 20 3809 cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) { 3810 rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path 3811 done := make(chan bool) 3812 go func() { 3813 io.Copy(rw, pr) 3814 close(done) 3815 }() 3816 time.Sleep(25 * time.Millisecond) // give Copy a chance to break things 3817 n, err := io.Copy(ioutil.Discard, req.Body) 3818 if err != nil { 3819 t.Errorf("handler Copy: %v", err) 3820 return 3821 } 3822 if n != size { 3823 t.Errorf("handler Copy = %d; want %d", n, size) 3824 } 3825 pw.Write([]byte("hi")) 3826 pw.Close() 3827 <-done 3828 })) 3829 defer cst.close() 3830 3831 req, err := NewRequest("POST", cst.ts.URL, io.LimitReader(neverEnding('a'), size)) 3832 if err != nil { 3833 t.Fatal(err) 3834 } 3835 res, err := cst.c.Do(req) 3836 if err != nil { 3837 t.Fatal(err) 3838 } 3839 all, err := ioutil.ReadAll(res.Body) 3840 if err != nil { 3841 t.Fatal(err) 3842 } 3843 res.Body.Close() 3844 if string(all) != "hi" { 3845 t.Errorf("Body = %q; want hi", all) 3846 } 3847 } 3848 3849 // Issue 6157, Issue 6685 3850 func TestCodesPreventingContentTypeAndBody(t *testing.T) { 3851 for _, code := range []int{StatusNotModified, StatusNoContent, StatusContinue} { 3852 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 3853 if r.URL.Path == "/header" { 3854 w.Header().Set("Content-Length", "123") 3855 } 3856 w.WriteHeader(code) 3857 if r.URL.Path == "/more" { 3858 w.Write([]byte("stuff")) 3859 } 3860 })) 3861 for _, req := range []string{ 3862 "GET / HTTP/1.0", 3863 "GET /header HTTP/1.0", 3864 "GET /more HTTP/1.0", 3865 "GET / HTTP/1.1\nHost: foo", 3866 "GET /header HTTP/1.1\nHost: foo", 3867 "GET /more HTTP/1.1\nHost: foo", 3868 } { 3869 got := ht.rawResponse(req) 3870 wantStatus := fmt.Sprintf("%d %s", code, StatusText(code)) 3871 if !strings.Contains(got, wantStatus) { 3872 t.Errorf("Code %d: Wanted %q Modified for %q: %s", code, wantStatus, req, got) 3873 } else if strings.Contains(got, "Content-Length") { 3874 t.Errorf("Code %d: Got a Content-Length from %q: %s", code, req, got) 3875 } else if strings.Contains(got, "stuff") { 3876 t.Errorf("Code %d: Response contains a body from %q: %s", code, req, got) 3877 } 3878 } 3879 } 3880 } 3881 3882 func TestContentTypeOkayOn204(t *testing.T) { 3883 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 3884 w.Header().Set("Content-Length", "123") // suppressed 3885 w.Header().Set("Content-Type", "foo/bar") 3886 w.WriteHeader(204) 3887 })) 3888 got := ht.rawResponse("GET / HTTP/1.1\nHost: foo") 3889 if !strings.Contains(got, "Content-Type: foo/bar") { 3890 t.Errorf("Response = %q; want Content-Type: foo/bar", got) 3891 } 3892 if strings.Contains(got, "Content-Length: 123") { 3893 t.Errorf("Response = %q; don't want a Content-Length", got) 3894 } 3895 } 3896 3897 // Issue 6995 3898 // A server Handler can receive a Request, and then turn around and 3899 // give a copy of that Request.Body out to the Transport (e.g. any 3900 // proxy). So then two people own that Request.Body (both the server 3901 // and the http client), and both think they can close it on failure. 3902 // Therefore, all incoming server requests Bodies need to be thread-safe. 3903 func TestTransportAndServerSharedBodyRace_h1(t *testing.T) { 3904 testTransportAndServerSharedBodyRace(t, h1Mode) 3905 } 3906 func TestTransportAndServerSharedBodyRace_h2(t *testing.T) { 3907 testTransportAndServerSharedBodyRace(t, h2Mode) 3908 } 3909 func testTransportAndServerSharedBodyRace(t *testing.T, h2 bool) { 3910 setParallel(t) 3911 defer afterTest(t) 3912 3913 const bodySize = 1 << 20 3914 3915 // errorf is like t.Errorf, but also writes to println. When 3916 // this test fails, it hangs. This helps debugging and I've 3917 // added this enough times "temporarily". It now gets added 3918 // full time. 3919 errorf := func(format string, args ...interface{}) { 3920 v := fmt.Sprintf(format, args...) 3921 println(v) 3922 t.Error(v) 3923 } 3924 3925 unblockBackend := make(chan bool) 3926 backend := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) { 3927 gone := rw.(CloseNotifier).CloseNotify() 3928 didCopy := make(chan interface{}) 3929 go func() { 3930 n, err := io.CopyN(rw, req.Body, bodySize) 3931 didCopy <- []interface{}{n, err} 3932 }() 3933 isGone := false 3934 Loop: 3935 for { 3936 select { 3937 case <-didCopy: 3938 break Loop 3939 case <-gone: 3940 isGone = true 3941 case <-time.After(time.Second): 3942 println("1 second passes in backend, proxygone=", isGone) 3943 } 3944 } 3945 <-unblockBackend 3946 })) 3947 var quitTimer *time.Timer 3948 defer func() { quitTimer.Stop() }() 3949 defer backend.close() 3950 3951 backendRespc := make(chan *Response, 1) 3952 var proxy *clientServerTest 3953 proxy = newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) { 3954 req2, _ := NewRequest("POST", backend.ts.URL, req.Body) 3955 req2.ContentLength = bodySize 3956 cancel := make(chan struct{}) 3957 req2.Cancel = cancel 3958 3959 bresp, err := proxy.c.Do(req2) 3960 if err != nil { 3961 errorf("Proxy outbound request: %v", err) 3962 return 3963 } 3964 _, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/2) 3965 if err != nil { 3966 errorf("Proxy copy error: %v", err) 3967 return 3968 } 3969 backendRespc <- bresp // to close later 3970 3971 // Try to cause a race: Both the Transport and the proxy handler's Server 3972 // will try to read/close req.Body (aka req2.Body) 3973 if h2 { 3974 close(cancel) 3975 } else { 3976 proxy.c.Transport.(*Transport).CancelRequest(req2) 3977 } 3978 rw.Write([]byte("OK")) 3979 })) 3980 defer proxy.close() 3981 defer func() { 3982 // Before we shut down our two httptest.Servers, start a timer. 3983 // We choose 7 seconds because httptest.Server starts logging 3984 // warnings to stderr at 5 seconds. If we don't disarm this bomb 3985 // in 7 seconds (after the two httptest.Server.Close calls above), 3986 // then we explode with stacks. 3987 quitTimer = time.AfterFunc(7*time.Second, func() { 3988 debug.SetTraceback("ALL") 3989 stacks := make([]byte, 1<<20) 3990 stacks = stacks[:runtime.Stack(stacks, true)] 3991 fmt.Fprintf(os.Stderr, "%s", stacks) 3992 log.Fatalf("Timeout.") 3993 }) 3994 }() 3995 3996 defer close(unblockBackend) 3997 req, _ := NewRequest("POST", proxy.ts.URL, io.LimitReader(neverEnding('a'), bodySize)) 3998 res, err := proxy.c.Do(req) 3999 if err != nil { 4000 t.Fatalf("Original request: %v", err) 4001 } 4002 4003 // Cleanup, so we don't leak goroutines. 4004 res.Body.Close() 4005 select { 4006 case res := <-backendRespc: 4007 res.Body.Close() 4008 default: 4009 // We failed earlier. (e.g. on proxy.c.Do(req2)) 4010 } 4011 } 4012 4013 // Test that a hanging Request.Body.Read from another goroutine can't 4014 // cause the Handler goroutine's Request.Body.Close to block. 4015 // See issue 7121. 4016 func TestRequestBodyCloseDoesntBlock(t *testing.T) { 4017 if testing.Short() { 4018 t.Skip("skipping in -short mode") 4019 } 4020 defer afterTest(t) 4021 4022 readErrCh := make(chan error, 1) 4023 errCh := make(chan error, 2) 4024 4025 server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 4026 go func(body io.Reader) { 4027 _, err := body.Read(make([]byte, 100)) 4028 readErrCh <- err 4029 }(req.Body) 4030 time.Sleep(500 * time.Millisecond) 4031 })) 4032 defer server.Close() 4033 4034 closeConn := make(chan bool) 4035 defer close(closeConn) 4036 go func() { 4037 conn, err := net.Dial("tcp", server.Listener.Addr().String()) 4038 if err != nil { 4039 errCh <- err 4040 return 4041 } 4042 defer conn.Close() 4043 _, err = conn.Write([]byte("POST / HTTP/1.1\r\nConnection: close\r\nHost: foo\r\nContent-Length: 100000\r\n\r\n")) 4044 if err != nil { 4045 errCh <- err 4046 return 4047 } 4048 // And now just block, making the server block on our 4049 // 100000 bytes of body that will never arrive. 4050 <-closeConn 4051 }() 4052 select { 4053 case err := <-readErrCh: 4054 if err == nil { 4055 t.Error("Read was nil. Expected error.") 4056 } 4057 case err := <-errCh: 4058 t.Error(err) 4059 case <-time.After(5 * time.Second): 4060 t.Error("timeout") 4061 } 4062 } 4063 4064 // test that ResponseWriter implements io.StringWriter. 4065 func TestResponseWriterWriteString(t *testing.T) { 4066 okc := make(chan bool, 1) 4067 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 4068 _, ok := w.(io.StringWriter) 4069 okc <- ok 4070 })) 4071 ht.rawResponse("GET / HTTP/1.0") 4072 select { 4073 case ok := <-okc: 4074 if !ok { 4075 t.Error("ResponseWriter did not implement io.StringWriter") 4076 } 4077 default: 4078 t.Error("handler was never called") 4079 } 4080 } 4081 4082 func TestAppendTime(t *testing.T) { 4083 var b [len(TimeFormat)]byte 4084 t1 := time.Date(2013, 9, 21, 15, 41, 0, 0, time.FixedZone("CEST", 2*60*60)) 4085 res := ExportAppendTime(b[:0], t1) 4086 t2, err := ParseTime(string(res)) 4087 if err != nil { 4088 t.Fatalf("Error parsing time: %s", err) 4089 } 4090 if !t1.Equal(t2) { 4091 t.Fatalf("Times differ; expected: %v, got %v (%s)", t1, t2, string(res)) 4092 } 4093 } 4094 4095 func TestServerConnState(t *testing.T) { 4096 setParallel(t) 4097 defer afterTest(t) 4098 handler := map[string]func(w ResponseWriter, r *Request){ 4099 "/": func(w ResponseWriter, r *Request) { 4100 fmt.Fprintf(w, "Hello.") 4101 }, 4102 "/close": func(w ResponseWriter, r *Request) { 4103 w.Header().Set("Connection", "close") 4104 fmt.Fprintf(w, "Hello.") 4105 }, 4106 "/hijack": func(w ResponseWriter, r *Request) { 4107 c, _, _ := w.(Hijacker).Hijack() 4108 c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello.")) 4109 c.Close() 4110 }, 4111 "/hijack-panic": func(w ResponseWriter, r *Request) { 4112 c, _, _ := w.(Hijacker).Hijack() 4113 c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello.")) 4114 c.Close() 4115 panic("intentional panic") 4116 }, 4117 } 4118 4119 // A stateLog is a log of states over the lifetime of a connection. 4120 type stateLog struct { 4121 active net.Conn // The connection for which the log is recorded; set to the first connection seen in StateNew. 4122 got []ConnState 4123 want []ConnState 4124 complete chan<- struct{} // If non-nil, closed when either 'got' is equal to 'want', or 'got' is no longer a prefix of 'want'. 4125 } 4126 activeLog := make(chan *stateLog, 1) 4127 4128 // wantLog invokes doRequests, then waits for the resulting connection to 4129 // either pass through the sequence of states in want or enter a state outside 4130 // of that sequence. 4131 wantLog := func(doRequests func(), want ...ConnState) { 4132 t.Helper() 4133 complete := make(chan struct{}) 4134 activeLog <- &stateLog{want: want, complete: complete} 4135 4136 doRequests() 4137 4138 timer := time.NewTimer(5 * time.Second) 4139 select { 4140 case <-timer.C: 4141 t.Errorf("Timed out waiting for connection to change state.") 4142 case <-complete: 4143 timer.Stop() 4144 } 4145 sl := <-activeLog 4146 if !reflect.DeepEqual(sl.got, sl.want) { 4147 t.Errorf("Request(s) produced unexpected state sequence.\nGot: %v\nWant: %v", sl.got, sl.want) 4148 } 4149 // Don't return sl to activeLog: we don't expect any further states after 4150 // this point, and want to keep the ConnState callback blocked until the 4151 // next call to wantLog. 4152 } 4153 4154 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4155 handler[r.URL.Path](w, r) 4156 })) 4157 defer func() { 4158 activeLog <- &stateLog{} // If the test failed, allow any remaining ConnState callbacks to complete. 4159 ts.Close() 4160 }() 4161 4162 ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) 4163 ts.Config.ConnState = func(c net.Conn, state ConnState) { 4164 if c == nil { 4165 t.Errorf("nil conn seen in state %s", state) 4166 return 4167 } 4168 sl := <-activeLog 4169 if sl.active == nil && state == StateNew { 4170 sl.active = c 4171 } else if sl.active != c { 4172 t.Errorf("unexpected conn in state %s", state) 4173 activeLog <- sl 4174 return 4175 } 4176 sl.got = append(sl.got, state) 4177 if sl.complete != nil && (len(sl.got) >= len(sl.want) || !reflect.DeepEqual(sl.got, sl.want[:len(sl.got)])) { 4178 close(sl.complete) 4179 sl.complete = nil 4180 } 4181 activeLog <- sl 4182 } 4183 4184 ts.Start() 4185 c := ts.Client() 4186 4187 mustGet := func(url string, headers ...string) { 4188 t.Helper() 4189 req, err := NewRequest("GET", url, nil) 4190 if err != nil { 4191 t.Fatal(err) 4192 } 4193 for len(headers) > 0 { 4194 req.Header.Add(headers[0], headers[1]) 4195 headers = headers[2:] 4196 } 4197 res, err := c.Do(req) 4198 if err != nil { 4199 t.Errorf("Error fetching %s: %v", url, err) 4200 return 4201 } 4202 _, err = ioutil.ReadAll(res.Body) 4203 defer res.Body.Close() 4204 if err != nil { 4205 t.Errorf("Error reading %s: %v", url, err) 4206 } 4207 } 4208 4209 wantLog(func() { 4210 mustGet(ts.URL + "/") 4211 mustGet(ts.URL + "/close") 4212 }, StateNew, StateActive, StateIdle, StateActive, StateClosed) 4213 4214 wantLog(func() { 4215 mustGet(ts.URL + "/") 4216 mustGet(ts.URL+"/", "Connection", "close") 4217 }, StateNew, StateActive, StateIdle, StateActive, StateClosed) 4218 4219 wantLog(func() { 4220 mustGet(ts.URL + "/hijack") 4221 }, StateNew, StateActive, StateHijacked) 4222 4223 wantLog(func() { 4224 mustGet(ts.URL + "/hijack-panic") 4225 }, StateNew, StateActive, StateHijacked) 4226 4227 wantLog(func() { 4228 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4229 if err != nil { 4230 t.Fatal(err) 4231 } 4232 c.Close() 4233 }, StateNew, StateClosed) 4234 4235 wantLog(func() { 4236 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4237 if err != nil { 4238 t.Fatal(err) 4239 } 4240 if _, err := io.WriteString(c, "BOGUS REQUEST\r\n\r\n"); err != nil { 4241 t.Fatal(err) 4242 } 4243 c.Read(make([]byte, 1)) // block until server hangs up on us 4244 c.Close() 4245 }, StateNew, StateActive, StateClosed) 4246 4247 wantLog(func() { 4248 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4249 if err != nil { 4250 t.Fatal(err) 4251 } 4252 if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil { 4253 t.Fatal(err) 4254 } 4255 res, err := ReadResponse(bufio.NewReader(c), nil) 4256 if err != nil { 4257 t.Fatal(err) 4258 } 4259 if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { 4260 t.Fatal(err) 4261 } 4262 c.Close() 4263 }, StateNew, StateActive, StateIdle, StateClosed) 4264 } 4265 4266 func TestServerKeepAlivesEnabled(t *testing.T) { 4267 defer afterTest(t) 4268 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 4269 ts.Config.SetKeepAlivesEnabled(false) 4270 ts.Start() 4271 defer ts.Close() 4272 res, err := Get(ts.URL) 4273 if err != nil { 4274 t.Fatal(err) 4275 } 4276 defer res.Body.Close() 4277 if !res.Close { 4278 t.Errorf("Body.Close == false; want true") 4279 } 4280 } 4281 4282 // golang.org/issue/7856 4283 func TestServerEmptyBodyRace_h1(t *testing.T) { testServerEmptyBodyRace(t, h1Mode) } 4284 func TestServerEmptyBodyRace_h2(t *testing.T) { testServerEmptyBodyRace(t, h2Mode) } 4285 func testServerEmptyBodyRace(t *testing.T, h2 bool) { 4286 setParallel(t) 4287 defer afterTest(t) 4288 var n int32 4289 cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) { 4290 atomic.AddInt32(&n, 1) 4291 }), optQuietLog) 4292 defer cst.close() 4293 var wg sync.WaitGroup 4294 const reqs = 20 4295 for i := 0; i < reqs; i++ { 4296 wg.Add(1) 4297 go func() { 4298 defer wg.Done() 4299 res, err := cst.c.Get(cst.ts.URL) 4300 if err != nil { 4301 t.Error(err) 4302 return 4303 } 4304 defer res.Body.Close() 4305 _, err = io.Copy(ioutil.Discard, res.Body) 4306 if err != nil { 4307 t.Error(err) 4308 return 4309 } 4310 }() 4311 } 4312 wg.Wait() 4313 if got := atomic.LoadInt32(&n); got != reqs { 4314 t.Errorf("handler ran %d times; want %d", got, reqs) 4315 } 4316 } 4317 4318 func TestServerConnStateNew(t *testing.T) { 4319 sawNew := false // if the test is buggy, we'll race on this variable. 4320 srv := &Server{ 4321 ConnState: func(c net.Conn, state ConnState) { 4322 if state == StateNew { 4323 sawNew = true // testing that this write isn't racy 4324 } 4325 }, 4326 Handler: HandlerFunc(func(w ResponseWriter, r *Request) {}), // irrelevant 4327 } 4328 srv.Serve(&oneConnListener{ 4329 conn: &rwTestConn{ 4330 Reader: strings.NewReader("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"), 4331 Writer: ioutil.Discard, 4332 }, 4333 }) 4334 if !sawNew { // testing that this read isn't racy 4335 t.Error("StateNew not seen") 4336 } 4337 } 4338 4339 type closeWriteTestConn struct { 4340 rwTestConn 4341 didCloseWrite bool 4342 } 4343 4344 func (c *closeWriteTestConn) CloseWrite() error { 4345 c.didCloseWrite = true 4346 return nil 4347 } 4348 4349 func TestCloseWrite(t *testing.T) { 4350 setParallel(t) 4351 var srv Server 4352 var testConn closeWriteTestConn 4353 c := ExportServerNewConn(&srv, &testConn) 4354 ExportCloseWriteAndWait(c) 4355 if !testConn.didCloseWrite { 4356 t.Error("didn't see CloseWrite call") 4357 } 4358 } 4359 4360 // This verifies that a handler can Flush and then Hijack. 4361 // 4362 // A similar test crashed once during development, but it was only 4363 // testing this tangentially and temporarily until another TODO was 4364 // fixed. 4365 // 4366 // So add an explicit test for this. 4367 func TestServerFlushAndHijack(t *testing.T) { 4368 defer afterTest(t) 4369 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4370 io.WriteString(w, "Hello, ") 4371 w.(Flusher).Flush() 4372 conn, buf, _ := w.(Hijacker).Hijack() 4373 buf.WriteString("6\r\nworld!\r\n0\r\n\r\n") 4374 if err := buf.Flush(); err != nil { 4375 t.Error(err) 4376 } 4377 if err := conn.Close(); err != nil { 4378 t.Error(err) 4379 } 4380 })) 4381 defer ts.Close() 4382 res, err := Get(ts.URL) 4383 if err != nil { 4384 t.Fatal(err) 4385 } 4386 defer res.Body.Close() 4387 all, err := ioutil.ReadAll(res.Body) 4388 if err != nil { 4389 t.Fatal(err) 4390 } 4391 if want := "Hello, world!"; string(all) != want { 4392 t.Errorf("Got %q; want %q", all, want) 4393 } 4394 } 4395 4396 // golang.org/issue/8534 -- the Server shouldn't reuse a connection 4397 // for keep-alive after it's seen any Write error (e.g. a timeout) on 4398 // that net.Conn. 4399 // 4400 // To test, verify we don't timeout or see fewer unique client 4401 // addresses (== unique connections) than requests. 4402 func TestServerKeepAliveAfterWriteError(t *testing.T) { 4403 if testing.Short() { 4404 t.Skip("skipping in -short mode") 4405 } 4406 defer afterTest(t) 4407 const numReq = 3 4408 addrc := make(chan string, numReq) 4409 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4410 addrc <- r.RemoteAddr 4411 time.Sleep(500 * time.Millisecond) 4412 w.(Flusher).Flush() 4413 })) 4414 ts.Config.WriteTimeout = 250 * time.Millisecond 4415 ts.Start() 4416 defer ts.Close() 4417 4418 errc := make(chan error, numReq) 4419 go func() { 4420 defer close(errc) 4421 for i := 0; i < numReq; i++ { 4422 res, err := Get(ts.URL) 4423 if res != nil { 4424 res.Body.Close() 4425 } 4426 errc <- err 4427 } 4428 }() 4429 4430 timeout := time.NewTimer(numReq * 2 * time.Second) // 4x overkill 4431 defer timeout.Stop() 4432 addrSeen := map[string]bool{} 4433 numOkay := 0 4434 for { 4435 select { 4436 case v := <-addrc: 4437 addrSeen[v] = true 4438 case err, ok := <-errc: 4439 if !ok { 4440 if len(addrSeen) != numReq { 4441 t.Errorf("saw %d unique client addresses; want %d", len(addrSeen), numReq) 4442 } 4443 if numOkay != 0 { 4444 t.Errorf("got %d successful client requests; want 0", numOkay) 4445 } 4446 return 4447 } 4448 if err == nil { 4449 numOkay++ 4450 } 4451 case <-timeout.C: 4452 t.Fatal("timeout waiting for requests to complete") 4453 } 4454 } 4455 } 4456 4457 // Issue 9987: shouldn't add automatic Content-Length (or 4458 // Content-Type) if a Transfer-Encoding was set by the handler. 4459 func TestNoContentLengthIfTransferEncoding(t *testing.T) { 4460 defer afterTest(t) 4461 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4462 w.Header().Set("Transfer-Encoding", "foo") 4463 io.WriteString(w, "<html>") 4464 })) 4465 defer ts.Close() 4466 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4467 if err != nil { 4468 t.Fatalf("Dial: %v", err) 4469 } 4470 defer c.Close() 4471 if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil { 4472 t.Fatal(err) 4473 } 4474 bs := bufio.NewScanner(c) 4475 var got bytes.Buffer 4476 for bs.Scan() { 4477 if strings.TrimSpace(bs.Text()) == "" { 4478 break 4479 } 4480 got.WriteString(bs.Text()) 4481 got.WriteByte('\n') 4482 } 4483 if err := bs.Err(); err != nil { 4484 t.Fatal(err) 4485 } 4486 if strings.Contains(got.String(), "Content-Length") { 4487 t.Errorf("Unexpected Content-Length in response headers: %s", got.String()) 4488 } 4489 if strings.Contains(got.String(), "Content-Type") { 4490 t.Errorf("Unexpected Content-Type in response headers: %s", got.String()) 4491 } 4492 } 4493 4494 // tolerate extra CRLF(s) before Request-Line on subsequent requests on a conn 4495 // Issue 10876. 4496 func TestTolerateCRLFBeforeRequestLine(t *testing.T) { 4497 req := []byte("POST / HTTP/1.1\r\nHost: golang.org\r\nContent-Length: 3\r\n\r\nABC" + 4498 "\r\n\r\n" + // <-- this stuff is bogus, but we'll ignore it 4499 "GET / HTTP/1.1\r\nHost: golang.org\r\n\r\n") 4500 var buf bytes.Buffer 4501 conn := &rwTestConn{ 4502 Reader: bytes.NewReader(req), 4503 Writer: &buf, 4504 closec: make(chan bool, 1), 4505 } 4506 ln := &oneConnListener{conn: conn} 4507 numReq := 0 4508 go Serve(ln, HandlerFunc(func(rw ResponseWriter, r *Request) { 4509 numReq++ 4510 })) 4511 <-conn.closec 4512 if numReq != 2 { 4513 t.Errorf("num requests = %d; want 2", numReq) 4514 t.Logf("Res: %s", buf.Bytes()) 4515 } 4516 } 4517 4518 func TestIssue13893_Expect100(t *testing.T) { 4519 // test that the Server doesn't filter out Expect headers. 4520 req := reqBytes(`PUT /readbody HTTP/1.1 4521 User-Agent: PycURL/7.22.0 4522 Host: 127.0.0.1:9000 4523 Accept: */* 4524 Expect: 100-continue 4525 Content-Length: 10 4526 4527 HelloWorld 4528 4529 `) 4530 var buf bytes.Buffer 4531 conn := &rwTestConn{ 4532 Reader: bytes.NewReader(req), 4533 Writer: &buf, 4534 closec: make(chan bool, 1), 4535 } 4536 ln := &oneConnListener{conn: conn} 4537 go Serve(ln, HandlerFunc(func(w ResponseWriter, r *Request) { 4538 if _, ok := r.Header["Expect"]; !ok { 4539 t.Error("Expect header should not be filtered out") 4540 } 4541 })) 4542 <-conn.closec 4543 } 4544 4545 func TestIssue11549_Expect100(t *testing.T) { 4546 req := reqBytes(`PUT /readbody HTTP/1.1 4547 User-Agent: PycURL/7.22.0 4548 Host: 127.0.0.1:9000 4549 Accept: */* 4550 Expect: 100-continue 4551 Content-Length: 10 4552 4553 HelloWorldPUT /noreadbody HTTP/1.1 4554 User-Agent: PycURL/7.22.0 4555 Host: 127.0.0.1:9000 4556 Accept: */* 4557 Expect: 100-continue 4558 Content-Length: 10 4559 4560 GET /should-be-ignored HTTP/1.1 4561 Host: foo 4562 4563 `) 4564 var buf bytes.Buffer 4565 conn := &rwTestConn{ 4566 Reader: bytes.NewReader(req), 4567 Writer: &buf, 4568 closec: make(chan bool, 1), 4569 } 4570 ln := &oneConnListener{conn: conn} 4571 numReq := 0 4572 go Serve(ln, HandlerFunc(func(w ResponseWriter, r *Request) { 4573 numReq++ 4574 if r.URL.Path == "/readbody" { 4575 ioutil.ReadAll(r.Body) 4576 } 4577 io.WriteString(w, "Hello world!") 4578 })) 4579 <-conn.closec 4580 if numReq != 2 { 4581 t.Errorf("num requests = %d; want 2", numReq) 4582 } 4583 if !strings.Contains(buf.String(), "Connection: close\r\n") { 4584 t.Errorf("expected 'Connection: close' in response; got: %s", buf.String()) 4585 } 4586 } 4587 4588 // If a Handler finishes and there's an unread request body, 4589 // verify the server try to do implicit read on it before replying. 4590 func TestHandlerFinishSkipBigContentLengthRead(t *testing.T) { 4591 setParallel(t) 4592 conn := &testConn{closec: make(chan bool)} 4593 conn.readBuf.Write([]byte(fmt.Sprintf( 4594 "POST / HTTP/1.1\r\n" + 4595 "Host: test\r\n" + 4596 "Content-Length: 9999999999\r\n" + 4597 "\r\n" + strings.Repeat("a", 1<<20)))) 4598 4599 ls := &oneConnListener{conn} 4600 var inHandlerLen int 4601 go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 4602 inHandlerLen = conn.readBuf.Len() 4603 rw.WriteHeader(404) 4604 })) 4605 <-conn.closec 4606 afterHandlerLen := conn.readBuf.Len() 4607 4608 if afterHandlerLen != inHandlerLen { 4609 t.Errorf("unexpected implicit read. Read buffer went from %d -> %d", inHandlerLen, afterHandlerLen) 4610 } 4611 } 4612 4613 func TestHandlerSetsBodyNil_h1(t *testing.T) { testHandlerSetsBodyNil(t, h1Mode) } 4614 func TestHandlerSetsBodyNil_h2(t *testing.T) { testHandlerSetsBodyNil(t, h2Mode) } 4615 func testHandlerSetsBodyNil(t *testing.T, h2 bool) { 4616 defer afterTest(t) 4617 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 4618 r.Body = nil 4619 fmt.Fprintf(w, "%v", r.RemoteAddr) 4620 })) 4621 defer cst.close() 4622 get := func() string { 4623 res, err := cst.c.Get(cst.ts.URL) 4624 if err != nil { 4625 t.Fatal(err) 4626 } 4627 defer res.Body.Close() 4628 slurp, err := ioutil.ReadAll(res.Body) 4629 if err != nil { 4630 t.Fatal(err) 4631 } 4632 return string(slurp) 4633 } 4634 a, b := get(), get() 4635 if a != b { 4636 t.Errorf("Failed to reuse connections between requests: %v vs %v", a, b) 4637 } 4638 } 4639 4640 // Test that we validate the Host header. 4641 // Issue 11206 (invalid bytes in Host) and 13624 (Host present in HTTP/1.1) 4642 func TestServerValidatesHostHeader(t *testing.T) { 4643 tests := []struct { 4644 proto string 4645 host string 4646 want int 4647 }{ 4648 {"HTTP/0.9", "", 400}, 4649 4650 {"HTTP/1.1", "", 400}, 4651 {"HTTP/1.1", "Host: \r\n", 200}, 4652 {"HTTP/1.1", "Host: 1.2.3.4\r\n", 200}, 4653 {"HTTP/1.1", "Host: foo.com\r\n", 200}, 4654 {"HTTP/1.1", "Host: foo-bar_baz.com\r\n", 200}, 4655 {"HTTP/1.1", "Host: foo.com:80\r\n", 200}, 4656 {"HTTP/1.1", "Host: ::1\r\n", 200}, 4657 {"HTTP/1.1", "Host: [::1]\r\n", 200}, // questionable without port, but accept it 4658 {"HTTP/1.1", "Host: [::1]:80\r\n", 200}, 4659 {"HTTP/1.1", "Host: [::1%25en0]:80\r\n", 200}, 4660 {"HTTP/1.1", "Host: 1.2.3.4\r\n", 200}, 4661 {"HTTP/1.1", "Host: \x06\r\n", 400}, 4662 {"HTTP/1.1", "Host: \xff\r\n", 400}, 4663 {"HTTP/1.1", "Host: {\r\n", 400}, 4664 {"HTTP/1.1", "Host: }\r\n", 400}, 4665 {"HTTP/1.1", "Host: first\r\nHost: second\r\n", 400}, 4666 4667 // HTTP/1.0 can lack a host header, but if present 4668 // must play by the rules too: 4669 {"HTTP/1.0", "", 200}, 4670 {"HTTP/1.0", "Host: first\r\nHost: second\r\n", 400}, 4671 {"HTTP/1.0", "Host: \xff\r\n", 400}, 4672 4673 // Make an exception for HTTP upgrade requests: 4674 {"PRI * HTTP/2.0", "", 200}, 4675 4676 // Also an exception for CONNECT requests: (Issue 18215) 4677 {"CONNECT golang.org:443 HTTP/1.1", "", 200}, 4678 4679 // But not other HTTP/2 stuff: 4680 {"PRI / HTTP/2.0", "", 400}, 4681 {"GET / HTTP/2.0", "", 400}, 4682 {"GET / HTTP/3.0", "", 400}, 4683 } 4684 for _, tt := range tests { 4685 conn := &testConn{closec: make(chan bool, 1)} 4686 methodTarget := "GET / " 4687 if !strings.HasPrefix(tt.proto, "HTTP/") { 4688 methodTarget = "" 4689 } 4690 io.WriteString(&conn.readBuf, methodTarget+tt.proto+"\r\n"+tt.host+"\r\n") 4691 4692 ln := &oneConnListener{conn} 4693 srv := Server{ 4694 ErrorLog: quietLog, 4695 Handler: HandlerFunc(func(ResponseWriter, *Request) {}), 4696 } 4697 go srv.Serve(ln) 4698 <-conn.closec 4699 res, err := ReadResponse(bufio.NewReader(&conn.writeBuf), nil) 4700 if err != nil { 4701 t.Errorf("For %s %q, ReadResponse: %v", tt.proto, tt.host, res) 4702 continue 4703 } 4704 if res.StatusCode != tt.want { 4705 t.Errorf("For %s %q, Status = %d; want %d", tt.proto, tt.host, res.StatusCode, tt.want) 4706 } 4707 } 4708 } 4709 4710 func TestServerHandlersCanHandleH2PRI(t *testing.T) { 4711 const upgradeResponse = "upgrade here" 4712 defer afterTest(t) 4713 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4714 conn, br, err := w.(Hijacker).Hijack() 4715 if err != nil { 4716 t.Error(err) 4717 return 4718 } 4719 defer conn.Close() 4720 if r.Method != "PRI" || r.RequestURI != "*" { 4721 t.Errorf("Got method/target %q %q; want PRI *", r.Method, r.RequestURI) 4722 return 4723 } 4724 if !r.Close { 4725 t.Errorf("Request.Close = true; want false") 4726 } 4727 const want = "SM\r\n\r\n" 4728 buf := make([]byte, len(want)) 4729 n, err := io.ReadFull(br, buf) 4730 if err != nil || string(buf[:n]) != want { 4731 t.Errorf("Read = %v, %v (%q), want %q", n, err, buf[:n], want) 4732 return 4733 } 4734 io.WriteString(conn, upgradeResponse) 4735 })) 4736 defer ts.Close() 4737 4738 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4739 if err != nil { 4740 t.Fatalf("Dial: %v", err) 4741 } 4742 defer c.Close() 4743 io.WriteString(c, "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n") 4744 slurp, err := ioutil.ReadAll(c) 4745 if err != nil { 4746 t.Fatal(err) 4747 } 4748 if string(slurp) != upgradeResponse { 4749 t.Errorf("Handler response = %q; want %q", slurp, upgradeResponse) 4750 } 4751 } 4752 4753 // Test that we validate the valid bytes in HTTP/1 headers. 4754 // Issue 11207. 4755 func TestServerValidatesHeaders(t *testing.T) { 4756 setParallel(t) 4757 tests := []struct { 4758 header string 4759 want int 4760 }{ 4761 {"", 200}, 4762 {"Foo: bar\r\n", 200}, 4763 {"X-Foo: bar\r\n", 200}, 4764 {"Foo: a space\r\n", 200}, 4765 4766 {"A space: foo\r\n", 400}, // space in header 4767 {"foo\xffbar: foo\r\n", 400}, // binary in header 4768 {"foo\x00bar: foo\r\n", 400}, // binary in header 4769 {"Foo: " + strings.Repeat("x", 1<<21) + "\r\n", 431}, // header too large 4770 // Spaces between the header key and colon are not allowed. 4771 // See RFC 7230, Section 3.2.4. 4772 {"Foo : bar\r\n", 400}, 4773 {"Foo\t: bar\r\n", 400}, 4774 4775 {"foo: foo foo\r\n", 200}, // LWS space is okay 4776 {"foo: foo\tfoo\r\n", 200}, // LWS tab is okay 4777 {"foo: foo\x00foo\r\n", 400}, // CTL 0x00 in value is bad 4778 {"foo: foo\x7ffoo\r\n", 400}, // CTL 0x7f in value is bad 4779 {"foo: foo\xfffoo\r\n", 200}, // non-ASCII high octets in value are fine 4780 } 4781 for _, tt := range tests { 4782 conn := &testConn{closec: make(chan bool, 1)} 4783 io.WriteString(&conn.readBuf, "GET / HTTP/1.1\r\nHost: foo\r\n"+tt.header+"\r\n") 4784 4785 ln := &oneConnListener{conn} 4786 srv := Server{ 4787 ErrorLog: quietLog, 4788 Handler: HandlerFunc(func(ResponseWriter, *Request) {}), 4789 } 4790 go srv.Serve(ln) 4791 <-conn.closec 4792 res, err := ReadResponse(bufio.NewReader(&conn.writeBuf), nil) 4793 if err != nil { 4794 t.Errorf("For %q, ReadResponse: %v", tt.header, res) 4795 continue 4796 } 4797 if res.StatusCode != tt.want { 4798 t.Errorf("For %q, Status = %d; want %d", tt.header, res.StatusCode, tt.want) 4799 } 4800 } 4801 } 4802 4803 func TestServerRequestContextCancel_ServeHTTPDone_h1(t *testing.T) { 4804 testServerRequestContextCancel_ServeHTTPDone(t, h1Mode) 4805 } 4806 func TestServerRequestContextCancel_ServeHTTPDone_h2(t *testing.T) { 4807 testServerRequestContextCancel_ServeHTTPDone(t, h2Mode) 4808 } 4809 func testServerRequestContextCancel_ServeHTTPDone(t *testing.T, h2 bool) { 4810 setParallel(t) 4811 defer afterTest(t) 4812 ctxc := make(chan context.Context, 1) 4813 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 4814 ctx := r.Context() 4815 select { 4816 case <-ctx.Done(): 4817 t.Error("should not be Done in ServeHTTP") 4818 default: 4819 } 4820 ctxc <- ctx 4821 })) 4822 defer cst.close() 4823 res, err := cst.c.Get(cst.ts.URL) 4824 if err != nil { 4825 t.Fatal(err) 4826 } 4827 res.Body.Close() 4828 ctx := <-ctxc 4829 select { 4830 case <-ctx.Done(): 4831 default: 4832 t.Error("context should be done after ServeHTTP completes") 4833 } 4834 } 4835 4836 // Tests that the Request.Context available to the Handler is canceled 4837 // if the peer closes their TCP connection. This requires that the server 4838 // is always blocked in a Read call so it notices the EOF from the client. 4839 // See issues 15927 and 15224. 4840 func TestServerRequestContextCancel_ConnClose(t *testing.T) { 4841 setParallel(t) 4842 defer afterTest(t) 4843 inHandler := make(chan struct{}) 4844 handlerDone := make(chan struct{}) 4845 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4846 close(inHandler) 4847 select { 4848 case <-r.Context().Done(): 4849 case <-time.After(3 * time.Second): 4850 t.Errorf("timeout waiting for context to be done") 4851 } 4852 close(handlerDone) 4853 })) 4854 defer ts.Close() 4855 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4856 if err != nil { 4857 t.Fatal(err) 4858 } 4859 defer c.Close() 4860 io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n") 4861 select { 4862 case <-inHandler: 4863 case <-time.After(3 * time.Second): 4864 t.Fatalf("timeout waiting to see ServeHTTP get called") 4865 } 4866 c.Close() // this should trigger the context being done 4867 4868 select { 4869 case <-handlerDone: 4870 case <-time.After(4 * time.Second): 4871 t.Fatalf("timeout waiting to see ServeHTTP exit") 4872 } 4873 } 4874 4875 func TestServerContext_ServerContextKey_h1(t *testing.T) { 4876 testServerContext_ServerContextKey(t, h1Mode) 4877 } 4878 func TestServerContext_ServerContextKey_h2(t *testing.T) { 4879 testServerContext_ServerContextKey(t, h2Mode) 4880 } 4881 func testServerContext_ServerContextKey(t *testing.T, h2 bool) { 4882 setParallel(t) 4883 defer afterTest(t) 4884 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 4885 ctx := r.Context() 4886 got := ctx.Value(ServerContextKey) 4887 if _, ok := got.(*Server); !ok { 4888 t.Errorf("context value = %T; want *http.Server", got) 4889 } 4890 })) 4891 defer cst.close() 4892 res, err := cst.c.Get(cst.ts.URL) 4893 if err != nil { 4894 t.Fatal(err) 4895 } 4896 res.Body.Close() 4897 } 4898 4899 func TestServerContext_LocalAddrContextKey_h1(t *testing.T) { 4900 testServerContext_LocalAddrContextKey(t, h1Mode) 4901 } 4902 func TestServerContext_LocalAddrContextKey_h2(t *testing.T) { 4903 testServerContext_LocalAddrContextKey(t, h2Mode) 4904 } 4905 func testServerContext_LocalAddrContextKey(t *testing.T, h2 bool) { 4906 setParallel(t) 4907 defer afterTest(t) 4908 ch := make(chan interface{}, 1) 4909 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 4910 ch <- r.Context().Value(LocalAddrContextKey) 4911 })) 4912 defer cst.close() 4913 if _, err := cst.c.Head(cst.ts.URL); err != nil { 4914 t.Fatal(err) 4915 } 4916 4917 host := cst.ts.Listener.Addr().String() 4918 select { 4919 case got := <-ch: 4920 if addr, ok := got.(net.Addr); !ok { 4921 t.Errorf("local addr value = %T; want net.Addr", got) 4922 } else if fmt.Sprint(addr) != host { 4923 t.Errorf("local addr = %v; want %v", addr, host) 4924 } 4925 case <-time.After(5 * time.Second): 4926 t.Error("timed out") 4927 } 4928 } 4929 4930 // https://golang.org/issue/15960 4931 func TestHandlerSetTransferEncodingChunked(t *testing.T) { 4932 setParallel(t) 4933 defer afterTest(t) 4934 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 4935 w.Header().Set("Transfer-Encoding", "chunked") 4936 w.Write([]byte("hello")) 4937 })) 4938 resp := ht.rawResponse("GET / HTTP/1.1\nHost: foo") 4939 const hdr = "Transfer-Encoding: chunked" 4940 if n := strings.Count(resp, hdr); n != 1 { 4941 t.Errorf("want 1 occurrence of %q in response, got %v\nresponse: %v", hdr, n, resp) 4942 } 4943 } 4944 4945 // https://golang.org/issue/16063 4946 func TestHandlerSetTransferEncodingGzip(t *testing.T) { 4947 setParallel(t) 4948 defer afterTest(t) 4949 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 4950 w.Header().Set("Transfer-Encoding", "gzip") 4951 gz := gzip.NewWriter(w) 4952 gz.Write([]byte("hello")) 4953 gz.Close() 4954 })) 4955 resp := ht.rawResponse("GET / HTTP/1.1\nHost: foo") 4956 for _, v := range []string{"gzip", "chunked"} { 4957 hdr := "Transfer-Encoding: " + v 4958 if n := strings.Count(resp, hdr); n != 1 { 4959 t.Errorf("want 1 occurrence of %q in response, got %v\nresponse: %v", hdr, n, resp) 4960 } 4961 } 4962 } 4963 4964 func BenchmarkClientServer(b *testing.B) { 4965 b.ReportAllocs() 4966 b.StopTimer() 4967 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 4968 fmt.Fprintf(rw, "Hello world.\n") 4969 })) 4970 defer ts.Close() 4971 b.StartTimer() 4972 4973 for i := 0; i < b.N; i++ { 4974 res, err := Get(ts.URL) 4975 if err != nil { 4976 b.Fatal("Get:", err) 4977 } 4978 all, err := ioutil.ReadAll(res.Body) 4979 res.Body.Close() 4980 if err != nil { 4981 b.Fatal("ReadAll:", err) 4982 } 4983 body := string(all) 4984 if body != "Hello world.\n" { 4985 b.Fatal("Got body:", body) 4986 } 4987 } 4988 4989 b.StopTimer() 4990 } 4991 4992 func BenchmarkClientServerParallel4(b *testing.B) { 4993 benchmarkClientServerParallel(b, 4, false) 4994 } 4995 4996 func BenchmarkClientServerParallel64(b *testing.B) { 4997 benchmarkClientServerParallel(b, 64, false) 4998 } 4999 5000 func BenchmarkClientServerParallelTLS4(b *testing.B) { 5001 benchmarkClientServerParallel(b, 4, true) 5002 } 5003 5004 func BenchmarkClientServerParallelTLS64(b *testing.B) { 5005 benchmarkClientServerParallel(b, 64, true) 5006 } 5007 5008 func benchmarkClientServerParallel(b *testing.B, parallelism int, useTLS bool) { 5009 b.ReportAllocs() 5010 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 5011 fmt.Fprintf(rw, "Hello world.\n") 5012 })) 5013 if useTLS { 5014 ts.StartTLS() 5015 } else { 5016 ts.Start() 5017 } 5018 defer ts.Close() 5019 b.ResetTimer() 5020 b.SetParallelism(parallelism) 5021 b.RunParallel(func(pb *testing.PB) { 5022 c := ts.Client() 5023 for pb.Next() { 5024 res, err := c.Get(ts.URL) 5025 if err != nil { 5026 b.Logf("Get: %v", err) 5027 continue 5028 } 5029 all, err := ioutil.ReadAll(res.Body) 5030 res.Body.Close() 5031 if err != nil { 5032 b.Logf("ReadAll: %v", err) 5033 continue 5034 } 5035 body := string(all) 5036 if body != "Hello world.\n" { 5037 panic("Got body: " + body) 5038 } 5039 } 5040 }) 5041 } 5042 5043 // A benchmark for profiling the server without the HTTP client code. 5044 // The client code runs in a subprocess. 5045 // 5046 // For use like: 5047 // $ go test -c 5048 // $ ./http.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=http.prof 5049 // $ go tool pprof http.test http.prof 5050 // (pprof) web 5051 func BenchmarkServer(b *testing.B) { 5052 b.ReportAllocs() 5053 // Child process mode; 5054 if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" { 5055 n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N")) 5056 if err != nil { 5057 panic(err) 5058 } 5059 for i := 0; i < n; i++ { 5060 res, err := Get(url) 5061 if err != nil { 5062 log.Panicf("Get: %v", err) 5063 } 5064 all, err := ioutil.ReadAll(res.Body) 5065 res.Body.Close() 5066 if err != nil { 5067 log.Panicf("ReadAll: %v", err) 5068 } 5069 body := string(all) 5070 if body != "Hello world.\n" { 5071 log.Panicf("Got body: %q", body) 5072 } 5073 } 5074 os.Exit(0) 5075 return 5076 } 5077 5078 var res = []byte("Hello world.\n") 5079 b.StopTimer() 5080 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 5081 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 5082 rw.Write(res) 5083 })) 5084 defer ts.Close() 5085 b.StartTimer() 5086 5087 cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer$") 5088 cmd.Env = append([]string{ 5089 fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N), 5090 fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL), 5091 }, os.Environ()...) 5092 out, err := cmd.CombinedOutput() 5093 if err != nil { 5094 b.Errorf("Test failure: %v, with output: %s", err, out) 5095 } 5096 } 5097 5098 // getNoBody wraps Get but closes any Response.Body before returning the response. 5099 func getNoBody(urlStr string) (*Response, error) { 5100 res, err := Get(urlStr) 5101 if err != nil { 5102 return nil, err 5103 } 5104 res.Body.Close() 5105 return res, nil 5106 } 5107 5108 // A benchmark for profiling the client without the HTTP server code. 5109 // The server code runs in a subprocess. 5110 func BenchmarkClient(b *testing.B) { 5111 b.ReportAllocs() 5112 b.StopTimer() 5113 defer afterTest(b) 5114 5115 var data = []byte("Hello world.\n") 5116 if server := os.Getenv("TEST_BENCH_SERVER"); server != "" { 5117 // Server process mode. 5118 port := os.Getenv("TEST_BENCH_SERVER_PORT") // can be set by user 5119 if port == "" { 5120 port = "0" 5121 } 5122 ln, err := net.Listen("tcp", "localhost:"+port) 5123 if err != nil { 5124 fmt.Fprintln(os.Stderr, err.Error()) 5125 os.Exit(1) 5126 } 5127 fmt.Println(ln.Addr().String()) 5128 HandleFunc("/", func(w ResponseWriter, r *Request) { 5129 r.ParseForm() 5130 if r.Form.Get("stop") != "" { 5131 os.Exit(0) 5132 } 5133 w.Header().Set("Content-Type", "text/html; charset=utf-8") 5134 w.Write(data) 5135 }) 5136 var srv Server 5137 log.Fatal(srv.Serve(ln)) 5138 } 5139 5140 // Start server process. 5141 cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkClient$") 5142 cmd.Env = append(os.Environ(), "TEST_BENCH_SERVER=yes") 5143 cmd.Stderr = os.Stderr 5144 stdout, err := cmd.StdoutPipe() 5145 if err != nil { 5146 b.Fatal(err) 5147 } 5148 if err := cmd.Start(); err != nil { 5149 b.Fatalf("subprocess failed to start: %v", err) 5150 } 5151 defer cmd.Process.Kill() 5152 5153 // Wait for the server in the child process to respond and tell us 5154 // its listening address, once it's started listening: 5155 timer := time.AfterFunc(10*time.Second, func() { 5156 cmd.Process.Kill() 5157 }) 5158 defer timer.Stop() 5159 bs := bufio.NewScanner(stdout) 5160 if !bs.Scan() { 5161 b.Fatalf("failed to read listening URL from child: %v", bs.Err()) 5162 } 5163 url := "http://" + strings.TrimSpace(bs.Text()) + "/" 5164 timer.Stop() 5165 if _, err := getNoBody(url); err != nil { 5166 b.Fatalf("initial probe of child process failed: %v", err) 5167 } 5168 5169 done := make(chan error) 5170 go func() { 5171 done <- cmd.Wait() 5172 }() 5173 5174 // Do b.N requests to the server. 5175 b.StartTimer() 5176 for i := 0; i < b.N; i++ { 5177 res, err := Get(url) 5178 if err != nil { 5179 b.Fatalf("Get: %v", err) 5180 } 5181 body, err := ioutil.ReadAll(res.Body) 5182 res.Body.Close() 5183 if err != nil { 5184 b.Fatalf("ReadAll: %v", err) 5185 } 5186 if !bytes.Equal(body, data) { 5187 b.Fatalf("Got body: %q", body) 5188 } 5189 } 5190 b.StopTimer() 5191 5192 // Instruct server process to stop. 5193 getNoBody(url + "?stop=yes") 5194 select { 5195 case err := <-done: 5196 if err != nil { 5197 b.Fatalf("subprocess failed: %v", err) 5198 } 5199 case <-time.After(5 * time.Second): 5200 b.Fatalf("subprocess did not stop") 5201 } 5202 } 5203 5204 func BenchmarkServerFakeConnNoKeepAlive(b *testing.B) { 5205 b.ReportAllocs() 5206 req := reqBytes(`GET / HTTP/1.0 5207 Host: golang.org 5208 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5209 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 5210 Accept-Encoding: gzip,deflate,sdch 5211 Accept-Language: en-US,en;q=0.8 5212 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 5213 `) 5214 res := []byte("Hello world!\n") 5215 5216 conn := &testConn{ 5217 // testConn.Close will not push into the channel 5218 // if it's full. 5219 closec: make(chan bool, 1), 5220 } 5221 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 5222 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 5223 rw.Write(res) 5224 }) 5225 ln := new(oneConnListener) 5226 for i := 0; i < b.N; i++ { 5227 conn.readBuf.Reset() 5228 conn.writeBuf.Reset() 5229 conn.readBuf.Write(req) 5230 ln.conn = conn 5231 Serve(ln, handler) 5232 <-conn.closec 5233 } 5234 } 5235 5236 // repeatReader reads content count times, then EOFs. 5237 type repeatReader struct { 5238 content []byte 5239 count int 5240 off int 5241 } 5242 5243 func (r *repeatReader) Read(p []byte) (n int, err error) { 5244 if r.count <= 0 { 5245 return 0, io.EOF 5246 } 5247 n = copy(p, r.content[r.off:]) 5248 r.off += n 5249 if r.off == len(r.content) { 5250 r.count-- 5251 r.off = 0 5252 } 5253 return 5254 } 5255 5256 func BenchmarkServerFakeConnWithKeepAlive(b *testing.B) { 5257 b.ReportAllocs() 5258 5259 req := reqBytes(`GET / HTTP/1.1 5260 Host: golang.org 5261 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5262 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 5263 Accept-Encoding: gzip,deflate,sdch 5264 Accept-Language: en-US,en;q=0.8 5265 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 5266 `) 5267 res := []byte("Hello world!\n") 5268 5269 conn := &rwTestConn{ 5270 Reader: &repeatReader{content: req, count: b.N}, 5271 Writer: ioutil.Discard, 5272 closec: make(chan bool, 1), 5273 } 5274 handled := 0 5275 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 5276 handled++ 5277 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 5278 rw.Write(res) 5279 }) 5280 ln := &oneConnListener{conn: conn} 5281 go Serve(ln, handler) 5282 <-conn.closec 5283 if b.N != handled { 5284 b.Errorf("b.N=%d but handled %d", b.N, handled) 5285 } 5286 } 5287 5288 // same as above, but representing the most simple possible request 5289 // and handler. Notably: the handler does not call rw.Header(). 5290 func BenchmarkServerFakeConnWithKeepAliveLite(b *testing.B) { 5291 b.ReportAllocs() 5292 5293 req := reqBytes(`GET / HTTP/1.1 5294 Host: golang.org 5295 `) 5296 res := []byte("Hello world!\n") 5297 5298 conn := &rwTestConn{ 5299 Reader: &repeatReader{content: req, count: b.N}, 5300 Writer: ioutil.Discard, 5301 closec: make(chan bool, 1), 5302 } 5303 handled := 0 5304 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 5305 handled++ 5306 rw.Write(res) 5307 }) 5308 ln := &oneConnListener{conn: conn} 5309 go Serve(ln, handler) 5310 <-conn.closec 5311 if b.N != handled { 5312 b.Errorf("b.N=%d but handled %d", b.N, handled) 5313 } 5314 } 5315 5316 const someResponse = "<html>some response</html>" 5317 5318 // A Response that's just no bigger than 2KB, the buffer-before-chunking threshold. 5319 var response = bytes.Repeat([]byte(someResponse), 2<<10/len(someResponse)) 5320 5321 // Both Content-Type and Content-Length set. Should be no buffering. 5322 func BenchmarkServerHandlerTypeLen(b *testing.B) { 5323 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 5324 w.Header().Set("Content-Type", "text/html") 5325 w.Header().Set("Content-Length", strconv.Itoa(len(response))) 5326 w.Write(response) 5327 })) 5328 } 5329 5330 // A Content-Type is set, but no length. No sniffing, but will count the Content-Length. 5331 func BenchmarkServerHandlerNoLen(b *testing.B) { 5332 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 5333 w.Header().Set("Content-Type", "text/html") 5334 w.Write(response) 5335 })) 5336 } 5337 5338 // A Content-Length is set, but the Content-Type will be sniffed. 5339 func BenchmarkServerHandlerNoType(b *testing.B) { 5340 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 5341 w.Header().Set("Content-Length", strconv.Itoa(len(response))) 5342 w.Write(response) 5343 })) 5344 } 5345 5346 // Neither a Content-Type or Content-Length, so sniffed and counted. 5347 func BenchmarkServerHandlerNoHeader(b *testing.B) { 5348 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 5349 w.Write(response) 5350 })) 5351 } 5352 5353 func benchmarkHandler(b *testing.B, h Handler) { 5354 b.ReportAllocs() 5355 req := reqBytes(`GET / HTTP/1.1 5356 Host: golang.org 5357 `) 5358 conn := &rwTestConn{ 5359 Reader: &repeatReader{content: req, count: b.N}, 5360 Writer: ioutil.Discard, 5361 closec: make(chan bool, 1), 5362 } 5363 handled := 0 5364 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 5365 handled++ 5366 h.ServeHTTP(rw, r) 5367 }) 5368 ln := &oneConnListener{conn: conn} 5369 go Serve(ln, handler) 5370 <-conn.closec 5371 if b.N != handled { 5372 b.Errorf("b.N=%d but handled %d", b.N, handled) 5373 } 5374 } 5375 5376 func BenchmarkServerHijack(b *testing.B) { 5377 b.ReportAllocs() 5378 req := reqBytes(`GET / HTTP/1.1 5379 Host: golang.org 5380 `) 5381 h := HandlerFunc(func(w ResponseWriter, r *Request) { 5382 conn, _, err := w.(Hijacker).Hijack() 5383 if err != nil { 5384 panic(err) 5385 } 5386 conn.Close() 5387 }) 5388 conn := &rwTestConn{ 5389 Writer: ioutil.Discard, 5390 closec: make(chan bool, 1), 5391 } 5392 ln := &oneConnListener{conn: conn} 5393 for i := 0; i < b.N; i++ { 5394 conn.Reader = bytes.NewReader(req) 5395 ln.conn = conn 5396 Serve(ln, h) 5397 <-conn.closec 5398 } 5399 } 5400 5401 func BenchmarkCloseNotifier(b *testing.B) { 5402 b.ReportAllocs() 5403 b.StopTimer() 5404 sawClose := make(chan bool) 5405 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 5406 <-rw.(CloseNotifier).CloseNotify() 5407 sawClose <- true 5408 })) 5409 defer ts.Close() 5410 tot := time.NewTimer(5 * time.Second) 5411 defer tot.Stop() 5412 b.StartTimer() 5413 for i := 0; i < b.N; i++ { 5414 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 5415 if err != nil { 5416 b.Fatalf("error dialing: %v", err) 5417 } 5418 _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n") 5419 if err != nil { 5420 b.Fatal(err) 5421 } 5422 conn.Close() 5423 tot.Reset(5 * time.Second) 5424 select { 5425 case <-sawClose: 5426 case <-tot.C: 5427 b.Fatal("timeout") 5428 } 5429 } 5430 b.StopTimer() 5431 } 5432 5433 // Verify this doesn't race (Issue 16505) 5434 func TestConcurrentServerServe(t *testing.T) { 5435 setParallel(t) 5436 for i := 0; i < 100; i++ { 5437 ln1 := &oneConnListener{conn: nil} 5438 ln2 := &oneConnListener{conn: nil} 5439 srv := Server{} 5440 go func() { srv.Serve(ln1) }() 5441 go func() { srv.Serve(ln2) }() 5442 } 5443 } 5444 5445 func TestServerIdleTimeout(t *testing.T) { 5446 if testing.Short() { 5447 t.Skip("skipping in short mode") 5448 } 5449 setParallel(t) 5450 defer afterTest(t) 5451 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5452 io.Copy(ioutil.Discard, r.Body) 5453 io.WriteString(w, r.RemoteAddr) 5454 })) 5455 ts.Config.ReadHeaderTimeout = 1 * time.Second 5456 ts.Config.IdleTimeout = 2 * time.Second 5457 ts.Start() 5458 defer ts.Close() 5459 c := ts.Client() 5460 5461 get := func() string { 5462 res, err := c.Get(ts.URL) 5463 if err != nil { 5464 t.Fatal(err) 5465 } 5466 defer res.Body.Close() 5467 slurp, err := ioutil.ReadAll(res.Body) 5468 if err != nil { 5469 t.Fatal(err) 5470 } 5471 return string(slurp) 5472 } 5473 5474 a1, a2 := get(), get() 5475 if a1 != a2 { 5476 t.Fatalf("did requests on different connections") 5477 } 5478 time.Sleep(3 * time.Second) 5479 a3 := get() 5480 if a2 == a3 { 5481 t.Fatal("request three unexpectedly on same connection") 5482 } 5483 5484 // And test that ReadHeaderTimeout still works: 5485 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 5486 if err != nil { 5487 t.Fatal(err) 5488 } 5489 defer conn.Close() 5490 conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo.com\r\n")) 5491 time.Sleep(2 * time.Second) 5492 if _, err := io.CopyN(ioutil.Discard, conn, 1); err == nil { 5493 t.Fatal("copy byte succeeded; want err") 5494 } 5495 } 5496 5497 func get(t *testing.T, c *Client, url string) string { 5498 res, err := c.Get(url) 5499 if err != nil { 5500 t.Fatal(err) 5501 } 5502 defer res.Body.Close() 5503 slurp, err := ioutil.ReadAll(res.Body) 5504 if err != nil { 5505 t.Fatal(err) 5506 } 5507 return string(slurp) 5508 } 5509 5510 // Tests that calls to Server.SetKeepAlivesEnabled(false) closes any 5511 // currently-open connections. 5512 func TestServerSetKeepAlivesEnabledClosesConns(t *testing.T) { 5513 setParallel(t) 5514 defer afterTest(t) 5515 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5516 io.WriteString(w, r.RemoteAddr) 5517 })) 5518 defer ts.Close() 5519 5520 c := ts.Client() 5521 tr := c.Transport.(*Transport) 5522 5523 get := func() string { return get(t, c, ts.URL) } 5524 5525 a1, a2 := get(), get() 5526 if a1 != a2 { 5527 t.Fatal("expected first two requests on same connection") 5528 } 5529 addr := strings.TrimPrefix(ts.URL, "http://") 5530 5531 // The two requests should have used the same connection, 5532 // and there should not have been a second connection that 5533 // was created by racing dial against reuse. 5534 // (The first get was completed when the second get started.) 5535 n := tr.IdleConnCountForTesting("http", addr) 5536 if n != 1 { 5537 t.Fatalf("idle count for %q after 2 gets = %d, want 1", addr, n) 5538 } 5539 5540 // SetKeepAlivesEnabled should discard idle conns. 5541 ts.Config.SetKeepAlivesEnabled(false) 5542 5543 var idle1 int 5544 if !waitCondition(2*time.Second, 10*time.Millisecond, func() bool { 5545 idle1 = tr.IdleConnCountForTesting("http", addr) 5546 return idle1 == 0 5547 }) { 5548 t.Fatalf("idle count after SetKeepAlivesEnabled called = %v; want 0", idle1) 5549 } 5550 5551 a3 := get() 5552 if a3 == a2 { 5553 t.Fatal("expected third request on new connection") 5554 } 5555 } 5556 5557 func TestServerShutdown_h1(t *testing.T) { testServerShutdown(t, h1Mode) } 5558 func TestServerShutdown_h2(t *testing.T) { testServerShutdown(t, h2Mode) } 5559 5560 func testServerShutdown(t *testing.T, h2 bool) { 5561 setParallel(t) 5562 defer afterTest(t) 5563 var doShutdown func() // set later 5564 var shutdownRes = make(chan error, 1) 5565 var gotOnShutdown = make(chan struct{}, 1) 5566 handler := HandlerFunc(func(w ResponseWriter, r *Request) { 5567 go doShutdown() 5568 // Shutdown is graceful, so it should not interrupt 5569 // this in-flight response. Add a tiny sleep here to 5570 // increase the odds of a failure if shutdown has 5571 // bugs. 5572 time.Sleep(20 * time.Millisecond) 5573 io.WriteString(w, r.RemoteAddr) 5574 }) 5575 cst := newClientServerTest(t, h2, handler, func(srv *httptest.Server) { 5576 srv.Config.RegisterOnShutdown(func() { gotOnShutdown <- struct{}{} }) 5577 }) 5578 defer cst.close() 5579 5580 doShutdown = func() { 5581 shutdownRes <- cst.ts.Config.Shutdown(context.Background()) 5582 } 5583 get(t, cst.c, cst.ts.URL) // calls t.Fail on failure 5584 5585 if err := <-shutdownRes; err != nil { 5586 t.Fatalf("Shutdown: %v", err) 5587 } 5588 select { 5589 case <-gotOnShutdown: 5590 case <-time.After(5 * time.Second): 5591 t.Errorf("onShutdown callback not called, RegisterOnShutdown broken?") 5592 } 5593 5594 res, err := cst.c.Get(cst.ts.URL) 5595 if err == nil { 5596 res.Body.Close() 5597 t.Fatal("second request should fail. server should be shut down") 5598 } 5599 } 5600 5601 func TestServerShutdownStateNew(t *testing.T) { 5602 if testing.Short() { 5603 t.Skip("test takes 5-6 seconds; skipping in short mode") 5604 } 5605 setParallel(t) 5606 defer afterTest(t) 5607 5608 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5609 // nothing. 5610 })) 5611 var connAccepted sync.WaitGroup 5612 ts.Config.ConnState = func(conn net.Conn, state ConnState) { 5613 if state == StateNew { 5614 connAccepted.Done() 5615 } 5616 } 5617 ts.Start() 5618 defer ts.Close() 5619 5620 // Start a connection but never write to it. 5621 connAccepted.Add(1) 5622 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 5623 if err != nil { 5624 t.Fatal(err) 5625 } 5626 defer c.Close() 5627 5628 // Wait for the connection to be accepted by the server. Otherwise, if 5629 // Shutdown happens to run first, the server will be closed when 5630 // encountering the connection, in which case it will be rejected 5631 // immediately. 5632 connAccepted.Wait() 5633 5634 shutdownRes := make(chan error, 1) 5635 go func() { 5636 shutdownRes <- ts.Config.Shutdown(context.Background()) 5637 }() 5638 readRes := make(chan error, 1) 5639 go func() { 5640 _, err := c.Read([]byte{0}) 5641 readRes <- err 5642 }() 5643 5644 const expectTimeout = 5 * time.Second 5645 t0 := time.Now() 5646 select { 5647 case got := <-shutdownRes: 5648 d := time.Since(t0) 5649 if got != nil { 5650 t.Fatalf("shutdown error after %v: %v", d, err) 5651 } 5652 if d < expectTimeout/2 { 5653 t.Errorf("shutdown too soon after %v", d) 5654 } 5655 case <-time.After(expectTimeout * 3 / 2): 5656 t.Fatalf("timeout waiting for shutdown") 5657 } 5658 5659 // Wait for c.Read to unblock; should be already done at this point, 5660 // or within a few milliseconds. 5661 select { 5662 case err := <-readRes: 5663 if err == nil { 5664 t.Error("expected error from Read") 5665 } 5666 case <-time.After(2 * time.Second): 5667 t.Errorf("timeout waiting for Read to unblock") 5668 } 5669 } 5670 5671 // Issue 17878: tests that we can call Close twice. 5672 func TestServerCloseDeadlock(t *testing.T) { 5673 var s Server 5674 s.Close() 5675 s.Close() 5676 } 5677 5678 // Issue 17717: tests that Server.SetKeepAlivesEnabled is respected by 5679 // both HTTP/1 and HTTP/2. 5680 func TestServerKeepAlivesEnabled_h1(t *testing.T) { testServerKeepAlivesEnabled(t, h1Mode) } 5681 func TestServerKeepAlivesEnabled_h2(t *testing.T) { testServerKeepAlivesEnabled(t, h2Mode) } 5682 func testServerKeepAlivesEnabled(t *testing.T, h2 bool) { 5683 if h2 { 5684 restore := ExportSetH2GoawayTimeout(10 * time.Millisecond) 5685 defer restore() 5686 } 5687 // Not parallel: messes with global variable. (http2goAwayTimeout) 5688 defer afterTest(t) 5689 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 5690 fmt.Fprintf(w, "%v", r.RemoteAddr) 5691 })) 5692 defer cst.close() 5693 srv := cst.ts.Config 5694 srv.SetKeepAlivesEnabled(false) 5695 a := cst.getURL(cst.ts.URL) 5696 if !waitCondition(2*time.Second, 10*time.Millisecond, srv.ExportAllConnsIdle) { 5697 t.Fatalf("test server has active conns") 5698 } 5699 b := cst.getURL(cst.ts.URL) 5700 if a == b { 5701 t.Errorf("got same connection between first and second requests") 5702 } 5703 if !waitCondition(2*time.Second, 10*time.Millisecond, srv.ExportAllConnsIdle) { 5704 t.Fatalf("test server has active conns") 5705 } 5706 } 5707 5708 // Issue 18447: test that the Server's ReadTimeout is stopped while 5709 // the server's doing its 1-byte background read between requests, 5710 // waiting for the connection to maybe close. 5711 func TestServerCancelsReadTimeoutWhenIdle(t *testing.T) { 5712 setParallel(t) 5713 defer afterTest(t) 5714 runTimeSensitiveTest(t, []time.Duration{ 5715 10 * time.Millisecond, 5716 50 * time.Millisecond, 5717 250 * time.Millisecond, 5718 time.Second, 5719 2 * time.Second, 5720 }, func(t *testing.T, timeout time.Duration) error { 5721 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5722 select { 5723 case <-time.After(2 * timeout): 5724 fmt.Fprint(w, "ok") 5725 case <-r.Context().Done(): 5726 fmt.Fprint(w, r.Context().Err()) 5727 } 5728 })) 5729 ts.Config.ReadTimeout = timeout 5730 ts.Start() 5731 defer ts.Close() 5732 5733 c := ts.Client() 5734 5735 res, err := c.Get(ts.URL) 5736 if err != nil { 5737 return fmt.Errorf("Get: %v", err) 5738 } 5739 slurp, err := ioutil.ReadAll(res.Body) 5740 res.Body.Close() 5741 if err != nil { 5742 return fmt.Errorf("Body ReadAll: %v", err) 5743 } 5744 if string(slurp) != "ok" { 5745 return fmt.Errorf("got: %q, want ok", slurp) 5746 } 5747 return nil 5748 }) 5749 } 5750 5751 // runTimeSensitiveTest runs test with the provided durations until one passes. 5752 // If they all fail, t.Fatal is called with the last one's duration and error value. 5753 func runTimeSensitiveTest(t *testing.T, durations []time.Duration, test func(t *testing.T, d time.Duration) error) { 5754 for i, d := range durations { 5755 err := test(t, d) 5756 if err == nil { 5757 return 5758 } 5759 if i == len(durations)-1 { 5760 t.Fatalf("failed with duration %v: %v", d, err) 5761 } 5762 } 5763 } 5764 5765 // Issue 18535: test that the Server doesn't try to do a background 5766 // read if it's already done one. 5767 func TestServerDuplicateBackgroundRead(t *testing.T) { 5768 if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm" { 5769 testenv.SkipFlaky(t, 24826) 5770 } 5771 5772 setParallel(t) 5773 defer afterTest(t) 5774 5775 goroutines := 5 5776 requests := 2000 5777 if testing.Short() { 5778 goroutines = 3 5779 requests = 100 5780 } 5781 5782 hts := httptest.NewServer(HandlerFunc(NotFound)) 5783 defer hts.Close() 5784 5785 reqBytes := []byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n") 5786 5787 var wg sync.WaitGroup 5788 for i := 0; i < goroutines; i++ { 5789 wg.Add(1) 5790 go func() { 5791 defer wg.Done() 5792 cn, err := net.Dial("tcp", hts.Listener.Addr().String()) 5793 if err != nil { 5794 t.Error(err) 5795 return 5796 } 5797 defer cn.Close() 5798 5799 wg.Add(1) 5800 go func() { 5801 defer wg.Done() 5802 io.Copy(ioutil.Discard, cn) 5803 }() 5804 5805 for j := 0; j < requests; j++ { 5806 if t.Failed() { 5807 return 5808 } 5809 _, err := cn.Write(reqBytes) 5810 if err != nil { 5811 t.Error(err) 5812 return 5813 } 5814 } 5815 }() 5816 } 5817 wg.Wait() 5818 } 5819 5820 // Test that the bufio.Reader returned by Hijack includes any buffered 5821 // byte (from the Server's backgroundRead) in its buffer. We want the 5822 // Handler code to be able to tell that a byte is available via 5823 // bufio.Reader.Buffered(), without resorting to Reading it 5824 // (potentially blocking) to get at it. 5825 func TestServerHijackGetsBackgroundByte(t *testing.T) { 5826 if runtime.GOOS == "plan9" { 5827 t.Skip("skipping test; see https://golang.org/issue/18657") 5828 } 5829 setParallel(t) 5830 defer afterTest(t) 5831 done := make(chan struct{}) 5832 inHandler := make(chan bool, 1) 5833 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5834 defer close(done) 5835 5836 // Tell the client to send more data after the GET request. 5837 inHandler <- true 5838 5839 conn, buf, err := w.(Hijacker).Hijack() 5840 if err != nil { 5841 t.Error(err) 5842 return 5843 } 5844 defer conn.Close() 5845 5846 peek, err := buf.Reader.Peek(3) 5847 if string(peek) != "foo" || err != nil { 5848 t.Errorf("Peek = %q, %v; want foo, nil", peek, err) 5849 } 5850 5851 select { 5852 case <-r.Context().Done(): 5853 t.Error("context unexpectedly canceled") 5854 default: 5855 } 5856 })) 5857 defer ts.Close() 5858 5859 cn, err := net.Dial("tcp", ts.Listener.Addr().String()) 5860 if err != nil { 5861 t.Fatal(err) 5862 } 5863 defer cn.Close() 5864 if _, err := cn.Write([]byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n")); err != nil { 5865 t.Fatal(err) 5866 } 5867 <-inHandler 5868 if _, err := cn.Write([]byte("foo")); err != nil { 5869 t.Fatal(err) 5870 } 5871 5872 if err := cn.(*net.TCPConn).CloseWrite(); err != nil { 5873 t.Fatal(err) 5874 } 5875 select { 5876 case <-done: 5877 case <-time.After(2 * time.Second): 5878 t.Error("timeout") 5879 } 5880 } 5881 5882 // Like TestServerHijackGetsBackgroundByte above but sending a 5883 // immediate 1MB of data to the server to fill up the server's 4KB 5884 // buffer. 5885 func TestServerHijackGetsBackgroundByte_big(t *testing.T) { 5886 if runtime.GOOS == "plan9" { 5887 t.Skip("skipping test; see https://golang.org/issue/18657") 5888 } 5889 setParallel(t) 5890 defer afterTest(t) 5891 done := make(chan struct{}) 5892 const size = 8 << 10 5893 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5894 defer close(done) 5895 5896 conn, buf, err := w.(Hijacker).Hijack() 5897 if err != nil { 5898 t.Error(err) 5899 return 5900 } 5901 defer conn.Close() 5902 slurp, err := ioutil.ReadAll(buf.Reader) 5903 if err != nil { 5904 t.Errorf("Copy: %v", err) 5905 } 5906 allX := true 5907 for _, v := range slurp { 5908 if v != 'x' { 5909 allX = false 5910 } 5911 } 5912 if len(slurp) != size { 5913 t.Errorf("read %d; want %d", len(slurp), size) 5914 } else if !allX { 5915 t.Errorf("read %q; want %d 'x'", slurp, size) 5916 } 5917 })) 5918 defer ts.Close() 5919 5920 cn, err := net.Dial("tcp", ts.Listener.Addr().String()) 5921 if err != nil { 5922 t.Fatal(err) 5923 } 5924 defer cn.Close() 5925 if _, err := fmt.Fprintf(cn, "GET / HTTP/1.1\r\nHost: e.com\r\n\r\n%s", 5926 strings.Repeat("x", size)); err != nil { 5927 t.Fatal(err) 5928 } 5929 if err := cn.(*net.TCPConn).CloseWrite(); err != nil { 5930 t.Fatal(err) 5931 } 5932 5933 select { 5934 case <-done: 5935 case <-time.After(2 * time.Second): 5936 t.Error("timeout") 5937 } 5938 } 5939 5940 // Issue 18319: test that the Server validates the request method. 5941 func TestServerValidatesMethod(t *testing.T) { 5942 tests := []struct { 5943 method string 5944 want int 5945 }{ 5946 {"GET", 200}, 5947 {"GE(T", 400}, 5948 } 5949 for _, tt := range tests { 5950 conn := &testConn{closec: make(chan bool, 1)} 5951 io.WriteString(&conn.readBuf, tt.method+" / HTTP/1.1\r\nHost: foo.example\r\n\r\n") 5952 5953 ln := &oneConnListener{conn} 5954 go Serve(ln, serve(200)) 5955 <-conn.closec 5956 res, err := ReadResponse(bufio.NewReader(&conn.writeBuf), nil) 5957 if err != nil { 5958 t.Errorf("For %s, ReadResponse: %v", tt.method, res) 5959 continue 5960 } 5961 if res.StatusCode != tt.want { 5962 t.Errorf("For %s, Status = %d; want %d", tt.method, res.StatusCode, tt.want) 5963 } 5964 } 5965 } 5966 5967 // Listener for TestServerListenNotComparableListener. 5968 type eofListenerNotComparable []int 5969 5970 func (eofListenerNotComparable) Accept() (net.Conn, error) { return nil, io.EOF } 5971 func (eofListenerNotComparable) Addr() net.Addr { return nil } 5972 func (eofListenerNotComparable) Close() error { return nil } 5973 5974 // Issue 24812: don't crash on non-comparable Listener 5975 func TestServerListenNotComparableListener(t *testing.T) { 5976 var s Server 5977 s.Serve(make(eofListenerNotComparable, 1)) // used to panic 5978 } 5979 5980 // countCloseListener is a Listener wrapper that counts the number of Close calls. 5981 type countCloseListener struct { 5982 net.Listener 5983 closes int32 // atomic 5984 } 5985 5986 func (p *countCloseListener) Close() error { 5987 atomic.AddInt32(&p.closes, 1) 5988 return nil 5989 } 5990 5991 // Issue 24803: don't call Listener.Close on Server.Shutdown. 5992 func TestServerCloseListenerOnce(t *testing.T) { 5993 setParallel(t) 5994 defer afterTest(t) 5995 5996 ln := newLocalListener(t) 5997 defer ln.Close() 5998 5999 cl := &countCloseListener{Listener: ln} 6000 server := &Server{} 6001 sdone := make(chan bool, 1) 6002 6003 go func() { 6004 server.Serve(cl) 6005 sdone <- true 6006 }() 6007 time.Sleep(10 * time.Millisecond) 6008 server.Shutdown(context.Background()) 6009 ln.Close() 6010 <-sdone 6011 6012 nclose := atomic.LoadInt32(&cl.closes) 6013 if nclose != 1 { 6014 t.Errorf("Close calls = %v; want 1", nclose) 6015 } 6016 } 6017 6018 // Issue 20239: don't block in Serve if Shutdown is called first. 6019 func TestServerShutdownThenServe(t *testing.T) { 6020 var srv Server 6021 cl := &countCloseListener{Listener: nil} 6022 srv.Shutdown(context.Background()) 6023 got := srv.Serve(cl) 6024 if got != ErrServerClosed { 6025 t.Errorf("Serve err = %v; want ErrServerClosed", got) 6026 } 6027 nclose := atomic.LoadInt32(&cl.closes) 6028 if nclose != 1 { 6029 t.Errorf("Close calls = %v; want 1", nclose) 6030 } 6031 } 6032 6033 // Issue 23351: document and test behavior of ServeMux with ports 6034 func TestStripPortFromHost(t *testing.T) { 6035 mux := NewServeMux() 6036 6037 mux.HandleFunc("example.com/", func(w ResponseWriter, r *Request) { 6038 fmt.Fprintf(w, "OK") 6039 }) 6040 mux.HandleFunc("example.com:9000/", func(w ResponseWriter, r *Request) { 6041 fmt.Fprintf(w, "uh-oh!") 6042 }) 6043 6044 req := httptest.NewRequest("GET", "http://example.com:9000/", nil) 6045 rw := httptest.NewRecorder() 6046 6047 mux.ServeHTTP(rw, req) 6048 6049 response := rw.Body.String() 6050 if response != "OK" { 6051 t.Errorf("Response gotten was %q", response) 6052 } 6053 } 6054 6055 func TestServerContexts(t *testing.T) { 6056 setParallel(t) 6057 defer afterTest(t) 6058 type baseKey struct{} 6059 type connKey struct{} 6060 ch := make(chan context.Context, 1) 6061 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 6062 ch <- r.Context() 6063 })) 6064 ts.Config.BaseContext = func(ln net.Listener) context.Context { 6065 if strings.Contains(reflect.TypeOf(ln).String(), "onceClose") { 6066 t.Errorf("unexpected onceClose listener type %T", ln) 6067 } 6068 return context.WithValue(context.Background(), baseKey{}, "base") 6069 } 6070 ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { 6071 if got, want := ctx.Value(baseKey{}), "base"; got != want { 6072 t.Errorf("in ConnContext, base context key = %#v; want %q", got, want) 6073 } 6074 return context.WithValue(ctx, connKey{}, "conn") 6075 } 6076 ts.Start() 6077 defer ts.Close() 6078 res, err := ts.Client().Get(ts.URL) 6079 if err != nil { 6080 t.Fatal(err) 6081 } 6082 res.Body.Close() 6083 ctx := <-ch 6084 if got, want := ctx.Value(baseKey{}), "base"; got != want { 6085 t.Errorf("base context key = %#v; want %q", got, want) 6086 } 6087 if got, want := ctx.Value(connKey{}), "conn"; got != want { 6088 t.Errorf("conn context key = %#v; want %q", got, want) 6089 } 6090 } 6091 6092 func TestServerContextsHTTP2(t *testing.T) { 6093 setParallel(t) 6094 defer afterTest(t) 6095 type baseKey struct{} 6096 type connKey struct{} 6097 ch := make(chan context.Context, 1) 6098 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 6099 if r.ProtoMajor != 2 { 6100 t.Errorf("unexpected HTTP/1.x request") 6101 } 6102 ch <- r.Context() 6103 })) 6104 ts.Config.BaseContext = func(ln net.Listener) context.Context { 6105 if strings.Contains(reflect.TypeOf(ln).String(), "onceClose") { 6106 t.Errorf("unexpected onceClose listener type %T", ln) 6107 } 6108 return context.WithValue(context.Background(), baseKey{}, "base") 6109 } 6110 ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { 6111 if got, want := ctx.Value(baseKey{}), "base"; got != want { 6112 t.Errorf("in ConnContext, base context key = %#v; want %q", got, want) 6113 } 6114 return context.WithValue(ctx, connKey{}, "conn") 6115 } 6116 ts.TLS = &tls.Config{ 6117 NextProtos: []string{"h2", "http/1.1"}, 6118 } 6119 ts.StartTLS() 6120 defer ts.Close() 6121 ts.Client().Transport.(*Transport).ForceAttemptHTTP2 = true 6122 res, err := ts.Client().Get(ts.URL) 6123 if err != nil { 6124 t.Fatal(err) 6125 } 6126 res.Body.Close() 6127 ctx := <-ch 6128 if got, want := ctx.Value(baseKey{}), "base"; got != want { 6129 t.Errorf("base context key = %#v; want %q", got, want) 6130 } 6131 if got, want := ctx.Value(connKey{}), "conn"; got != want { 6132 t.Errorf("conn context key = %#v; want %q", got, want) 6133 } 6134 } 6135 6136 // Issue 35750: check ConnContext not modifying context for other connections 6137 func TestConnContextNotModifyingAllContexts(t *testing.T) { 6138 setParallel(t) 6139 defer afterTest(t) 6140 type connKey struct{} 6141 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 6142 rw.Header().Set("Connection", "close") 6143 })) 6144 ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { 6145 if got := ctx.Value(connKey{}); got != nil { 6146 t.Errorf("in ConnContext, unexpected context key = %#v", got) 6147 } 6148 return context.WithValue(ctx, connKey{}, "conn") 6149 } 6150 ts.Start() 6151 defer ts.Close() 6152 6153 var res *Response 6154 var err error 6155 6156 res, err = ts.Client().Get(ts.URL) 6157 if err != nil { 6158 t.Fatal(err) 6159 } 6160 res.Body.Close() 6161 6162 res, err = ts.Client().Get(ts.URL) 6163 if err != nil { 6164 t.Fatal(err) 6165 } 6166 res.Body.Close() 6167 } 6168 6169 // Issue 30710: ensure that as per the spec, a server responds 6170 // with 501 Not Implemented for unsupported transfer-encodings. 6171 func TestUnsupportedTransferEncodingsReturn501(t *testing.T) { 6172 cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 6173 w.Write([]byte("Hello, World!")) 6174 })) 6175 defer cst.Close() 6176 6177 serverURL, err := url.Parse(cst.URL) 6178 if err != nil { 6179 t.Fatalf("Failed to parse server URL: %v", err) 6180 } 6181 6182 unsupportedTEs := []string{ 6183 "fugazi", 6184 "foo-bar", 6185 "unknown", 6186 } 6187 6188 for _, badTE := range unsupportedTEs { 6189 http1ReqBody := fmt.Sprintf(""+ 6190 "POST / HTTP/1.1\r\nConnection: close\r\n"+ 6191 "Host: localhost\r\nTransfer-Encoding: %s\r\n\r\n", badTE) 6192 6193 gotBody, err := fetchWireResponse(serverURL.Host, []byte(http1ReqBody)) 6194 if err != nil { 6195 t.Errorf("%q. unexpected error: %v", badTE, err) 6196 continue 6197 } 6198 6199 wantBody := fmt.Sprintf("" + 6200 "HTTP/1.1 501 Not Implemented\r\nContent-Type: text/plain; charset=utf-8\r\n" + 6201 "Connection: close\r\n\r\nUnsupported transfer encoding") 6202 6203 if string(gotBody) != wantBody { 6204 t.Errorf("%q. body\ngot\n%q\nwant\n%q", badTE, gotBody, wantBody) 6205 } 6206 } 6207 } 6208 6209 func TestContentEncodingNoSniffing_h1(t *testing.T) { 6210 testContentEncodingNoSniffing(t, h1Mode) 6211 } 6212 6213 func TestContentEncodingNoSniffing_h2(t *testing.T) { 6214 testContentEncodingNoSniffing(t, h2Mode) 6215 } 6216 6217 // Issue 31753: don't sniff when Content-Encoding is set 6218 func testContentEncodingNoSniffing(t *testing.T, h2 bool) { 6219 setParallel(t) 6220 defer afterTest(t) 6221 6222 type setting struct { 6223 name string 6224 body []byte 6225 6226 // setting contentEncoding as an interface instead of a string 6227 // directly, so as to differentiate between 3 states: 6228 // unset, empty string "" and set string "foo/bar". 6229 contentEncoding interface{} 6230 wantContentType string 6231 } 6232 6233 settings := []*setting{ 6234 { 6235 name: "gzip content-encoding, gzipped", // don't sniff. 6236 contentEncoding: "application/gzip", 6237 wantContentType: "", 6238 body: func() []byte { 6239 buf := new(bytes.Buffer) 6240 gzw := gzip.NewWriter(buf) 6241 gzw.Write([]byte("doctype html><p>Hello</p>")) 6242 gzw.Close() 6243 return buf.Bytes() 6244 }(), 6245 }, 6246 { 6247 name: "zlib content-encoding, zlibbed", // don't sniff. 6248 contentEncoding: "application/zlib", 6249 wantContentType: "", 6250 body: func() []byte { 6251 buf := new(bytes.Buffer) 6252 zw := zlib.NewWriter(buf) 6253 zw.Write([]byte("doctype html><p>Hello</p>")) 6254 zw.Close() 6255 return buf.Bytes() 6256 }(), 6257 }, 6258 { 6259 name: "no content-encoding", // must sniff. 6260 wantContentType: "application/x-gzip", 6261 body: func() []byte { 6262 buf := new(bytes.Buffer) 6263 gzw := gzip.NewWriter(buf) 6264 gzw.Write([]byte("doctype html><p>Hello</p>")) 6265 gzw.Close() 6266 return buf.Bytes() 6267 }(), 6268 }, 6269 { 6270 name: "phony content-encoding", // don't sniff. 6271 contentEncoding: "foo/bar", 6272 body: []byte("doctype html><p>Hello</p>"), 6273 }, 6274 { 6275 name: "empty but set content-encoding", 6276 contentEncoding: "", 6277 wantContentType: "audio/mpeg", 6278 body: []byte("ID3"), 6279 }, 6280 } 6281 6282 for _, tt := range settings { 6283 t.Run(tt.name, func(t *testing.T) { 6284 cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, r *Request) { 6285 if tt.contentEncoding != nil { 6286 rw.Header().Set("Content-Encoding", tt.contentEncoding.(string)) 6287 } 6288 rw.Write(tt.body) 6289 })) 6290 defer cst.close() 6291 6292 res, err := cst.c.Get(cst.ts.URL) 6293 if err != nil { 6294 t.Fatalf("Failed to fetch URL: %v", err) 6295 } 6296 defer res.Body.Close() 6297 6298 if g, w := res.Header.Get("Content-Encoding"), tt.contentEncoding; g != w { 6299 if w != nil { // The case where contentEncoding was set explicitly. 6300 t.Errorf("Content-Encoding mismatch\n\tgot: %q\n\twant: %q", g, w) 6301 } else if g != "" { // "" should be the equivalent when the contentEncoding is unset. 6302 t.Errorf("Unexpected Content-Encoding %q", g) 6303 } 6304 } 6305 6306 if g, w := res.Header.Get("Content-Type"), tt.wantContentType; g != w { 6307 t.Errorf("Content-Type mismatch\n\tgot: %q\n\twant: %q", g, w) 6308 } 6309 }) 6310 } 6311 } 6312 6313 // Issue 30803: ensure that TimeoutHandler logs spurious 6314 // WriteHeader calls, for consistency with other Handlers. 6315 func TestTimeoutHandlerSuperfluousLogs(t *testing.T) { 6316 if testing.Short() { 6317 t.Skip("skipping in short mode") 6318 } 6319 6320 setParallel(t) 6321 defer afterTest(t) 6322 6323 pc, curFile, _, _ := runtime.Caller(0) 6324 curFileBaseName := filepath.Base(curFile) 6325 testFuncName := runtime.FuncForPC(pc).Name() 6326 6327 timeoutMsg := "timed out here!" 6328 6329 tests := []struct { 6330 name string 6331 mustTimeout bool 6332 wantResp string 6333 }{ 6334 { 6335 name: "return before timeout", 6336 wantResp: "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n", 6337 }, 6338 { 6339 name: "return after timeout", 6340 mustTimeout: true, 6341 wantResp: fmt.Sprintf("HTTP/1.1 503 Service Unavailable\r\nContent-Length: %d\r\n\r\n%s", 6342 len(timeoutMsg), timeoutMsg), 6343 }, 6344 } 6345 6346 for _, tt := range tests { 6347 tt := tt 6348 t.Run(tt.name, func(t *testing.T) { 6349 exitHandler := make(chan bool, 1) 6350 defer close(exitHandler) 6351 lastLine := make(chan int, 1) 6352 6353 sh := HandlerFunc(func(w ResponseWriter, r *Request) { 6354 w.WriteHeader(404) 6355 w.WriteHeader(404) 6356 w.WriteHeader(404) 6357 w.WriteHeader(404) 6358 _, _, line, _ := runtime.Caller(0) 6359 lastLine <- line 6360 <-exitHandler 6361 }) 6362 6363 if !tt.mustTimeout { 6364 exitHandler <- true 6365 } 6366 6367 logBuf := new(bytes.Buffer) 6368 srvLog := log.New(logBuf, "", 0) 6369 // When expecting to timeout, we'll keep the duration short. 6370 dur := 20 * time.Millisecond 6371 if !tt.mustTimeout { 6372 // Otherwise, make it arbitrarily long to reduce the risk of flakes. 6373 dur = 10 * time.Second 6374 } 6375 th := TimeoutHandler(sh, dur, timeoutMsg) 6376 cst := newClientServerTest(t, h1Mode /* the test is protocol-agnostic */, th, optWithServerLog(srvLog)) 6377 defer cst.close() 6378 6379 res, err := cst.c.Get(cst.ts.URL) 6380 if err != nil { 6381 t.Fatalf("Unexpected error: %v", err) 6382 } 6383 6384 // Deliberately removing the "Date" header since it is highly ephemeral 6385 // and will cause failure if we try to match it exactly. 6386 res.Header.Del("Date") 6387 res.Header.Del("Content-Type") 6388 6389 // Match the response. 6390 blob, _ := httputil.DumpResponse(res, true) 6391 if g, w := string(blob), tt.wantResp; g != w { 6392 t.Errorf("Response mismatch\nGot\n%q\n\nWant\n%q", g, w) 6393 } 6394 6395 // Given 4 w.WriteHeader calls, only the first one is valid 6396 // and the rest should be reported as the 3 spurious logs. 6397 logEntries := strings.Split(strings.TrimSpace(logBuf.String()), "\n") 6398 if g, w := len(logEntries), 3; g != w { 6399 blob, _ := json.MarshalIndent(logEntries, "", " ") 6400 t.Fatalf("Server logs count mismatch\ngot %d, want %d\n\nGot\n%s\n", g, w, blob) 6401 } 6402 6403 lastSpuriousLine := <-lastLine 6404 firstSpuriousLine := lastSpuriousLine - 3 6405 // Now ensure that the regexes match exactly. 6406 // "http: superfluous response.WriteHeader call from <fn>.func\d.\d (<curFile>:lastSpuriousLine-[1, 3]" 6407 for i, logEntry := range logEntries { 6408 wantLine := firstSpuriousLine + i 6409 pat := fmt.Sprintf("^http: superfluous response.WriteHeader call from %s.func\\d+.\\d+ \\(%s:%d\\)$", 6410 testFuncName, curFileBaseName, wantLine) 6411 re := regexp.MustCompile(pat) 6412 if !re.MatchString(logEntry) { 6413 t.Errorf("Log entry mismatch\n\t%s\ndoes not match\n\t%s", logEntry, pat) 6414 } 6415 } 6416 }) 6417 } 6418 } 6419 6420 // fetchWireResponse is a helper for dialing to host, 6421 // sending http1ReqBody as the payload and retrieving 6422 // the response as it was sent on the wire. 6423 func fetchWireResponse(host string, http1ReqBody []byte) ([]byte, error) { 6424 conn, err := net.Dial("tcp", host) 6425 if err != nil { 6426 return nil, err 6427 } 6428 defer conn.Close() 6429 6430 if _, err := conn.Write(http1ReqBody); err != nil { 6431 return nil, err 6432 } 6433 return ioutil.ReadAll(conn) 6434 } 6435 6436 func BenchmarkResponseStatusLine(b *testing.B) { 6437 b.ReportAllocs() 6438 b.RunParallel(func(pb *testing.PB) { 6439 bw := bufio.NewWriter(ioutil.Discard) 6440 var buf3 [3]byte 6441 for pb.Next() { 6442 Export_writeStatusLine(bw, true, 200, buf3[:]) 6443 } 6444 }) 6445 }