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