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