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