gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/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/zhaochuninhefei/gmgo/gmhttp" 39 "gitee.com/zhaochuninhefei/gmgo/gmhttp/httptest" 40 "gitee.com/zhaochuninhefei/gmgo/gmhttp/httputil" 41 "gitee.com/zhaochuninhefei/gmgo/gmhttp/internal" 42 "gitee.com/zhaochuninhefei/gmgo/gmhttp/internal/testcert" 43 tls "gitee.com/zhaochuninhefei/gmgo/gmtls" 44 "gitee.com/zhaochuninhefei/gmgo/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 //goland:noinspection HttpUrlsUsage 2634 func TestRedirect(t *testing.T) { 2635 req, _ := NewRequest("GET", "http://example.com/qux/", nil) 2636 2637 var tests = []struct { 2638 in string 2639 want string 2640 }{ 2641 // normal http 2642 {"http://foobar.com/baz", "http://foobar.com/baz"}, 2643 // normal https 2644 {"https://foobar.com/baz", "https://foobar.com/baz"}, 2645 // custom scheme 2646 {"test://foobar.com/baz", "test://foobar.com/baz"}, 2647 // schemeless 2648 {"//foobar.com/baz", "//foobar.com/baz"}, 2649 // relative to the root 2650 {"/foobar.com/baz", "/foobar.com/baz"}, 2651 // relative to the current path 2652 {"foobar.com/baz", "/qux/foobar.com/baz"}, 2653 // relative to the current path (+ going upwards) 2654 {"../quux/foobar.com/baz", "/quux/foobar.com/baz"}, 2655 // incorrect number of slashes 2656 {"///foobar.com/baz", "/foobar.com/baz"}, 2657 2658 // Verifies we don't path.Clean() on the wrong parts in redirects: 2659 {"/foo?next=http://bar.com/", "/foo?next=http://bar.com/"}, 2660 {"http://localhost:8080/_ah/login?continue=http://localhost:8080/", 2661 "http://localhost:8080/_ah/login?continue=http://localhost:8080/"}, 2662 2663 {"/фубар", "/%d1%84%d1%83%d0%b1%d0%b0%d1%80"}, 2664 {"http://foo.com/фубар", "http://foo.com/%d1%84%d1%83%d0%b1%d0%b0%d1%80"}, 2665 } 2666 2667 for _, tt := range tests { 2668 rec := httptest.NewRecorder() 2669 Redirect(rec, req, tt.in, 302) 2670 if got, want := rec.Code, 302; got != want { 2671 t.Errorf("Redirect(%q) generated status code %v; want %v", tt.in, got, want) 2672 } 2673 if got := rec.Header().Get("Location"); got != tt.want { 2674 t.Errorf("Redirect(%q) generated Location header %q; want %q", tt.in, got, tt.want) 2675 } 2676 } 2677 } 2678 2679 // Test that Redirect sets Content-Type header for GET and HEAD requests 2680 // and writes a short HTML body, unless the request already has a Content-Type header. 2681 //goland:noinspection HttpUrlsUsage 2682 func TestRedirectContentTypeAndBody(t *testing.T) { 2683 type ctHeader struct { 2684 Values []string 2685 } 2686 2687 var tests = []struct { 2688 method string 2689 ct *ctHeader // Optional Content-Type header to set. 2690 wantCT string 2691 wantBody string 2692 }{ 2693 {MethodGet, nil, "text/html; charset=utf-8", "<a href=\"/foo\">Found</a>.\n\n"}, 2694 {MethodHead, nil, "text/html; charset=utf-8", ""}, 2695 {MethodPost, nil, "", ""}, 2696 {MethodDelete, nil, "", ""}, 2697 {"foo", nil, "", ""}, 2698 {MethodGet, &ctHeader{[]string{"application/test"}}, "application/test", ""}, 2699 {MethodGet, &ctHeader{[]string{}}, "", ""}, 2700 {MethodGet, &ctHeader{nil}, "", ""}, 2701 } 2702 for _, tt := range tests { 2703 req := httptest.NewRequest(tt.method, "http://example.com/qux/", nil) 2704 rec := httptest.NewRecorder() 2705 if tt.ct != nil { 2706 rec.Header()["Content-Type"] = tt.ct.Values 2707 } 2708 Redirect(rec, req, "/foo", 302) 2709 if got, want := rec.Code, 302; got != want { 2710 t.Errorf("Redirect(%q, %#v) generated status code %v; want %v", tt.method, tt.ct, got, want) 2711 } 2712 if got, want := rec.Header().Get("Content-Type"), tt.wantCT; got != want { 2713 t.Errorf("Redirect(%q, %#v) generated Content-Type header %q; want %q", tt.method, tt.ct, got, want) 2714 } 2715 resp := rec.Result() 2716 body, err := io.ReadAll(resp.Body) 2717 if err != nil { 2718 t.Fatal(err) 2719 } 2720 if got, want := string(body), tt.wantBody; got != want { 2721 t.Errorf("Redirect(%q, %#v) generated Body %q; want %q", tt.method, tt.ct, got, want) 2722 } 2723 } 2724 } 2725 2726 // TestZeroLengthPostAndResponse exercises an optimization done by the Transport: 2727 // when there is no body (either because the method doesn't permit a body, or an 2728 // explicit Content-Length of zero is present), then the transport can re-use the 2729 // connection immediately. But when it re-uses the connection, it typically closes 2730 // the previous request's body, which is not optimal for zero-lengthed bodies, 2731 // as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF. 2732 func TestZeroLengthPostAndResponse_h1(t *testing.T) { 2733 testZeroLengthPostAndResponse(t, h1Mode) 2734 } 2735 func TestZeroLengthPostAndResponse_h2(t *testing.T) { 2736 testZeroLengthPostAndResponse(t, h2Mode) 2737 } 2738 2739 func testZeroLengthPostAndResponse(t *testing.T, h2 bool) { 2740 setParallel(t) 2741 defer afterTest(t) 2742 cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, r *Request) { 2743 all, err := io.ReadAll(r.Body) 2744 if err != nil { 2745 t.Fatalf("handler ReadAll: %v", err) 2746 } 2747 if len(all) != 0 { 2748 t.Errorf("handler got %d bytes; expected 0", len(all)) 2749 } 2750 rw.Header().Set("Content-Length", "0") 2751 })) 2752 defer cst.close() 2753 2754 req, err := NewRequest("POST", cst.ts.URL, strings.NewReader("")) 2755 if err != nil { 2756 t.Fatal(err) 2757 } 2758 req.ContentLength = 0 2759 2760 var resp [5]*Response 2761 for i := range resp { 2762 resp[i], err = cst.c.Do(req) 2763 if err != nil { 2764 t.Fatalf("client post #%d: %v", i, err) 2765 } 2766 } 2767 2768 for i := range resp { 2769 all, err := io.ReadAll(resp[i].Body) 2770 if err != nil { 2771 t.Fatalf("req #%d: client ReadAll: %v", i, err) 2772 } 2773 if len(all) != 0 { 2774 t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all)) 2775 } 2776 } 2777 } 2778 2779 func TestHandlerPanicNil_h1(t *testing.T) { testHandlerPanic(t, false, h1Mode, nil, nil) } 2780 func TestHandlerPanicNil_h2(t *testing.T) { testHandlerPanic(t, false, h2Mode, nil, nil) } 2781 2782 func TestHandlerPanic_h1(t *testing.T) { 2783 testHandlerPanic(t, false, h1Mode, nil, "intentional death for testing") 2784 } 2785 func TestHandlerPanic_h2(t *testing.T) { 2786 testHandlerPanic(t, false, h2Mode, nil, "intentional death for testing") 2787 } 2788 2789 func TestHandlerPanicWithHijack(t *testing.T) { 2790 // Only testing HTTP/1, and our http2 server doesn't support hijacking. 2791 testHandlerPanic(t, true, h1Mode, nil, "intentional death for testing") 2792 } 2793 2794 func testHandlerPanic(t *testing.T, withHijack, h2 bool, wrapper func(Handler) Handler, panicValue interface{}) { 2795 defer afterTest(t) 2796 // Unlike the other tests that set the log output to io.Discard 2797 // to quiet the output, this test uses a pipe. The pipe serves three 2798 // purposes: 2799 // 2800 // 1) The log.Print from the http server (generated by the caught 2801 // panic) will go to the pipe instead of stderr, making the 2802 // output quiet. 2803 // 2804 // 2) We read from the pipe to verify that the handler 2805 // actually caught the panic and logged something. 2806 // 2807 // 3) The blocking Read call prevents this TestHandlerPanic 2808 // function from exiting before the HTTP server handler 2809 // finishes crashing. If this text function exited too 2810 // early (and its defer log.SetOutput(os.Stderr) ran), 2811 // then the crash output could spill into the next test. 2812 pr, pw := io.Pipe() 2813 log.SetOutput(pw) 2814 defer log.SetOutput(os.Stderr) 2815 defer func(pw *io.PipeWriter) { 2816 _ = pw.Close() 2817 }(pw) 2818 2819 var handler Handler = HandlerFunc(func(w ResponseWriter, r *Request) { 2820 if withHijack { 2821 rwc, _, err := w.(Hijacker).Hijack() 2822 if err != nil { 2823 t.Logf("unexpected error: %v", err) 2824 } 2825 defer func(rwc net.Conn) { 2826 _ = rwc.Close() 2827 }(rwc) 2828 } 2829 panic(panicValue) 2830 }) 2831 if wrapper != nil { 2832 handler = wrapper(handler) 2833 } 2834 cst := newClientServerTest(t, h2, handler) 2835 defer cst.close() 2836 2837 // Do a blocking read on the log output pipe so its logging 2838 // doesn't bleed into the next test. But wait only 5 seconds 2839 // for it. 2840 done := make(chan bool, 1) 2841 go func() { 2842 buf := make([]byte, 4<<10) 2843 _, err := pr.Read(buf) 2844 _ = pr.Close() 2845 if err != nil && err != io.EOF { 2846 t.Error(err) 2847 } 2848 done <- true 2849 }() 2850 2851 _, err := cst.c.Get(cst.ts.URL) 2852 if err == nil { 2853 t.Logf("expected an error") 2854 } 2855 2856 if panicValue == nil { 2857 return 2858 } 2859 2860 select { 2861 case <-done: 2862 return 2863 case <-time.After(5 * time.Second): 2864 t.Fatal("expected server handler to log an error") 2865 } 2866 } 2867 2868 type terrorWriter struct{ t *testing.T } 2869 2870 func (w terrorWriter) Write(p []byte) (int, error) { 2871 w.t.Errorf("%s", p) 2872 return len(p), nil 2873 } 2874 2875 // Issue 16456: allow writing 0 bytes on hijacked conn to test hijack 2876 // without any log spam. 2877 func TestServerWriteHijackZeroBytes(t *testing.T) { 2878 defer afterTest(t) 2879 done := make(chan struct{}) 2880 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2881 defer close(done) 2882 w.(Flusher).Flush() 2883 conn, _, err := w.(Hijacker).Hijack() 2884 if err != nil { 2885 t.Errorf("Hijack: %v", err) 2886 return 2887 } 2888 defer func(conn net.Conn) { 2889 _ = conn.Close() 2890 }(conn) 2891 _, err = w.Write(nil) 2892 if err != ErrHijacked { 2893 t.Errorf("Write error = %v; want ErrHijacked", err) 2894 } 2895 })) 2896 ts.Config.ErrorLog = log.New(terrorWriter{t}, "Unexpected write: ", 0) 2897 ts.Start() 2898 defer ts.Close() 2899 2900 c := ts.Client() 2901 res, err := c.Get(ts.URL) 2902 if err != nil { 2903 t.Fatal(err) 2904 } 2905 _ = res.Body.Close() 2906 select { 2907 case <-done: 2908 case <-time.After(5 * time.Second): 2909 t.Fatal("timeout") 2910 } 2911 } 2912 2913 func TestServerNoDate_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Date") } 2914 func TestServerNoDate_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Date") } 2915 func TestServerNoContentType_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Content-Type") } 2916 func TestServerNoContentType_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Content-Type") } 2917 2918 func testServerNoHeader(t *testing.T, h2 bool, header string) { 2919 setParallel(t) 2920 defer afterTest(t) 2921 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 2922 w.Header()[header] = nil 2923 _, _ = io.WriteString(w, "<html>foo</html>") // non-empty 2924 })) 2925 defer cst.close() 2926 res, err := cst.c.Get(cst.ts.URL) 2927 if err != nil { 2928 t.Fatal(err) 2929 } 2930 _ = res.Body.Close() 2931 if got, ok := res.Header[header]; ok { 2932 t.Fatalf("Expected no %s header; got %q", header, got) 2933 } 2934 } 2935 2936 func TestStripPrefix(t *testing.T) { 2937 setParallel(t) 2938 defer afterTest(t) 2939 h := HandlerFunc(func(w ResponseWriter, r *Request) { 2940 w.Header().Set("X-Path", r.URL.Path) 2941 w.Header().Set("X-RawPath", r.URL.RawPath) 2942 }) 2943 ts := httptest.NewServer(StripPrefix("/foo/bar", h)) 2944 defer ts.Close() 2945 2946 c := ts.Client() 2947 2948 cases := []struct { 2949 reqPath string 2950 path string // If empty we want a 404. 2951 rawPath string 2952 }{ 2953 {"/foo/bar/qux", "/qux", ""}, 2954 {"/foo/bar%2Fqux", "/qux", "%2Fqux"}, 2955 {"/foo%2Fbar/qux", "", ""}, // Escaped prefix does not match. 2956 {"/bar", "", ""}, // No prefix match. 2957 } 2958 for _, tc := range cases { 2959 t.Run(tc.reqPath, func(t *testing.T) { 2960 res, err := c.Get(ts.URL + tc.reqPath) 2961 if err != nil { 2962 t.Fatal(err) 2963 } 2964 _ = res.Body.Close() 2965 if tc.path == "" { 2966 if res.StatusCode != StatusNotFound { 2967 t.Errorf("got %q, want 404 Not Found", res.Status) 2968 } 2969 return 2970 } 2971 if res.StatusCode != StatusOK { 2972 t.Fatalf("got %q, want 200 OK", res.Status) 2973 } 2974 if g, w := res.Header.Get("X-Path"), tc.path; g != w { 2975 t.Errorf("got Path %q, want %q", g, w) 2976 } 2977 if g, w := res.Header.Get("X-RawPath"), tc.rawPath; g != w { 2978 t.Errorf("got RawPath %q, want %q", g, w) 2979 } 2980 }) 2981 } 2982 } 2983 2984 // https://golang.org/issue/18952. 2985 func TestStripPrefixNotModifyRequest(t *testing.T) { 2986 h := StripPrefix("/foo", NotFoundHandler()) 2987 req := httptest.NewRequest("GET", "/foo/bar", nil) 2988 h.ServeHTTP(httptest.NewRecorder(), req) 2989 if req.URL.Path != "/foo/bar" { 2990 t.Errorf("StripPrefix should not modify the provided Request, but it did") 2991 } 2992 } 2993 2994 func TestRequestLimit_h1(t *testing.T) { testRequestLimit(t, h1Mode) } 2995 func TestRequestLimit_h2(t *testing.T) { testRequestLimit(t, h2Mode) } 2996 func testRequestLimit(t *testing.T, h2 bool) { 2997 setParallel(t) 2998 defer afterTest(t) 2999 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 3000 t.Fatalf("didn't expect to get request in Handler") 3001 }), optQuietLog) 3002 defer cst.close() 3003 req, _ := NewRequest("GET", cst.ts.URL, nil) 3004 var bytesPerHeader = len("header12345: val12345\r\n") 3005 for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ { 3006 req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i)) 3007 } 3008 res, err := cst.c.Do(req) 3009 if res != nil { 3010 defer func(Body io.ReadCloser) { 3011 _ = Body.Close() 3012 }(res.Body) 3013 } 3014 if h2 { 3015 // In HTTP/2, the result depends on a race. If the client has received the 3016 // server's SETTINGS before RoundTrip starts sending the request, then RoundTrip 3017 // will fail with an error. Otherwise, the client should receive a 431 from the 3018 // server. 3019 if err == nil && res.StatusCode != 431 { 3020 t.Fatalf("expected 431 response status; got: %d %s", res.StatusCode, res.Status) 3021 } 3022 } else { 3023 // In HTTP/1, we expect a 431 from the server. 3024 // Some HTTP clients may fail on this undefined behavior (server replying and 3025 // closing the connection while the request is still being written), but 3026 // we do support it (at least currently), so we expect a response below. 3027 if err != nil { 3028 t.Fatalf("Do: %v", err) 3029 } 3030 if res.StatusCode != 431 { 3031 t.Fatalf("expected 431 response status; got: %d %s", res.StatusCode, res.Status) 3032 } 3033 } 3034 } 3035 3036 type neverEnding byte 3037 3038 func (b neverEnding) Read(p []byte) (n int, err error) { 3039 for i := range p { 3040 p[i] = byte(b) 3041 } 3042 return len(p), nil 3043 } 3044 3045 type countReader struct { 3046 r io.Reader 3047 n *int64 3048 } 3049 3050 func (cr countReader) Read(p []byte) (n int, err error) { 3051 n, err = cr.r.Read(p) 3052 atomic.AddInt64(cr.n, int64(n)) 3053 return 3054 } 3055 3056 func TestRequestBodyLimit_h1(t *testing.T) { testRequestBodyLimit(t, h1Mode) } 3057 func TestRequestBodyLimit_h2(t *testing.T) { testRequestBodyLimit(t, h2Mode) } 3058 func testRequestBodyLimit(t *testing.T, h2 bool) { 3059 setParallel(t) 3060 defer afterTest(t) 3061 const limit = 1 << 20 3062 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 3063 r.Body = MaxBytesReader(w, r.Body, limit) 3064 n, err := io.Copy(io.Discard, r.Body) 3065 if err == nil { 3066 t.Errorf("expected error from io.Copy") 3067 } 3068 if n != limit { 3069 t.Errorf("io.Copy = %d, want %d", n, limit) 3070 } 3071 })) 3072 defer cst.close() 3073 3074 nWritten := new(int64) 3075 req, _ := NewRequest("POST", cst.ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200)) 3076 3077 // Send the POST, but don't care it succeeds or not. The 3078 // remote side is going to reply and then close the TCP 3079 // connection, and HTTP doesn't really define if that's 3080 // allowed or not. Some HTTP clients will get the response 3081 // and some (like ours, currently) will complain that the 3082 // request write failed, without reading the response. 3083 // 3084 // But that's okay, since what we're really testing is that 3085 // the remote side hung up on us before we wrote too much. 3086 _, _ = cst.c.Do(req) 3087 3088 if atomic.LoadInt64(nWritten) > limit*100 { 3089 t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d", 3090 limit, nWritten) 3091 } 3092 } 3093 3094 // TestClientWriteShutdown tests that if the client shuts down the write 3095 // side of their TCP connection, the server doesn't send a 400 Bad Request. 3096 func TestClientWriteShutdown(t *testing.T) { 3097 if runtime.GOOS == "plan9" { 3098 t.Skip("skipping test; see https://golang.org/issue/17906") 3099 } 3100 defer afterTest(t) 3101 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 3102 defer ts.Close() 3103 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3104 if err != nil { 3105 t.Fatalf("Dial: %v", err) 3106 } 3107 err = conn.(*net.TCPConn).CloseWrite() 3108 if err != nil { 3109 t.Fatalf("CloseWrite: %v", err) 3110 } 3111 donec := make(chan bool) 3112 go func() { 3113 defer close(donec) 3114 bs, err := io.ReadAll(conn) 3115 if err != nil { 3116 t.Errorf("ReadAll: %v", err) 3117 } 3118 got := string(bs) 3119 if got != "" { 3120 t.Errorf("read %q from server; want nothing", got) 3121 } 3122 }() 3123 select { 3124 case <-donec: 3125 case <-time.After(10 * time.Second): 3126 t.Fatalf("timeout") 3127 } 3128 } 3129 3130 // Tests that chunked server responses that write 1 byte at a time are 3131 // buffered before chunk headers are added, not after chunk headers. 3132 func TestServerBufferedChunking(t *testing.T) { 3133 conn := new(testConn) 3134 conn.readBuf.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")) 3135 conn.closec = make(chan bool, 1) 3136 ls := &oneConnListener{conn} 3137 go func() { 3138 _ = Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 3139 rw.(Flusher).Flush() // force the Header to be sent, in chunking mode, not counting the length 3140 _, _ = rw.Write([]byte{'x'}) 3141 _, _ = rw.Write([]byte{'y'}) 3142 _, _ = rw.Write([]byte{'z'}) 3143 })) 3144 }() 3145 <-conn.closec 3146 if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) { 3147 t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q", 3148 conn.writeBuf.Bytes()) 3149 } 3150 } 3151 3152 // Tests that the server flushes its response headers out when it's 3153 // ignoring the response body and waits a bit before forcefully 3154 // closing the TCP connection, causing the client to get a RST. 3155 // See https://golang.org/issue/3595 3156 func TestServerGracefulClose(t *testing.T) { 3157 setParallel(t) 3158 defer afterTest(t) 3159 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3160 Error(w, "bye", StatusUnauthorized) 3161 })) 3162 defer ts.Close() 3163 3164 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3165 if err != nil { 3166 t.Fatal(err) 3167 } 3168 defer func(conn net.Conn) { 3169 _ = conn.Close() 3170 }(conn) 3171 const bodySize = 5 << 20 3172 req := []byte(fmt.Sprintf("POST / HTTP/1.1\r\nHost: foo.com\r\nContent-Length: %d\r\n\r\n", bodySize)) 3173 for i := 0; i < bodySize; i++ { 3174 req = append(req, 'x') 3175 } 3176 writeErr := make(chan error) 3177 go func() { 3178 _, err := conn.Write(req) 3179 writeErr <- err 3180 }() 3181 br := bufio.NewReader(conn) 3182 lineNum := 0 3183 for { 3184 line, err := br.ReadString('\n') 3185 if err == io.EOF { 3186 break 3187 } 3188 if err != nil { 3189 t.Fatalf("ReadLine: %v", err) 3190 } 3191 lineNum++ 3192 if lineNum == 1 && !strings.Contains(line, "401 Unauthorized") { 3193 t.Errorf("Response line = %q; want a 401", line) 3194 } 3195 } 3196 // Wait for write to finish. This is a broken pipe on both 3197 // Darwin and Linux, but checking this isn't the point of 3198 // the test. 3199 <-writeErr 3200 } 3201 3202 func TestCaseSensitiveMethod_h1(t *testing.T) { testCaseSensitiveMethod(t, h1Mode) } 3203 func TestCaseSensitiveMethod_h2(t *testing.T) { testCaseSensitiveMethod(t, h2Mode) } 3204 func testCaseSensitiveMethod(t *testing.T, h2 bool) { 3205 defer afterTest(t) 3206 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 3207 if r.Method != "get" { 3208 t.Errorf(`Got method %q; want "get"`, r.Method) 3209 } 3210 })) 3211 defer cst.close() 3212 req, _ := NewRequest("get", cst.ts.URL, nil) 3213 res, err := cst.c.Do(req) 3214 if err != nil { 3215 t.Error(err) 3216 return 3217 } 3218 3219 _ = res.Body.Close() 3220 } 3221 3222 // TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1 3223 // request (both keep-alive), when a Handler never writes any 3224 // response, the net/http package adds a "Content-Length: 0" response 3225 // header. 3226 func TestContentLengthZero(t *testing.T) { 3227 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {})) 3228 defer ts.Close() 3229 3230 for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} { 3231 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3232 if err != nil { 3233 t.Fatalf("error dialing: %v", err) 3234 } 3235 _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version) 3236 if err != nil { 3237 t.Fatalf("error writing: %v", err) 3238 } 3239 req, _ := NewRequest("GET", "/", nil) 3240 res, err := ReadResponse(bufio.NewReader(conn), req) 3241 if err != nil { 3242 t.Fatalf("error reading response: %v", err) 3243 } 3244 if te := res.TransferEncoding; len(te) > 0 { 3245 t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te) 3246 } 3247 if cl := res.ContentLength; cl != 0 { 3248 t.Errorf("For version %q, Content-Length = %v; want 0", version, cl) 3249 } 3250 _ = conn.Close() 3251 } 3252 } 3253 3254 func TestCloseNotifier(t *testing.T) { 3255 defer afterTest(t) 3256 gotReq := make(chan bool, 1) 3257 sawClose := make(chan bool, 1) 3258 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 3259 gotReq <- true 3260 cc := rw.(CloseNotifier).CloseNotify() 3261 <-cc 3262 sawClose <- true 3263 })) 3264 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3265 if err != nil { 3266 t.Fatalf("error dialing: %v", err) 3267 } 3268 diec := make(chan bool) 3269 go func() { 3270 _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n") 3271 if err != nil { 3272 t.Error(err) 3273 return 3274 } 3275 <-diec 3276 _ = conn.Close() 3277 }() 3278 For: 3279 for { 3280 select { 3281 case <-gotReq: 3282 diec <- true 3283 case <-sawClose: 3284 break For 3285 case <-time.After(5 * time.Second): 3286 t.Fatal("timeout") 3287 } 3288 } 3289 ts.Close() 3290 } 3291 3292 // Tests that a pipelined request does not cause the first request's 3293 // Handler's CloseNotify channel to fire. 3294 // 3295 // Issue 13165 (where it used to deadlock), but behavior changed in Issue 23921. 3296 func TestCloseNotifierPipelined(t *testing.T) { 3297 setParallel(t) 3298 defer afterTest(t) 3299 gotReq := make(chan bool, 2) 3300 sawClose := make(chan bool, 2) 3301 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 3302 gotReq <- true 3303 cc := rw.(CloseNotifier).CloseNotify() 3304 select { 3305 case <-cc: 3306 t.Error("unexpected CloseNotify") 3307 case <-time.After(100 * time.Millisecond): 3308 } 3309 sawClose <- true 3310 })) 3311 defer ts.Close() 3312 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3313 if err != nil { 3314 t.Fatalf("error dialing: %v", err) 3315 } 3316 diec := make(chan bool, 1) 3317 defer close(diec) 3318 go func() { 3319 const req = "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n" 3320 _, err = io.WriteString(conn, req+req) // two requests 3321 if err != nil { 3322 t.Error(err) 3323 return 3324 } 3325 <-diec 3326 _ = conn.Close() 3327 }() 3328 reqs := 0 3329 closes := 0 3330 for { 3331 select { 3332 case <-gotReq: 3333 reqs++ 3334 if reqs > 2 { 3335 t.Fatal("too many requests") 3336 } 3337 case <-sawClose: 3338 closes++ 3339 if closes > 1 { 3340 return 3341 } 3342 case <-time.After(5 * time.Second): 3343 ts.CloseClientConnections() 3344 t.Fatal("timeout") 3345 } 3346 } 3347 } 3348 3349 func TestCloseNotifierChanLeak(t *testing.T) { 3350 defer afterTest(t) 3351 req := reqBytes("GET / HTTP/1.0\nHost: golang.org") 3352 for i := 0; i < 20; i++ { 3353 var output bytes.Buffer 3354 conn := &rwTestConn{ 3355 Reader: bytes.NewReader(req), 3356 Writer: &output, 3357 closec: make(chan bool, 1), 3358 } 3359 ln := &oneConnListener{conn: conn} 3360 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3361 // Ignore the return value and never read from 3362 // it, testing that we don't leak goroutines 3363 // on the sending side: 3364 _ = rw.(CloseNotifier).CloseNotify() 3365 }) 3366 go func() { 3367 _ = Serve(ln, handler) 3368 }() 3369 <-conn.closec 3370 } 3371 } 3372 3373 // Tests that we can use CloseNotifier in one request, and later call Hijack 3374 // on a second request on the same connection. 3375 // 3376 // It also tests that the connReader stitches together its background 3377 // 1-byte read for CloseNotifier when CloseNotifier doesn't fire with 3378 // the rest of the second HTTP later. 3379 // 3380 // Issue 9763. 3381 // HTTP/1-only test. (http2 doesn't have Hijack) 3382 func TestHijackAfterCloseNotifier(t *testing.T) { 3383 defer afterTest(t) 3384 script := make(chan string, 2) 3385 script <- "closenotify" 3386 script <- "hijack" 3387 close(script) 3388 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3389 plan := <-script 3390 switch plan { 3391 default: 3392 panic("bogus plan; too many requests") 3393 case "closenotify": 3394 w.(CloseNotifier).CloseNotify() // discard result 3395 w.Header().Set("X-Addr", r.RemoteAddr) 3396 case "hijack": 3397 c, _, err := w.(Hijacker).Hijack() 3398 if err != nil { 3399 t.Errorf("Hijack in Handler: %v", err) 3400 return 3401 } 3402 if _, ok := c.(*net.TCPConn); !ok { 3403 // Verify it's not wrapped in some type. 3404 // Not strictly a go1 compat issue, but in practice it probably is. 3405 t.Errorf("type of hijacked conn is %T; want *net.TCPConn", c) 3406 } 3407 _, _ = fmt.Fprintf(c, "HTTP/1.0 200 OK\r\nX-Addr: %v\r\nContent-Length: 0\r\n\r\n", r.RemoteAddr) 3408 _ = c.Close() 3409 return 3410 } 3411 })) 3412 defer ts.Close() 3413 res1, err := Get(ts.URL) 3414 if err != nil { 3415 log.Fatal(err) 3416 } 3417 res2, err := Get(ts.URL) 3418 if err != nil { 3419 log.Fatal(err) 3420 } 3421 addr1 := res1.Header.Get("X-Addr") 3422 addr2 := res2.Header.Get("X-Addr") 3423 if addr1 == "" || addr1 != addr2 { 3424 t.Errorf("addr1, addr2 = %q, %q; want same", addr1, addr2) 3425 } 3426 } 3427 3428 func TestHijackBeforeRequestBodyRead(t *testing.T) { 3429 setParallel(t) 3430 defer afterTest(t) 3431 var requestBody = bytes.Repeat([]byte("a"), 1<<20) 3432 bodyOkay := make(chan bool, 1) 3433 gotCloseNotify := make(chan bool, 1) 3434 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3435 defer close(bodyOkay) // caller will read false if nothing else 3436 3437 reqBody := r.Body 3438 r.Body = nil // to test that server.go doesn't use this value. 3439 3440 gone := w.(CloseNotifier).CloseNotify() 3441 slurp, err := io.ReadAll(reqBody) 3442 if err != nil { 3443 t.Errorf("Body read: %v", err) 3444 return 3445 } 3446 if len(slurp) != len(requestBody) { 3447 t.Errorf("Backend read %d request body bytes; want %d", len(slurp), len(requestBody)) 3448 return 3449 } 3450 if !bytes.Equal(slurp, requestBody) { 3451 t.Error("Backend read wrong request body.") // 1MB; omitting details 3452 return 3453 } 3454 bodyOkay <- true 3455 select { 3456 case <-gone: 3457 gotCloseNotify <- true 3458 case <-time.After(5 * time.Second): 3459 gotCloseNotify <- false 3460 } 3461 })) 3462 defer ts.Close() 3463 3464 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3465 if err != nil { 3466 t.Fatal(err) 3467 } 3468 defer func(conn net.Conn) { 3469 _ = conn.Close() 3470 }(conn) 3471 3472 _, _ = fmt.Fprintf(conn, "POST / HTTP/1.1\r\nHost: foo\r\nContent-Length: %d\r\n\r\n%s", 3473 len(requestBody), requestBody) 3474 if !<-bodyOkay { 3475 // already failed. 3476 return 3477 } 3478 _ = conn.Close() 3479 if !<-gotCloseNotify { 3480 t.Error("timeout waiting for CloseNotify") 3481 } 3482 } 3483 3484 func TestOptions(t *testing.T) { 3485 uric := make(chan string, 2) // only expect 1, but leave space for 2 3486 mux := NewServeMux() 3487 mux.HandleFunc("/", func(w ResponseWriter, r *Request) { 3488 uric <- r.RequestURI 3489 }) 3490 ts := httptest.NewServer(mux) 3491 defer ts.Close() 3492 3493 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3494 if err != nil { 3495 t.Fatal(err) 3496 } 3497 defer func(conn net.Conn) { 3498 _ = conn.Close() 3499 }(conn) 3500 3501 // An OPTIONS * request should succeed. 3502 _, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n")) 3503 if err != nil { 3504 t.Fatal(err) 3505 } 3506 br := bufio.NewReader(conn) 3507 res, err := ReadResponse(br, &Request{Method: "OPTIONS"}) 3508 if err != nil { 3509 t.Fatal(err) 3510 } 3511 if res.StatusCode != 200 { 3512 t.Errorf("Got non-200 response to OPTIONS *: %#v", res) 3513 } 3514 3515 // A GET * request on a ServeMux should fail. 3516 _, err = conn.Write([]byte("GET * HTTP/1.1\r\nHost: foo.com\r\n\r\n")) 3517 if err != nil { 3518 t.Fatal(err) 3519 } 3520 res, err = ReadResponse(br, &Request{Method: "GET"}) 3521 if err != nil { 3522 t.Fatal(err) 3523 } 3524 if res.StatusCode != 400 { 3525 t.Errorf("Got non-400 response to GET *: %#v", res) 3526 } 3527 3528 res, err = Get(ts.URL + "/second") 3529 if err != nil { 3530 t.Fatal(err) 3531 } 3532 _ = res.Body.Close() 3533 if got := <-uric; got != "/second" { 3534 t.Errorf("Handler saw request for %q; want /second", got) 3535 } 3536 } 3537 3538 // Tests regarding the ordering of Write, WriteHeader, Header, and 3539 // Flush calls. In Go 1.0, rw.WriteHeader immediately flushed the 3540 // (*response).header to the wire. In Go 1.1, the actual wire flush is 3541 // delayed, so we could maybe tack on a Content-Length and better 3542 // Content-Type after we see more (or all) of the output. To preserve 3543 // compatibility with Go 1, we need to be careful to track which 3544 // headers were live at the time of WriteHeader, so we write the same 3545 // ones, even if the handler modifies them (~erroneously) after the 3546 // first Write. 3547 func TestHeaderToWire(t *testing.T) { 3548 tests := []struct { 3549 name string 3550 handler func(ResponseWriter, *Request) 3551 check func(got, logs string) error 3552 }{ 3553 { 3554 name: "write without Header", 3555 handler: func(rw ResponseWriter, r *Request) { 3556 _, _ = rw.Write([]byte("hello world")) 3557 }, 3558 check: func(got, logs string) error { 3559 if !strings.Contains(got, "Content-Length:") { 3560 return errors.New("no content-length") 3561 } 3562 if !strings.Contains(got, "Content-Type: text/plain") { 3563 return errors.New("no content-type") 3564 } 3565 return nil 3566 }, 3567 }, 3568 { 3569 name: "Header mutation before write", 3570 handler: func(rw ResponseWriter, r *Request) { 3571 h := rw.Header() 3572 h.Set("Content-Type", "some/type") 3573 _, _ = rw.Write([]byte("hello world")) 3574 h.Set("Too-Late", "bogus") 3575 }, 3576 check: func(got, logs string) error { 3577 if !strings.Contains(got, "Content-Length:") { 3578 return errors.New("no content-length") 3579 } 3580 if !strings.Contains(got, "Content-Type: some/type") { 3581 return errors.New("wrong content-type") 3582 } 3583 if strings.Contains(got, "Too-Late") { 3584 return errors.New("don't want too-late header") 3585 } 3586 return nil 3587 }, 3588 }, 3589 { 3590 name: "write then useless Header mutation", 3591 handler: func(rw ResponseWriter, r *Request) { 3592 _, _ = rw.Write([]byte("hello world")) 3593 rw.Header().Set("Too-Late", "Write already wrote headers") 3594 }, 3595 check: func(got, logs string) error { 3596 if strings.Contains(got, "Too-Late") { 3597 return errors.New("header appeared from after WriteHeader") 3598 } 3599 return nil 3600 }, 3601 }, 3602 { 3603 name: "flush then write", 3604 handler: func(rw ResponseWriter, r *Request) { 3605 rw.(Flusher).Flush() 3606 _, _ = rw.Write([]byte("post-flush")) 3607 rw.Header().Set("Too-Late", "Write already wrote headers") 3608 }, 3609 check: func(got, logs string) error { 3610 if !strings.Contains(got, "Transfer-Encoding: chunked") { 3611 return errors.New("not chunked") 3612 } 3613 if strings.Contains(got, "Too-Late") { 3614 return errors.New("header appeared from after WriteHeader") 3615 } 3616 return nil 3617 }, 3618 }, 3619 { 3620 name: "header then flush", 3621 handler: func(rw ResponseWriter, r *Request) { 3622 rw.Header().Set("Content-Type", "some/type") 3623 rw.(Flusher).Flush() 3624 _, _ = rw.Write([]byte("post-flush")) 3625 rw.Header().Set("Too-Late", "Write already wrote headers") 3626 }, 3627 check: func(got, logs string) error { 3628 if !strings.Contains(got, "Transfer-Encoding: chunked") { 3629 return errors.New("not chunked") 3630 } 3631 if strings.Contains(got, "Too-Late") { 3632 return errors.New("header appeared from after WriteHeader") 3633 } 3634 if !strings.Contains(got, "Content-Type: some/type") { 3635 return errors.New("wrong content-type") 3636 } 3637 return nil 3638 }, 3639 }, 3640 { 3641 name: "sniff-on-first-write content-type", 3642 handler: func(rw ResponseWriter, r *Request) { 3643 _, _ = rw.Write([]byte("<html><head></head><body>some html</body></html>")) 3644 rw.Header().Set("Content-Type", "x/wrong") 3645 }, 3646 check: func(got, logs string) error { 3647 if !strings.Contains(got, "Content-Type: text/html") { 3648 return errors.New("wrong content-type; want html") 3649 } 3650 return nil 3651 }, 3652 }, 3653 { 3654 name: "explicit content-type wins", 3655 handler: func(rw ResponseWriter, r *Request) { 3656 rw.Header().Set("Content-Type", "some/type") 3657 _, _ = rw.Write([]byte("<html><head></head><body>some html</body></html>")) 3658 }, 3659 check: func(got, logs string) error { 3660 if !strings.Contains(got, "Content-Type: some/type") { 3661 return errors.New("wrong content-type; want html") 3662 } 3663 return nil 3664 }, 3665 }, 3666 { 3667 name: "empty handler", 3668 handler: func(rw ResponseWriter, r *Request) { 3669 }, 3670 check: func(got, logs string) error { 3671 if !strings.Contains(got, "Content-Length: 0") { 3672 return errors.New("want 0 content-length") 3673 } 3674 return nil 3675 }, 3676 }, 3677 { 3678 name: "only Header, no write", 3679 handler: func(rw ResponseWriter, r *Request) { 3680 rw.Header().Set("Some-Header", "some-value") 3681 }, 3682 check: func(got, logs string) error { 3683 if !strings.Contains(got, "Some-Header") { 3684 return errors.New("didn't get header") 3685 } 3686 return nil 3687 }, 3688 }, 3689 { 3690 name: "WriteHeader call", 3691 handler: func(rw ResponseWriter, r *Request) { 3692 rw.WriteHeader(404) 3693 rw.Header().Set("Too-Late", "some-value") 3694 }, 3695 check: func(got, logs string) error { 3696 if !strings.Contains(got, "404") { 3697 return errors.New("wrong status") 3698 } 3699 if strings.Contains(got, "Too-Late") { 3700 return errors.New("shouldn't have seen Too-Late") 3701 } 3702 return nil 3703 }, 3704 }, 3705 } 3706 for _, tc := range tests { 3707 ht := newHandlerTest(HandlerFunc(tc.handler)) 3708 got := ht.rawResponse("GET / HTTP/1.1\nHost: golang.org") 3709 logs := ht.logbuf.String() 3710 if err := tc.check(got, logs); err != nil { 3711 t.Errorf("%s: %v\nGot response:\n%s\n\n%s", tc.name, err, got, logs) 3712 } 3713 } 3714 } 3715 3716 type errorListener struct { 3717 errs []error 3718 } 3719 3720 func (l *errorListener) Accept() (c net.Conn, err error) { 3721 if len(l.errs) == 0 { 3722 return nil, io.EOF 3723 } 3724 err = l.errs[0] 3725 l.errs = l.errs[1:] 3726 return 3727 } 3728 3729 func (l *errorListener) Close() error { 3730 return nil 3731 } 3732 3733 func (l *errorListener) Addr() net.Addr { 3734 return dummyAddr("test-address") 3735 } 3736 3737 func TestAcceptMaxFds(t *testing.T) { 3738 setParallel(t) 3739 3740 ln := &errorListener{[]error{ 3741 &net.OpError{ 3742 Op: "accept", 3743 Err: syscall.EMFILE, 3744 }}} 3745 server := &Server{ 3746 Handler: HandlerFunc(func(ResponseWriter, *Request) {}), 3747 ErrorLog: log.New(io.Discard, "", 0), // noisy otherwise 3748 } 3749 err := server.Serve(ln) 3750 if err != io.EOF { 3751 t.Errorf("got error %v, want EOF", err) 3752 } 3753 } 3754 3755 func TestWriteAfterHijack(t *testing.T) { 3756 req := reqBytes("GET / HTTP/1.1\nHost: golang.org") 3757 var buf bytes.Buffer 3758 wrotec := make(chan bool, 1) 3759 conn := &rwTestConn{ 3760 Reader: bytes.NewReader(req), 3761 Writer: &buf, 3762 closec: make(chan bool, 1), 3763 } 3764 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3765 conn, bufrw, err := rw.(Hijacker).Hijack() 3766 if err != nil { 3767 t.Error(err) 3768 return 3769 } 3770 go func() { 3771 _, _ = bufrw.Write([]byte("[hijack-to-bufw]")) 3772 _ = bufrw.Flush() 3773 _, _ = conn.Write([]byte("[hijack-to-conn]")) 3774 _ = conn.Close() 3775 wrotec <- true 3776 }() 3777 }) 3778 ln := &oneConnListener{conn: conn} 3779 go func() { 3780 _ = Serve(ln, handler) 3781 }() 3782 <-conn.closec 3783 <-wrotec 3784 if g, w := buf.String(), "[hijack-to-bufw][hijack-to-conn]"; g != w { 3785 t.Errorf("wrote %q; want %q", g, w) 3786 } 3787 } 3788 3789 func TestDoubleHijack(t *testing.T) { 3790 req := reqBytes("GET / HTTP/1.1\nHost: golang.org") 3791 var buf bytes.Buffer 3792 conn := &rwTestConn{ 3793 Reader: bytes.NewReader(req), 3794 Writer: &buf, 3795 closec: make(chan bool, 1), 3796 } 3797 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 3798 conn, _, err := rw.(Hijacker).Hijack() 3799 if err != nil { 3800 t.Error(err) 3801 return 3802 } 3803 _, _, err = rw.(Hijacker).Hijack() 3804 if err == nil { 3805 t.Errorf("got err = nil; want err != nil") 3806 } 3807 _ = conn.Close() 3808 }) 3809 ln := &oneConnListener{conn: conn} 3810 go func() { 3811 _ = Serve(ln, handler) 3812 }() 3813 <-conn.closec 3814 } 3815 3816 // https://golang.org/issue/5955 3817 // Note that this does not test the "request too large" 3818 // exit path from the http server. This is intentional; 3819 // not sending Connection: close is just a minor wire 3820 // optimization and is pointless if dealing with a 3821 // badly behaved client. 3822 func TestHTTP10ConnectionHeader(t *testing.T) { 3823 defer afterTest(t) 3824 3825 mux := NewServeMux() 3826 mux.Handle("/", HandlerFunc(func(ResponseWriter, *Request) {})) 3827 ts := httptest.NewServer(mux) 3828 defer ts.Close() 3829 3830 // net/http uses HTTP/1.1 for requests, so write requests manually 3831 tests := []struct { 3832 req string // raw http request 3833 expect []string // expected Connection header(s) 3834 }{ 3835 { 3836 req: "GET / HTTP/1.0\r\n\r\n", 3837 expect: nil, 3838 }, 3839 { 3840 req: "OPTIONS * HTTP/1.0\r\n\r\n", 3841 expect: nil, 3842 }, 3843 { 3844 req: "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", 3845 expect: []string{"keep-alive"}, 3846 }, 3847 } 3848 3849 for _, tt := range tests { 3850 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 3851 if err != nil { 3852 t.Fatal("dial err:", err) 3853 } 3854 3855 _, err = fmt.Fprint(conn, tt.req) 3856 if err != nil { 3857 t.Fatal("conn write err:", err) 3858 } 3859 3860 resp, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "GET"}) 3861 if err != nil { 3862 t.Fatal("ReadResponse err:", err) 3863 } 3864 _ = conn.Close() 3865 _ = resp.Body.Close() 3866 3867 got := resp.Header["Connection"] 3868 if !reflect.DeepEqual(got, tt.expect) { 3869 t.Errorf("wrong Connection headers for request %q. Got %q expect %q", tt.req, got, tt.expect) 3870 } 3871 } 3872 } 3873 3874 // See golang.org/issue/5660 3875 func TestServerReaderFromOrder_h1(t *testing.T) { testServerReaderFromOrder(t, h1Mode) } 3876 func TestServerReaderFromOrder_h2(t *testing.T) { testServerReaderFromOrder(t, h2Mode) } 3877 func testServerReaderFromOrder(t *testing.T, h2 bool) { 3878 setParallel(t) 3879 defer afterTest(t) 3880 pr, pw := io.Pipe() 3881 const size = 3 << 20 3882 cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) { 3883 rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path 3884 done := make(chan bool) 3885 go func() { 3886 _, _ = io.Copy(rw, pr) 3887 close(done) 3888 }() 3889 time.Sleep(25 * time.Millisecond) // give Copy a chance to break things 3890 n, err := io.Copy(io.Discard, req.Body) 3891 if err != nil { 3892 t.Errorf("handler Copy: %v", err) 3893 return 3894 } 3895 if n != size { 3896 t.Errorf("handler Copy = %d; want %d", n, size) 3897 } 3898 _, _ = pw.Write([]byte("hi")) 3899 _ = pw.Close() 3900 <-done 3901 })) 3902 defer cst.close() 3903 3904 req, err := NewRequest("POST", cst.ts.URL, io.LimitReader(neverEnding('a'), size)) 3905 if err != nil { 3906 t.Fatal(err) 3907 } 3908 res, err := cst.c.Do(req) 3909 if err != nil { 3910 t.Fatal(err) 3911 } 3912 all, err := io.ReadAll(res.Body) 3913 if err != nil { 3914 t.Fatal(err) 3915 } 3916 _ = res.Body.Close() 3917 if string(all) != "hi" { 3918 t.Errorf("Body = %q; want hi", all) 3919 } 3920 } 3921 3922 // Issue 6157, Issue 6685 3923 func TestCodesPreventingContentTypeAndBody(t *testing.T) { 3924 for _, code := range []int{StatusNotModified, StatusNoContent, StatusContinue} { 3925 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 3926 if r.URL.Path == "/header" { 3927 w.Header().Set("Content-Length", "123") 3928 } 3929 w.WriteHeader(code) 3930 if r.URL.Path == "/more" { 3931 _, _ = w.Write([]byte("stuff")) 3932 } 3933 })) 3934 for _, req := range []string{ 3935 "GET / HTTP/1.0", 3936 "GET /header HTTP/1.0", 3937 "GET /more HTTP/1.0", 3938 "GET / HTTP/1.1\nHost: foo", 3939 "GET /header HTTP/1.1\nHost: foo", 3940 "GET /more HTTP/1.1\nHost: foo", 3941 } { 3942 got := ht.rawResponse(req) 3943 wantStatus := fmt.Sprintf("%d %s", code, StatusText(code)) 3944 if !strings.Contains(got, wantStatus) { 3945 t.Errorf("Code %d: Wanted %q Modified for %q: %s", code, wantStatus, req, got) 3946 } else if strings.Contains(got, "Content-Length") { 3947 t.Errorf("Code %d: Got a Content-Length from %q: %s", code, req, got) 3948 } else if strings.Contains(got, "stuff") { 3949 t.Errorf("Code %d: Response contains a body from %q: %s", code, req, got) 3950 } 3951 } 3952 } 3953 } 3954 3955 func TestContentTypeOkayOn204(t *testing.T) { 3956 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 3957 w.Header().Set("Content-Length", "123") // suppressed 3958 w.Header().Set("Content-Type", "foo/bar") 3959 w.WriteHeader(204) 3960 })) 3961 got := ht.rawResponse("GET / HTTP/1.1\nHost: foo") 3962 if !strings.Contains(got, "Content-Type: foo/bar") { 3963 t.Errorf("Response = %q; want Content-Type: foo/bar", got) 3964 } 3965 if strings.Contains(got, "Content-Length: 123") { 3966 t.Errorf("Response = %q; don't want a Content-Length", got) 3967 } 3968 } 3969 3970 // Issue 6995 3971 // A server Handler can receive a Request, and then turn around and 3972 // give a copy of that Request.Body out to the Transport (e.g. any 3973 // proxy). So then two people own that Request.Body (both the server 3974 // and the http client), and both think they can close it on failure. 3975 // Therefore, all incoming server requests Bodies need to be thread-safe. 3976 func TestTransportAndServerSharedBodyRace_h1(t *testing.T) { 3977 testTransportAndServerSharedBodyRace(t, h1Mode) 3978 } 3979 func TestTransportAndServerSharedBodyRace_h2(t *testing.T) { 3980 testTransportAndServerSharedBodyRace(t, h2Mode) 3981 } 3982 func testTransportAndServerSharedBodyRace(t *testing.T, h2 bool) { 3983 setParallel(t) 3984 defer afterTest(t) 3985 3986 const bodySize = 1 << 20 3987 3988 // errorf is like t.Errorf, but also writes to println. When 3989 // this test fails, it hangs. This helps debugging and I've 3990 // added this enough times "temporarily". It now gets added 3991 // full time. 3992 errorf := func(format string, args ...interface{}) { 3993 v := fmt.Sprintf(format, args...) 3994 println(v) 3995 t.Error(v) 3996 } 3997 3998 unblockBackend := make(chan bool) 3999 backend := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) { 4000 gone := rw.(CloseNotifier).CloseNotify() 4001 didCopy := make(chan interface{}) 4002 go func() { 4003 n, err := io.CopyN(rw, req.Body, bodySize) 4004 didCopy <- []interface{}{n, err} 4005 }() 4006 isGone := false 4007 Loop: 4008 for { 4009 select { 4010 case <-didCopy: 4011 break Loop 4012 case <-gone: 4013 isGone = true 4014 case <-time.After(time.Second): 4015 println("1 second passes in backend, proxygone=", isGone) 4016 } 4017 } 4018 <-unblockBackend 4019 })) 4020 var quitTimer *time.Timer 4021 defer func() { quitTimer.Stop() }() 4022 defer backend.close() 4023 4024 backendRespc := make(chan *Response, 1) 4025 var proxy *clientServerTest 4026 proxy = newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) { 4027 req2, _ := NewRequest("POST", backend.ts.URL, req.Body) 4028 req2.ContentLength = bodySize 4029 cancel := make(chan struct{}) 4030 req2.Cancel = cancel 4031 4032 bresp, err := proxy.c.Do(req2) 4033 if err != nil { 4034 errorf("Proxy outbound request: %v", err) 4035 return 4036 } 4037 _, err = io.CopyN(io.Discard, bresp.Body, bodySize/2) 4038 if err != nil { 4039 errorf("Proxy copy error: %v", err) 4040 return 4041 } 4042 backendRespc <- bresp // to close later 4043 4044 // Try to cause a race: Both the Transport and the proxy handler's Server 4045 // will try to read/close req.Body (aka req2.Body) 4046 if h2 { 4047 close(cancel) 4048 } else { 4049 proxy.c.Transport.(*Transport).CancelRequest(req2) 4050 } 4051 _, _ = rw.Write([]byte("OK")) 4052 })) 4053 defer proxy.close() 4054 defer func() { 4055 // Before we shut down our two httptest.Servers, start a timer. 4056 // We choose 7 seconds because httptest.Server starts logging 4057 // warnings to stderr at 5 seconds. If we don't disarm this bomb 4058 // in 7 seconds (after the two httptest.Server.Close calls above), 4059 // then we explode with stacks. 4060 quitTimer = time.AfterFunc(7*time.Second, func() { 4061 debug.SetTraceback("ALL") 4062 stacks := make([]byte, 1<<20) 4063 stacks = stacks[:runtime.Stack(stacks, true)] 4064 _, _ = fmt.Fprintf(os.Stderr, "%s", stacks) 4065 log.Fatalf("Timeout.") 4066 }) 4067 }() 4068 4069 defer close(unblockBackend) 4070 req, _ := NewRequest("POST", proxy.ts.URL, io.LimitReader(neverEnding('a'), bodySize)) 4071 res, err := proxy.c.Do(req) 4072 if err != nil { 4073 t.Fatalf("Original request: %v", err) 4074 } 4075 4076 // Cleanup, so we don't leak goroutines. 4077 _ = res.Body.Close() 4078 select { 4079 case res := <-backendRespc: 4080 _ = res.Body.Close() 4081 default: 4082 // We failed earlier. (e.g. on proxy.c.Do(req2)) 4083 } 4084 } 4085 4086 // Test that a hanging Request.Body.Read from another goroutine can't 4087 // cause the Handler goroutine's Request.Body.Close to block. 4088 // See issue 7121. 4089 func TestRequestBodyCloseDoesntBlock(t *testing.T) { 4090 if testing.Short() { 4091 t.Skip("skipping in -short mode") 4092 } 4093 defer afterTest(t) 4094 4095 readErrCh := make(chan error, 1) 4096 errCh := make(chan error, 2) 4097 4098 server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 4099 go func(body io.Reader) { 4100 _, err := body.Read(make([]byte, 100)) 4101 readErrCh <- err 4102 }(req.Body) 4103 time.Sleep(500 * time.Millisecond) 4104 })) 4105 defer server.Close() 4106 4107 closeConn := make(chan bool) 4108 defer close(closeConn) 4109 go func() { 4110 conn, err := net.Dial("tcp", server.Listener.Addr().String()) 4111 if err != nil { 4112 errCh <- err 4113 return 4114 } 4115 defer func(conn net.Conn) { 4116 _ = conn.Close() 4117 }(conn) 4118 _, err = conn.Write([]byte("POST / HTTP/1.1\r\nConnection: close\r\nHost: foo\r\nContent-Length: 100000\r\n\r\n")) 4119 if err != nil { 4120 errCh <- err 4121 return 4122 } 4123 // And now just block, making the server block on our 4124 // 100000 bytes of body that will never arrive. 4125 <-closeConn 4126 }() 4127 select { 4128 case err := <-readErrCh: 4129 if err == nil { 4130 t.Error("Read was nil. Expected error.") 4131 } 4132 case err := <-errCh: 4133 t.Error(err) 4134 case <-time.After(5 * time.Second): 4135 t.Error("timeout") 4136 } 4137 } 4138 4139 // test that ResponseWriter implements io.StringWriter. 4140 func TestResponseWriterWriteString(t *testing.T) { 4141 okc := make(chan bool, 1) 4142 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 4143 _, ok := w.(io.StringWriter) 4144 okc <- ok 4145 })) 4146 ht.rawResponse("GET / HTTP/1.0") 4147 select { 4148 case ok := <-okc: 4149 if !ok { 4150 t.Error("ResponseWriter did not implement io.StringWriter") 4151 } 4152 default: 4153 t.Error("handler was never called") 4154 } 4155 } 4156 4157 func TestAppendTime(t *testing.T) { 4158 var b [len(TimeFormat)]byte 4159 t1 := time.Date(2013, 9, 21, 15, 41, 0, 0, time.FixedZone("CEST", 2*60*60)) 4160 res := ExportAppendTime(b[:0], t1) 4161 t2, err := ParseTime(string(res)) 4162 if err != nil { 4163 t.Fatalf("Error parsing time: %s", err) 4164 } 4165 if !t1.Equal(t2) { 4166 t.Fatalf("Times differ; expected: %v, got %v (%s)", t1, t2, string(res)) 4167 } 4168 } 4169 4170 func TestServerConnState(t *testing.T) { 4171 setParallel(t) 4172 defer afterTest(t) 4173 handler := map[string]func(w ResponseWriter, r *Request){ 4174 "/": func(w ResponseWriter, r *Request) { 4175 _, _ = fmt.Fprintf(w, "Hello.") 4176 }, 4177 "/close": func(w ResponseWriter, r *Request) { 4178 w.Header().Set("Connection", "close") 4179 _, _ = fmt.Fprintf(w, "Hello.") 4180 }, 4181 "/hijack": func(w ResponseWriter, r *Request) { 4182 c, _, _ := w.(Hijacker).Hijack() 4183 _, _ = c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello.")) 4184 _ = c.Close() 4185 }, 4186 "/hijack-panic": func(w ResponseWriter, r *Request) { 4187 c, _, _ := w.(Hijacker).Hijack() 4188 _, _ = c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello.")) 4189 _ = c.Close() 4190 panic("intentional panic") 4191 }, 4192 } 4193 4194 // A stateLog is a log of states over the lifetime of a connection. 4195 type stateLog struct { 4196 active net.Conn // The connection for which the log is recorded; set to the first connection seen in StateNew. 4197 got []ConnState 4198 want []ConnState 4199 complete chan<- struct{} // If non-nil, closed when either 'got' is equal to 'want', or 'got' is no longer a prefix of 'want'. 4200 } 4201 activeLog := make(chan *stateLog, 1) 4202 4203 // wantLog invokes doRequests, then waits for the resulting connection to 4204 // either pass through the sequence of states in want or enter a state outside 4205 // of that sequence. 4206 wantLog := func(doRequests func(), want ...ConnState) { 4207 t.Helper() 4208 complete := make(chan struct{}) 4209 activeLog <- &stateLog{want: want, complete: complete} 4210 4211 doRequests() 4212 4213 stateDelay := 5 * time.Second 4214 if deadline, ok := t.Deadline(); ok { 4215 // Allow an arbitrarily long delay. 4216 // This test was observed to be flaky on the darwin-arm64-corellium builder, 4217 // so we're increasing the deadline to see if it starts passing. 4218 // See https://golang.org/issue/37322. 4219 const arbitraryCleanupMargin = 1 * time.Second 4220 stateDelay = time.Until(deadline) - arbitraryCleanupMargin 4221 } 4222 timer := time.NewTimer(stateDelay) 4223 select { 4224 case <-timer.C: 4225 t.Errorf("Timed out after %v waiting for connection to change state.", stateDelay) 4226 case <-complete: 4227 timer.Stop() 4228 } 4229 sl := <-activeLog 4230 if !reflect.DeepEqual(sl.got, sl.want) { 4231 t.Errorf("Request(s) produced unexpected state sequence.\nGot: %v\nWant: %v", sl.got, sl.want) 4232 } 4233 // Don't return sl to activeLog: we don't expect any further states after 4234 // this point, and want to keep the ConnState callback blocked until the 4235 // next call to wantLog. 4236 } 4237 4238 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4239 handler[r.URL.Path](w, r) 4240 })) 4241 defer func() { 4242 activeLog <- &stateLog{} // If the test failed, allow any remaining ConnState callbacks to complete. 4243 ts.Close() 4244 }() 4245 4246 ts.Config.ErrorLog = log.New(io.Discard, "", 0) 4247 ts.Config.ConnState = func(c net.Conn, state ConnState) { 4248 if c == nil { 4249 t.Errorf("nil conn seen in state %s", state) 4250 return 4251 } 4252 sl := <-activeLog 4253 if sl.active == nil && state == StateNew { 4254 sl.active = c 4255 } else if sl.active != c { 4256 t.Errorf("unexpected conn in state %s", state) 4257 activeLog <- sl 4258 return 4259 } 4260 sl.got = append(sl.got, state) 4261 if sl.complete != nil && (len(sl.got) >= len(sl.want) || !reflect.DeepEqual(sl.got, sl.want[:len(sl.got)])) { 4262 close(sl.complete) 4263 sl.complete = nil 4264 } 4265 activeLog <- sl 4266 } 4267 4268 ts.Start() 4269 c := ts.Client() 4270 4271 mustGet := func(url string, headers ...string) { 4272 t.Helper() 4273 req, err := NewRequest("GET", url, nil) 4274 if err != nil { 4275 t.Fatal(err) 4276 } 4277 for len(headers) > 0 { 4278 req.Header.Add(headers[0], headers[1]) 4279 headers = headers[2:] 4280 } 4281 res, err := c.Do(req) 4282 if err != nil { 4283 t.Errorf("Error fetching %s: %v", url, err) 4284 return 4285 } 4286 _, err = io.ReadAll(res.Body) 4287 defer func(Body io.ReadCloser) { 4288 _ = Body.Close() 4289 }(res.Body) 4290 if err != nil { 4291 t.Errorf("Error reading %s: %v", url, err) 4292 } 4293 } 4294 4295 wantLog(func() { 4296 mustGet(ts.URL + "/") 4297 mustGet(ts.URL + "/close") 4298 }, StateNew, StateActive, StateIdle, StateActive, StateClosed) 4299 4300 wantLog(func() { 4301 mustGet(ts.URL + "/") 4302 mustGet(ts.URL+"/", "Connection", "close") 4303 }, StateNew, StateActive, StateIdle, StateActive, StateClosed) 4304 4305 wantLog(func() { 4306 mustGet(ts.URL + "/hijack") 4307 }, StateNew, StateActive, StateHijacked) 4308 4309 wantLog(func() { 4310 mustGet(ts.URL + "/hijack-panic") 4311 }, StateNew, StateActive, StateHijacked) 4312 4313 wantLog(func() { 4314 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4315 if err != nil { 4316 t.Fatal(err) 4317 } 4318 _ = c.Close() 4319 }, StateNew, StateClosed) 4320 4321 wantLog(func() { 4322 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4323 if err != nil { 4324 t.Fatal(err) 4325 } 4326 if _, err := io.WriteString(c, "BOGUS REQUEST\r\n\r\n"); err != nil { 4327 t.Fatal(err) 4328 } 4329 _, _ = c.Read(make([]byte, 1)) // block until server hangs up on us 4330 _ = c.Close() 4331 }, StateNew, StateActive, StateClosed) 4332 4333 wantLog(func() { 4334 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4335 if err != nil { 4336 t.Fatal(err) 4337 } 4338 if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil { 4339 t.Fatal(err) 4340 } 4341 res, err := ReadResponse(bufio.NewReader(c), nil) 4342 if err != nil { 4343 t.Fatal(err) 4344 } 4345 if _, err := io.Copy(io.Discard, res.Body); err != nil { 4346 t.Fatal(err) 4347 } 4348 _ = c.Close() 4349 }, StateNew, StateActive, StateIdle, StateClosed) 4350 } 4351 4352 func TestServerKeepAlivesEnabled(t *testing.T) { 4353 defer afterTest(t) 4354 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 4355 ts.Config.SetKeepAlivesEnabled(false) 4356 ts.Start() 4357 defer ts.Close() 4358 res, err := Get(ts.URL) 4359 if err != nil { 4360 t.Fatal(err) 4361 } 4362 defer func(Body io.ReadCloser) { 4363 _ = Body.Close() 4364 }(res.Body) 4365 if !res.Close { 4366 t.Errorf("Body.Close == false; want true") 4367 } 4368 } 4369 4370 // golang.org/issue/7856 4371 func TestServerEmptyBodyRace_h1(t *testing.T) { testServerEmptyBodyRace(t, h1Mode) } 4372 func TestServerEmptyBodyRace_h2(t *testing.T) { testServerEmptyBodyRace(t, h2Mode) } 4373 func testServerEmptyBodyRace(t *testing.T, h2 bool) { 4374 setParallel(t) 4375 defer afterTest(t) 4376 var n int32 4377 cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) { 4378 atomic.AddInt32(&n, 1) 4379 }), optQuietLog) 4380 defer cst.close() 4381 var wg sync.WaitGroup 4382 const reqs = 20 4383 for i := 0; i < reqs; i++ { 4384 wg.Add(1) 4385 go func() { 4386 defer wg.Done() 4387 res, err := cst.c.Get(cst.ts.URL) 4388 if err != nil { 4389 // Try to deflake spurious "connection reset by peer" under load. 4390 // See golang.org/issue/22540. 4391 time.Sleep(10 * time.Millisecond) 4392 res, err = cst.c.Get(cst.ts.URL) 4393 if err != nil { 4394 t.Error(err) 4395 return 4396 } 4397 } 4398 defer func(Body io.ReadCloser) { 4399 _ = Body.Close() 4400 }(res.Body) 4401 _, err = io.Copy(io.Discard, res.Body) 4402 if err != nil { 4403 t.Error(err) 4404 return 4405 } 4406 }() 4407 } 4408 wg.Wait() 4409 if got := atomic.LoadInt32(&n); got != reqs { 4410 t.Errorf("handler ran %d times; want %d", got, reqs) 4411 } 4412 } 4413 4414 func TestServerConnStateNew(t *testing.T) { 4415 sawNew := false // if the test is buggy, we'll race on this variable. 4416 srv := &Server{ 4417 ConnState: func(c net.Conn, state ConnState) { 4418 if state == StateNew { 4419 sawNew = true // testing that this write isn't racy 4420 } 4421 }, 4422 Handler: HandlerFunc(func(w ResponseWriter, r *Request) {}), // irrelevant 4423 } 4424 _ = srv.Serve(&oneConnListener{ 4425 conn: &rwTestConn{ 4426 Reader: strings.NewReader("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"), 4427 Writer: io.Discard, 4428 }, 4429 }) 4430 if !sawNew { // testing that this read isn't racy 4431 t.Error("StateNew not seen") 4432 } 4433 } 4434 4435 type closeWriteTestConn struct { 4436 rwTestConn 4437 didCloseWrite bool 4438 } 4439 4440 func (c *closeWriteTestConn) CloseWrite() error { 4441 c.didCloseWrite = true 4442 return nil 4443 } 4444 4445 func TestCloseWrite(t *testing.T) { 4446 setParallel(t) 4447 var srv Server 4448 var testConn closeWriteTestConn 4449 c := ExportServerNewConn(&srv, &testConn) 4450 ExportCloseWriteAndWait(c) 4451 if !testConn.didCloseWrite { 4452 t.Error("didn't see CloseWrite call") 4453 } 4454 } 4455 4456 // This verifies that a handler can Flush and then Hijack. 4457 // 4458 // A similar test crashed once during development, but it was only 4459 // testing this tangentially and temporarily until another TODO was 4460 // fixed. 4461 // 4462 // So add an explicit test for this. 4463 func TestServerFlushAndHijack(t *testing.T) { 4464 defer afterTest(t) 4465 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4466 _, _ = io.WriteString(w, "Hello, ") 4467 w.(Flusher).Flush() 4468 conn, buf, _ := w.(Hijacker).Hijack() 4469 _, _ = buf.WriteString("6\r\nworld!\r\n0\r\n\r\n") 4470 if err := buf.Flush(); err != nil { 4471 t.Error(err) 4472 } 4473 if err := conn.Close(); err != nil { 4474 t.Error(err) 4475 } 4476 })) 4477 defer ts.Close() 4478 res, err := Get(ts.URL) 4479 if err != nil { 4480 t.Fatal(err) 4481 } 4482 defer func(Body io.ReadCloser) { 4483 _ = Body.Close() 4484 }(res.Body) 4485 all, err := io.ReadAll(res.Body) 4486 if err != nil { 4487 t.Fatal(err) 4488 } 4489 if want := "Hello, world!"; string(all) != want { 4490 t.Errorf("Got %q; want %q", all, want) 4491 } 4492 } 4493 4494 // golang.org/issue/8534 -- the Server shouldn't reuse a connection 4495 // for keep-alive after it's seen any Write error (e.g. a timeout) on 4496 // that net.Conn. 4497 // 4498 // To test, verify we don't timeout or see fewer unique client 4499 // addresses (== unique connections) than requests. 4500 func TestServerKeepAliveAfterWriteError(t *testing.T) { 4501 if testing.Short() { 4502 t.Skip("skipping in -short mode") 4503 } 4504 defer afterTest(t) 4505 const numReq = 3 4506 addrc := make(chan string, numReq) 4507 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4508 addrc <- r.RemoteAddr 4509 time.Sleep(500 * time.Millisecond) 4510 w.(Flusher).Flush() 4511 })) 4512 ts.Config.WriteTimeout = 250 * time.Millisecond 4513 ts.Start() 4514 defer ts.Close() 4515 4516 errc := make(chan error, numReq) 4517 go func() { 4518 defer close(errc) 4519 for i := 0; i < numReq; i++ { 4520 res, err := Get(ts.URL) 4521 if res != nil { 4522 _ = res.Body.Close() 4523 } 4524 errc <- err 4525 } 4526 }() 4527 4528 timeout := time.NewTimer(numReq * 2 * time.Second) // 4x overkill 4529 defer timeout.Stop() 4530 addrSeen := map[string]bool{} 4531 numOkay := 0 4532 for { 4533 select { 4534 case v := <-addrc: 4535 addrSeen[v] = true 4536 case err, ok := <-errc: 4537 if !ok { 4538 if len(addrSeen) != numReq { 4539 t.Errorf("saw %d unique client addresses; want %d", len(addrSeen), numReq) 4540 } 4541 if numOkay != 0 { 4542 t.Errorf("got %d successful client requests; want 0", numOkay) 4543 } 4544 return 4545 } 4546 if err == nil { 4547 numOkay++ 4548 } 4549 case <-timeout.C: 4550 t.Fatal("timeout waiting for requests to complete") 4551 } 4552 } 4553 } 4554 4555 // Issue 9987: shouldn't add automatic Content-Length (or 4556 // Content-Type) if a Transfer-Encoding was set by the handler. 4557 func TestNoContentLengthIfTransferEncoding(t *testing.T) { 4558 defer afterTest(t) 4559 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4560 w.Header().Set("Transfer-Encoding", "foo") 4561 _, _ = io.WriteString(w, "<html>") 4562 })) 4563 defer ts.Close() 4564 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4565 if err != nil { 4566 t.Fatalf("Dial: %v", err) 4567 } 4568 defer func(c net.Conn) { 4569 _ = c.Close() 4570 }(c) 4571 if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil { 4572 t.Fatal(err) 4573 } 4574 bs := bufio.NewScanner(c) 4575 var got bytes.Buffer 4576 for bs.Scan() { 4577 if strings.TrimSpace(bs.Text()) == "" { 4578 break 4579 } 4580 got.WriteString(bs.Text()) 4581 got.WriteByte('\n') 4582 } 4583 if err := bs.Err(); err != nil { 4584 t.Fatal(err) 4585 } 4586 if strings.Contains(got.String(), "Content-Length") { 4587 t.Errorf("Unexpected Content-Length in response headers: %s", got.String()) 4588 } 4589 if strings.Contains(got.String(), "Content-Type") { 4590 t.Errorf("Unexpected Content-Type in response headers: %s", got.String()) 4591 } 4592 } 4593 4594 // tolerate extra CRLF(s) before Request-Line on subsequent requests on a conn 4595 // Issue 10876. 4596 func TestTolerateCRLFBeforeRequestLine(t *testing.T) { 4597 req := []byte("POST / HTTP/1.1\r\nHost: golang.org\r\nContent-Length: 3\r\n\r\nABC" + 4598 "\r\n\r\n" + // <-- this stuff is bogus, but we'll ignore it 4599 "GET / HTTP/1.1\r\nHost: golang.org\r\n\r\n") 4600 var buf bytes.Buffer 4601 conn := &rwTestConn{ 4602 Reader: bytes.NewReader(req), 4603 Writer: &buf, 4604 closec: make(chan bool, 1), 4605 } 4606 ln := &oneConnListener{conn: conn} 4607 numReq := 0 4608 go func() { 4609 _ = Serve(ln, HandlerFunc(func(rw ResponseWriter, r *Request) { 4610 numReq++ 4611 })) 4612 }() 4613 <-conn.closec 4614 if numReq != 2 { 4615 t.Errorf("num requests = %d; want 2", numReq) 4616 t.Logf("Res: %s", buf.Bytes()) 4617 } 4618 } 4619 4620 func TestIssue13893_Expect100(t *testing.T) { 4621 // test that the Server doesn't filter out Expect headers. 4622 req := reqBytes(`PUT /readbody HTTP/1.1 4623 User-Agent: PycURL/7.22.0 4624 Host: 127.0.0.1:9000 4625 Accept: */* 4626 Expect: 100-continue 4627 Content-Length: 10 4628 4629 HelloWorld 4630 4631 `) 4632 var buf bytes.Buffer 4633 conn := &rwTestConn{ 4634 Reader: bytes.NewReader(req), 4635 Writer: &buf, 4636 closec: make(chan bool, 1), 4637 } 4638 ln := &oneConnListener{conn: conn} 4639 go func() { 4640 _ = Serve(ln, HandlerFunc(func(w ResponseWriter, r *Request) { 4641 if _, ok := r.Header["Expect"]; !ok { 4642 4643 t.Error("Expect header should not be filtered out") 4644 } 4645 })) 4646 }() 4647 <-conn.closec 4648 } 4649 4650 func TestIssue11549_Expect100(t *testing.T) { 4651 req := reqBytes(`PUT /readbody HTTP/1.1 4652 User-Agent: PycURL/7.22.0 4653 Host: 127.0.0.1:9000 4654 Accept: */* 4655 Expect: 100-continue 4656 Content-Length: 10 4657 4658 HelloWorldPUT /noreadbody HTTP/1.1 4659 User-Agent: PycURL/7.22.0 4660 Host: 127.0.0.1:9000 4661 Accept: */* 4662 Expect: 100-continue 4663 Content-Length: 10 4664 4665 GET /should-be-ignored HTTP/1.1 4666 Host: foo 4667 4668 `) 4669 var buf bytes.Buffer 4670 conn := &rwTestConn{ 4671 Reader: bytes.NewReader(req), 4672 Writer: &buf, 4673 closec: make(chan bool, 1), 4674 } 4675 ln := &oneConnListener{conn: conn} 4676 numReq := 0 4677 go func() { 4678 _ = Serve(ln, HandlerFunc(func(w ResponseWriter, r *Request) { 4679 numReq++ 4680 if r.URL.Path == "/readbody" { 4681 _, _ = io.ReadAll(r.Body) 4682 } 4683 _, _ = io.WriteString(w, "Hello world!") 4684 })) 4685 }() 4686 <-conn.closec 4687 if numReq != 2 { 4688 t.Errorf("num requests = %d; want 2", numReq) 4689 } 4690 if !strings.Contains(buf.String(), "Connection: close\r\n") { 4691 t.Errorf("expected 'Connection: close' in response; got: %s", buf.String()) 4692 } 4693 } 4694 4695 // If a Handler finishes and there's an unread request body, 4696 // verify the server try to do implicit read on it before replying. 4697 func TestHandlerFinishSkipBigContentLengthRead(t *testing.T) { 4698 setParallel(t) 4699 conn := &testConn{closec: make(chan bool)} 4700 conn.readBuf.Write([]byte(fmt.Sprintf( 4701 "POST / HTTP/1.1\r\n" + 4702 "Host: test\r\n" + 4703 "Content-Length: 9999999999\r\n" + 4704 "\r\n" + strings.Repeat("a", 1<<20)))) 4705 4706 ls := &oneConnListener{conn} 4707 var inHandlerLen int 4708 go func() { 4709 _ = Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) { 4710 inHandlerLen = conn.readBuf.Len() 4711 rw.WriteHeader(404) 4712 })) 4713 }() 4714 <-conn.closec 4715 afterHandlerLen := conn.readBuf.Len() 4716 4717 if afterHandlerLen != inHandlerLen { 4718 t.Errorf("unexpected implicit read. Read buffer went from %d -> %d", inHandlerLen, afterHandlerLen) 4719 } 4720 } 4721 4722 func TestHandlerSetsBodyNil_h1(t *testing.T) { testHandlerSetsBodyNil(t, h1Mode) } 4723 func TestHandlerSetsBodyNil_h2(t *testing.T) { testHandlerSetsBodyNil(t, h2Mode) } 4724 func testHandlerSetsBodyNil(t *testing.T, h2 bool) { 4725 defer afterTest(t) 4726 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 4727 r.Body = nil 4728 _, _ = fmt.Fprintf(w, "%v", r.RemoteAddr) 4729 })) 4730 defer cst.close() 4731 get := func() string { 4732 res, err := cst.c.Get(cst.ts.URL) 4733 if err != nil { 4734 t.Fatal(err) 4735 } 4736 defer func(Body io.ReadCloser) { 4737 _ = Body.Close() 4738 }(res.Body) 4739 slurp, err := io.ReadAll(res.Body) 4740 if err != nil { 4741 t.Fatal(err) 4742 } 4743 return string(slurp) 4744 } 4745 a, b := get(), get() 4746 if a != b { 4747 t.Errorf("Failed to reuse connections between requests: %v vs %v", a, b) 4748 } 4749 } 4750 4751 // Test that we validate the Host header. 4752 // Issue 11206 (invalid bytes in Host) and 13624 (Host present in HTTP/1.1) 4753 func TestServerValidatesHostHeader(t *testing.T) { 4754 tests := []struct { 4755 proto string 4756 host string 4757 want int 4758 }{ 4759 {"HTTP/0.9", "", 505}, 4760 4761 {"HTTP/1.1", "", 400}, 4762 {"HTTP/1.1", "Host: \r\n", 200}, 4763 {"HTTP/1.1", "Host: 1.2.3.4\r\n", 200}, 4764 {"HTTP/1.1", "Host: foo.com\r\n", 200}, 4765 {"HTTP/1.1", "Host: foo-bar_baz.com\r\n", 200}, 4766 {"HTTP/1.1", "Host: foo.com:80\r\n", 200}, 4767 {"HTTP/1.1", "Host: ::1\r\n", 200}, 4768 {"HTTP/1.1", "Host: [::1]\r\n", 200}, // questionable without port, but accept it 4769 {"HTTP/1.1", "Host: [::1]:80\r\n", 200}, 4770 {"HTTP/1.1", "Host: [::1%25en0]:80\r\n", 200}, 4771 {"HTTP/1.1", "Host: 1.2.3.4\r\n", 200}, 4772 {"HTTP/1.1", "Host: \x06\r\n", 400}, 4773 {"HTTP/1.1", "Host: \xff\r\n", 400}, 4774 {"HTTP/1.1", "Host: {\r\n", 400}, 4775 {"HTTP/1.1", "Host: }\r\n", 400}, 4776 {"HTTP/1.1", "Host: first\r\nHost: second\r\n", 400}, 4777 4778 // HTTP/1.0 can lack a host header, but if present 4779 // must play by the rules too: 4780 {"HTTP/1.0", "", 200}, 4781 {"HTTP/1.0", "Host: first\r\nHost: second\r\n", 400}, 4782 {"HTTP/1.0", "Host: \xff\r\n", 400}, 4783 4784 // Make an exception for HTTP upgrade requests: 4785 {"PRI * HTTP/2.0", "", 200}, 4786 4787 // Also an exception for CONNECT requests: (Issue 18215) 4788 {"CONNECT golang.org:443 HTTP/1.1", "", 200}, 4789 4790 // But not other HTTP/2 stuff: 4791 {"PRI / HTTP/2.0", "", 505}, 4792 {"GET / HTTP/2.0", "", 505}, 4793 {"GET / HTTP/3.0", "", 505}, 4794 } 4795 for _, tt := range tests { 4796 conn := &testConn{closec: make(chan bool, 1)} 4797 methodTarget := "GET / " 4798 if !strings.HasPrefix(tt.proto, "HTTP/") { 4799 methodTarget = "" 4800 } 4801 _, _ = io.WriteString(&conn.readBuf, methodTarget+tt.proto+"\r\n"+tt.host+"\r\n") 4802 4803 ln := &oneConnListener{conn} 4804 srv := Server{ 4805 ErrorLog: quietLog, 4806 Handler: HandlerFunc(func(ResponseWriter, *Request) {}), 4807 } 4808 go func() { 4809 _ = srv.Serve(ln) 4810 }() 4811 <-conn.closec 4812 res, err := ReadResponse(bufio.NewReader(&conn.writeBuf), nil) 4813 if err != nil { 4814 t.Errorf("For %s %q, ReadResponse: %v", tt.proto, tt.host, res) 4815 continue 4816 } 4817 if res.StatusCode != tt.want { 4818 t.Errorf("For %s %q, Status = %d; want %d", tt.proto, tt.host, res.StatusCode, tt.want) 4819 } 4820 } 4821 } 4822 4823 func TestServerHandlersCanHandleH2PRI(t *testing.T) { 4824 const upgradeResponse = "upgrade here" 4825 defer afterTest(t) 4826 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4827 conn, br, err := w.(Hijacker).Hijack() 4828 if err != nil { 4829 t.Error(err) 4830 return 4831 } 4832 defer func(conn net.Conn) { 4833 _ = conn.Close() 4834 }(conn) 4835 if r.Method != "PRI" || r.RequestURI != "*" { 4836 t.Errorf("Got method/target %q %q; want PRI *", r.Method, r.RequestURI) 4837 return 4838 } 4839 if !r.Close { 4840 t.Errorf("Request.Close = true; want false") 4841 } 4842 const want = "SM\r\n\r\n" 4843 buf := make([]byte, len(want)) 4844 n, err := io.ReadFull(br, buf) 4845 if err != nil || string(buf[:n]) != want { 4846 t.Errorf("Read = %v, %v (%q), want %q", n, err, buf[:n], want) 4847 return 4848 } 4849 _, _ = io.WriteString(conn, upgradeResponse) 4850 })) 4851 defer ts.Close() 4852 4853 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4854 if err != nil { 4855 t.Fatalf("Dial: %v", err) 4856 } 4857 defer func(c net.Conn) { 4858 _ = c.Close() 4859 }(c) 4860 _, _ = io.WriteString(c, "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n") 4861 slurp, err := io.ReadAll(c) 4862 if err != nil { 4863 t.Fatal(err) 4864 } 4865 if string(slurp) != upgradeResponse { 4866 t.Errorf("Handler response = %q; want %q", slurp, upgradeResponse) 4867 } 4868 } 4869 4870 // Test that we validate the valid bytes in HTTP/1 headers. 4871 // Issue 11207. 4872 func TestServerValidatesHeaders(t *testing.T) { 4873 setParallel(t) 4874 tests := []struct { 4875 header string 4876 want int 4877 }{ 4878 {"", 200}, 4879 {"Foo: bar\r\n", 200}, 4880 {"X-Foo: bar\r\n", 200}, 4881 {"Foo: a space\r\n", 200}, 4882 4883 {"A space: foo\r\n", 400}, // space in header 4884 {"foo\xffbar: foo\r\n", 400}, // binary in header 4885 {"foo\x00bar: foo\r\n", 400}, // binary in header 4886 {"Foo: " + strings.Repeat("x", 1<<21) + "\r\n", 431}, // header too large 4887 // Spaces between the header key and colon are not allowed. 4888 // See RFC 7230, Section 3.2.4. 4889 {"Foo : bar\r\n", 400}, 4890 {"Foo\t: bar\r\n", 400}, 4891 4892 {"foo: foo foo\r\n", 200}, // LWS space is okay 4893 {"foo: foo\tfoo\r\n", 200}, // LWS tab is okay 4894 {"foo: foo\x00foo\r\n", 400}, // CTL 0x00 in value is bad 4895 {"foo: foo\x7ffoo\r\n", 400}, // CTL 0x7f in value is bad 4896 {"foo: foo\xfffoo\r\n", 200}, // non-ASCII high octets in value are fine 4897 } 4898 for _, tt := range tests { 4899 conn := &testConn{closec: make(chan bool, 1)} 4900 _, _ = io.WriteString(&conn.readBuf, "GET / HTTP/1.1\r\nHost: foo\r\n"+tt.header+"\r\n") 4901 4902 ln := &oneConnListener{conn} 4903 srv := Server{ 4904 ErrorLog: quietLog, 4905 Handler: HandlerFunc(func(ResponseWriter, *Request) {}), 4906 } 4907 go func() { 4908 _ = srv.Serve(ln) 4909 }() 4910 <-conn.closec 4911 res, err := ReadResponse(bufio.NewReader(&conn.writeBuf), nil) 4912 if err != nil { 4913 t.Errorf("For %q, ReadResponse: %v", tt.header, res) 4914 continue 4915 } 4916 if res.StatusCode != tt.want { 4917 t.Errorf("For %q, Status = %d; want %d", tt.header, res.StatusCode, tt.want) 4918 } 4919 } 4920 } 4921 4922 func TestServerRequestContextCancel_ServeHTTPDone_h1(t *testing.T) { 4923 testServerRequestContextCancel_ServeHTTPDone(t, h1Mode) 4924 } 4925 func TestServerRequestContextCancel_ServeHTTPDone_h2(t *testing.T) { 4926 testServerRequestContextCancel_ServeHTTPDone(t, h2Mode) 4927 } 4928 4929 //goland:noinspection GoSnakeCaseUsage 4930 func testServerRequestContextCancel_ServeHTTPDone(t *testing.T, h2 bool) { 4931 setParallel(t) 4932 defer afterTest(t) 4933 ctxc := make(chan context.Context, 1) 4934 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 4935 ctx := r.Context() 4936 select { 4937 case <-ctx.Done(): 4938 t.Error("should not be Done in ServeHTTP") 4939 default: 4940 } 4941 ctxc <- ctx 4942 })) 4943 defer cst.close() 4944 res, err := cst.c.Get(cst.ts.URL) 4945 if err != nil { 4946 t.Fatal(err) 4947 } 4948 _ = res.Body.Close() 4949 ctx := <-ctxc 4950 select { 4951 case <-ctx.Done(): 4952 default: 4953 t.Error("context should be done after ServeHTTP completes") 4954 } 4955 } 4956 4957 // Tests that the Request.Context available to the Handler is canceled 4958 // if the peer closes their TCP connection. This requires that the server 4959 // is always blocked in a Read call so it notices the EOF from the client. 4960 // See issues 15927 and 15224. 4961 func TestServerRequestContextCancel_ConnClose(t *testing.T) { 4962 setParallel(t) 4963 defer afterTest(t) 4964 inHandler := make(chan struct{}) 4965 handlerDone := make(chan struct{}) 4966 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 4967 close(inHandler) 4968 select { 4969 case <-r.Context().Done(): 4970 case <-time.After(3 * time.Second): 4971 t.Errorf("timeout waiting for context to be done") 4972 } 4973 close(handlerDone) 4974 })) 4975 defer ts.Close() 4976 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 4977 if err != nil { 4978 t.Fatal(err) 4979 } 4980 defer func(c net.Conn) { 4981 _ = c.Close() 4982 }(c) 4983 _, _ = io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n") 4984 select { 4985 case <-inHandler: 4986 case <-time.After(3 * time.Second): 4987 t.Fatalf("timeout waiting to see ServeHTTP get called") 4988 } 4989 _ = c.Close() // this should trigger the context being done 4990 4991 select { 4992 case <-handlerDone: 4993 case <-time.After(4 * time.Second): 4994 t.Fatalf("timeout waiting to see ServeHTTP exit") 4995 } 4996 } 4997 4998 func TestServerContext_ServerContextKey_h1(t *testing.T) { 4999 testServerContext_ServerContextKey(t, h1Mode) 5000 } 5001 func TestServerContext_ServerContextKey_h2(t *testing.T) { 5002 testServerContext_ServerContextKey(t, h2Mode) 5003 } 5004 5005 //goland:noinspection GoSnakeCaseUsage 5006 func testServerContext_ServerContextKey(t *testing.T, h2 bool) { 5007 setParallel(t) 5008 defer afterTest(t) 5009 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 5010 ctx := r.Context() 5011 got := ctx.Value(ServerContextKey) 5012 if _, ok := got.(*Server); !ok { 5013 t.Errorf("context value = %T; want *http.Server", got) 5014 } 5015 })) 5016 defer cst.close() 5017 res, err := cst.c.Get(cst.ts.URL) 5018 if err != nil { 5019 t.Fatal(err) 5020 } 5021 _ = res.Body.Close() 5022 } 5023 5024 func TestServerContext_LocalAddrContextKey_h1(t *testing.T) { 5025 testServerContext_LocalAddrContextKey(t, h1Mode) 5026 } 5027 func TestServerContext_LocalAddrContextKey_h2(t *testing.T) { 5028 testServerContext_LocalAddrContextKey(t, h2Mode) 5029 } 5030 5031 //goland:noinspection GoSnakeCaseUsage 5032 func testServerContext_LocalAddrContextKey(t *testing.T, h2 bool) { 5033 setParallel(t) 5034 defer afterTest(t) 5035 ch := make(chan interface{}, 1) 5036 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 5037 ch <- r.Context().Value(LocalAddrContextKey) 5038 })) 5039 defer cst.close() 5040 if _, err := cst.c.Head(cst.ts.URL); err != nil { 5041 t.Fatal(err) 5042 } 5043 5044 host := cst.ts.Listener.Addr().String() 5045 select { 5046 case got := <-ch: 5047 if addr, ok := got.(net.Addr); !ok { 5048 t.Errorf("local addr value = %T; want net.Addr", got) 5049 } else if fmt.Sprint(addr) != host { 5050 t.Errorf("local addr = %v; want %v", addr, host) 5051 } 5052 case <-time.After(5 * time.Second): 5053 t.Error("timed out") 5054 } 5055 } 5056 5057 // https://golang.org/issue/15960 5058 func TestHandlerSetTransferEncodingChunked(t *testing.T) { 5059 setParallel(t) 5060 defer afterTest(t) 5061 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 5062 w.Header().Set("Transfer-Encoding", "chunked") 5063 _, _ = w.Write([]byte("hello")) 5064 })) 5065 resp := ht.rawResponse("GET / HTTP/1.1\nHost: foo") 5066 const hdr = "Transfer-Encoding: chunked" 5067 if n := strings.Count(resp, hdr); n != 1 { 5068 t.Errorf("want 1 occurrence of %q in response, got %v\nresponse: %v", hdr, n, resp) 5069 } 5070 } 5071 5072 // https://golang.org/issue/16063 5073 func TestHandlerSetTransferEncodingGzip(t *testing.T) { 5074 setParallel(t) 5075 defer afterTest(t) 5076 ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { 5077 w.Header().Set("Transfer-Encoding", "gzip") 5078 gz := gzip.NewWriter(w) 5079 _, _ = gz.Write([]byte("hello")) 5080 _ = gz.Close() 5081 })) 5082 resp := ht.rawResponse("GET / HTTP/1.1\nHost: foo") 5083 for _, v := range []string{"gzip", "chunked"} { 5084 hdr := "Transfer-Encoding: " + v 5085 if n := strings.Count(resp, hdr); n != 1 { 5086 t.Errorf("want 1 occurrence of %q in response, got %v\nresponse: %v", hdr, n, resp) 5087 } 5088 } 5089 } 5090 5091 func BenchmarkClientServer(b *testing.B) { 5092 b.ReportAllocs() 5093 b.StopTimer() 5094 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 5095 _, _ = fmt.Fprintf(rw, "Hello world.\n") 5096 })) 5097 defer ts.Close() 5098 b.StartTimer() 5099 5100 for i := 0; i < b.N; i++ { 5101 res, err := Get(ts.URL) 5102 if err != nil { 5103 b.Fatal("Get:", err) 5104 } 5105 all, err := io.ReadAll(res.Body) 5106 _ = res.Body.Close() 5107 if err != nil { 5108 b.Fatal("ReadAll:", err) 5109 } 5110 body := string(all) 5111 if body != "Hello world.\n" { 5112 b.Fatal("Got body:", body) 5113 } 5114 } 5115 5116 b.StopTimer() 5117 } 5118 5119 func BenchmarkClientServerParallel4(b *testing.B) { 5120 benchmarkClientServerParallel(b, 4, false) 5121 } 5122 5123 func BenchmarkClientServerParallel64(b *testing.B) { 5124 benchmarkClientServerParallel(b, 64, false) 5125 } 5126 5127 func BenchmarkClientServerParallelTLS4(b *testing.B) { 5128 benchmarkClientServerParallel(b, 4, true) 5129 } 5130 5131 func BenchmarkClientServerParallelTLS64(b *testing.B) { 5132 benchmarkClientServerParallel(b, 64, true) 5133 } 5134 5135 func benchmarkClientServerParallel(b *testing.B, parallelism int, useTLS bool) { 5136 b.ReportAllocs() 5137 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 5138 _, _ = fmt.Fprintf(rw, "Hello world.\n") 5139 })) 5140 if useTLS { 5141 ts.StartTLS() 5142 } else { 5143 ts.Start() 5144 } 5145 defer ts.Close() 5146 b.ResetTimer() 5147 b.SetParallelism(parallelism) 5148 b.RunParallel(func(pb *testing.PB) { 5149 c := ts.Client() 5150 for pb.Next() { 5151 res, err := c.Get(ts.URL) 5152 if err != nil { 5153 b.Logf("Get: %v", err) 5154 continue 5155 } 5156 all, err := io.ReadAll(res.Body) 5157 _ = res.Body.Close() 5158 if err != nil { 5159 b.Logf("ReadAll: %v", err) 5160 continue 5161 } 5162 body := string(all) 5163 if body != "Hello world.\n" { 5164 panic("Got body: " + body) 5165 } 5166 } 5167 }) 5168 } 5169 5170 // A benchmark for profiling the server without the HTTP client code. 5171 // The client code runs in a subprocess. 5172 // 5173 // For use like: 5174 // $ go test -c 5175 // $ ./http.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=http.prof 5176 // $ go tool pprof http.test http.prof 5177 // (pprof) web 5178 func BenchmarkServer(b *testing.B) { 5179 b.ReportAllocs() 5180 // Child process mode; 5181 if urlTmp := os.Getenv("TEST_BENCH_SERVER_URL"); urlTmp != "" { 5182 n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N")) 5183 if err != nil { 5184 panic(err) 5185 } 5186 for i := 0; i < n; i++ { 5187 res, err := Get(urlTmp) 5188 if err != nil { 5189 log.Panicf("Get: %v", err) 5190 } 5191 all, err := io.ReadAll(res.Body) 5192 _ = res.Body.Close() 5193 if err != nil { 5194 log.Panicf("ReadAll: %v", err) 5195 } 5196 body := string(all) 5197 if body != "Hello world.\n" { 5198 log.Panicf("Got body: %q", body) 5199 } 5200 } 5201 os.Exit(0) 5202 return 5203 } 5204 5205 var res = []byte("Hello world.\n") 5206 b.StopTimer() 5207 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 5208 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 5209 _, _ = rw.Write(res) 5210 })) 5211 defer ts.Close() 5212 b.StartTimer() 5213 5214 cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer$") 5215 cmd.Env = append([]string{ 5216 fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N), 5217 fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL), 5218 }, os.Environ()...) 5219 out, err := cmd.CombinedOutput() 5220 if err != nil { 5221 b.Errorf("Test failure: %v, with output: %s", err, out) 5222 } 5223 } 5224 5225 // getNoBody wraps Get but closes any Response.Body before returning the response. 5226 func getNoBody(urlStr string) (*Response, error) { 5227 res, err := Get(urlStr) 5228 if err != nil { 5229 return nil, err 5230 } 5231 _ = res.Body.Close() 5232 return res, nil 5233 } 5234 5235 // A benchmark for profiling the client without the HTTP server code. 5236 // The server code runs in a subprocess. 5237 func BenchmarkClient(b *testing.B) { 5238 b.ReportAllocs() 5239 b.StopTimer() 5240 defer afterTest(b) 5241 5242 var data = []byte("Hello world.\n") 5243 if server := os.Getenv("TEST_BENCH_SERVER"); server != "" { 5244 // Server process mode. 5245 port := os.Getenv("TEST_BENCH_SERVER_PORT") // can be set by user 5246 if port == "" { 5247 port = "0" 5248 } 5249 ln, err := net.Listen("tcp", "localhost:"+port) 5250 if err != nil { 5251 _, _ = fmt.Fprintln(os.Stderr, err.Error()) 5252 os.Exit(1) 5253 } 5254 fmt.Println(ln.Addr().String()) 5255 HandleFunc("/", func(w ResponseWriter, r *Request) { 5256 _ = r.ParseForm() 5257 if r.Form.Get("stop") != "" { 5258 os.Exit(0) 5259 } 5260 w.Header().Set("Content-Type", "text/html; charset=utf-8") 5261 _, _ = w.Write(data) 5262 }) 5263 var srv Server 5264 log.Fatal(srv.Serve(ln)) 5265 } 5266 5267 // Start server process. 5268 cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkClient$") 5269 cmd.Env = append(os.Environ(), "TEST_BENCH_SERVER=yes") 5270 cmd.Stderr = os.Stderr 5271 stdout, err := cmd.StdoutPipe() 5272 if err != nil { 5273 b.Fatal(err) 5274 } 5275 if err := cmd.Start(); err != nil { 5276 b.Fatalf("subprocess failed to start: %v", err) 5277 } 5278 defer func(Process *os.Process) { 5279 _ = Process.Kill() 5280 }(cmd.Process) 5281 5282 // Wait for the server in the child process to respond and tell us 5283 // its listening address, once it's started listening: 5284 timer := time.AfterFunc(10*time.Second, func() { 5285 _ = cmd.Process.Kill() 5286 }) 5287 defer timer.Stop() 5288 bs := bufio.NewScanner(stdout) 5289 if !bs.Scan() { 5290 b.Fatalf("failed to read listening URL from child: %v", bs.Err()) 5291 } 5292 //goland:noinspection HttpUrlsUsage 5293 urlTmp := "http://" + strings.TrimSpace(bs.Text()) + "/" 5294 timer.Stop() 5295 if _, err := getNoBody(urlTmp); err != nil { 5296 b.Fatalf("initial probe of child process failed: %v", err) 5297 } 5298 5299 done := make(chan error) 5300 stop := make(chan struct{}) 5301 defer close(stop) 5302 go func() { 5303 select { 5304 case <-stop: 5305 return 5306 case done <- cmd.Wait(): 5307 } 5308 }() 5309 5310 // Do b.N requests to the server. 5311 b.StartTimer() 5312 for i := 0; i < b.N; i++ { 5313 res, err := Get(urlTmp) 5314 if err != nil { 5315 b.Fatalf("Get: %v", err) 5316 } 5317 body, err := io.ReadAll(res.Body) 5318 _ = res.Body.Close() 5319 if err != nil { 5320 b.Fatalf("ReadAll: %v", err) 5321 } 5322 if !bytes.Equal(body, data) { 5323 b.Fatalf("Got body: %q", body) 5324 } 5325 } 5326 b.StopTimer() 5327 5328 // Instruct server process to stop. 5329 _, _ = getNoBody(urlTmp + "?stop=yes") 5330 select { 5331 case err := <-done: 5332 if err != nil { 5333 b.Fatalf("subprocess failed: %v", err) 5334 } 5335 case <-time.After(5 * time.Second): 5336 b.Fatalf("subprocess did not stop") 5337 } 5338 } 5339 5340 func BenchmarkServerFakeConnNoKeepAlive(b *testing.B) { 5341 b.ReportAllocs() 5342 req := reqBytes(`GET / HTTP/1.0 5343 Host: golang.org 5344 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5345 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 5346 Accept-Encoding: gzip,deflate,sdch 5347 Accept-Language: en-US,en;q=0.8 5348 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 5349 `) 5350 res := []byte("Hello world!\n") 5351 5352 conn := &testConn{ 5353 // testConn.Close will not push into the channel 5354 // if it's full. 5355 closec: make(chan bool, 1), 5356 } 5357 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 5358 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 5359 _, _ = rw.Write(res) 5360 }) 5361 ln := new(oneConnListener) 5362 for i := 0; i < b.N; i++ { 5363 conn.readBuf.Reset() 5364 conn.writeBuf.Reset() 5365 conn.readBuf.Write(req) 5366 ln.conn = conn 5367 _ = Serve(ln, handler) 5368 <-conn.closec 5369 } 5370 } 5371 5372 // repeatReader reads content count times, then EOFs. 5373 type repeatReader struct { 5374 content []byte 5375 count int 5376 off int 5377 } 5378 5379 func (r *repeatReader) Read(p []byte) (n int, err error) { 5380 if r.count <= 0 { 5381 return 0, io.EOF 5382 } 5383 n = copy(p, r.content[r.off:]) 5384 r.off += n 5385 if r.off == len(r.content) { 5386 r.count-- 5387 r.off = 0 5388 } 5389 return 5390 } 5391 5392 func BenchmarkServerFakeConnWithKeepAlive(b *testing.B) { 5393 b.ReportAllocs() 5394 5395 req := reqBytes(`GET / HTTP/1.1 5396 Host: golang.org 5397 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5398 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 5399 Accept-Encoding: gzip,deflate,sdch 5400 Accept-Language: en-US,en;q=0.8 5401 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 5402 `) 5403 res := []byte("Hello world!\n") 5404 5405 conn := &rwTestConn{ 5406 Reader: &repeatReader{content: req, count: b.N}, 5407 Writer: io.Discard, 5408 closec: make(chan bool, 1), 5409 } 5410 handled := 0 5411 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 5412 handled++ 5413 rw.Header().Set("Content-Type", "text/html; charset=utf-8") 5414 _, _ = rw.Write(res) 5415 }) 5416 ln := &oneConnListener{conn: conn} 5417 go func() { 5418 _ = Serve(ln, handler) 5419 }() 5420 <-conn.closec 5421 if b.N != handled { 5422 b.Errorf("b.N=%d but handled %d", b.N, handled) 5423 } 5424 } 5425 5426 // same as above, but representing the most simple possible request 5427 // and handler. Notably: the handler does not call rw.Header(). 5428 func BenchmarkServerFakeConnWithKeepAliveLite(b *testing.B) { 5429 b.ReportAllocs() 5430 5431 req := reqBytes(`GET / HTTP/1.1 5432 Host: golang.org 5433 `) 5434 res := []byte("Hello world!\n") 5435 5436 conn := &rwTestConn{ 5437 Reader: &repeatReader{content: req, count: b.N}, 5438 Writer: io.Discard, 5439 closec: make(chan bool, 1), 5440 } 5441 handled := 0 5442 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 5443 handled++ 5444 _, _ = rw.Write(res) 5445 }) 5446 ln := &oneConnListener{conn: conn} 5447 go func() { 5448 _ = Serve(ln, handler) 5449 }() 5450 <-conn.closec 5451 if b.N != handled { 5452 b.Errorf("b.N=%d but handled %d", b.N, handled) 5453 } 5454 } 5455 5456 const someResponse = "<html>some response</html>" 5457 5458 // A Response that's just no bigger than 2KB, the buffer-before-chunking threshold. 5459 var response = bytes.Repeat([]byte(someResponse), 2<<10/len(someResponse)) 5460 5461 // Both Content-Type and Content-Length set. Should be no buffering. 5462 func BenchmarkServerHandlerTypeLen(b *testing.B) { 5463 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 5464 w.Header().Set("Content-Type", "text/html") 5465 w.Header().Set("Content-Length", strconv.Itoa(len(response))) 5466 _, _ = w.Write(response) 5467 })) 5468 } 5469 5470 // A Content-Type is set, but no length. No sniffing, but will count the Content-Length. 5471 func BenchmarkServerHandlerNoLen(b *testing.B) { 5472 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 5473 w.Header().Set("Content-Type", "text/html") 5474 _, _ = w.Write(response) 5475 })) 5476 } 5477 5478 // A Content-Length is set, but the Content-Type will be sniffed. 5479 func BenchmarkServerHandlerNoType(b *testing.B) { 5480 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 5481 w.Header().Set("Content-Length", strconv.Itoa(len(response))) 5482 _, _ = w.Write(response) 5483 })) 5484 } 5485 5486 // Neither a Content-Type or Content-Length, so sniffed and counted. 5487 func BenchmarkServerHandlerNoHeader(b *testing.B) { 5488 benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) { 5489 _, _ = w.Write(response) 5490 })) 5491 } 5492 5493 func benchmarkHandler(b *testing.B, h Handler) { 5494 b.ReportAllocs() 5495 req := reqBytes(`GET / HTTP/1.1 5496 Host: golang.org 5497 `) 5498 conn := &rwTestConn{ 5499 Reader: &repeatReader{content: req, count: b.N}, 5500 Writer: io.Discard, 5501 closec: make(chan bool, 1), 5502 } 5503 handled := 0 5504 handler := HandlerFunc(func(rw ResponseWriter, r *Request) { 5505 handled++ 5506 h.ServeHTTP(rw, r) 5507 }) 5508 ln := &oneConnListener{conn: conn} 5509 go func() { 5510 _ = Serve(ln, handler) 5511 }() 5512 <-conn.closec 5513 if b.N != handled { 5514 b.Errorf("b.N=%d but handled %d", b.N, handled) 5515 } 5516 } 5517 5518 func BenchmarkServerHijack(b *testing.B) { 5519 b.ReportAllocs() 5520 req := reqBytes(`GET / HTTP/1.1 5521 Host: golang.org 5522 `) 5523 h := HandlerFunc(func(w ResponseWriter, r *Request) { 5524 conn, _, err := w.(Hijacker).Hijack() 5525 if err != nil { 5526 panic(err) 5527 } 5528 _ = conn.Close() 5529 }) 5530 conn := &rwTestConn{ 5531 Writer: io.Discard, 5532 closec: make(chan bool, 1), 5533 } 5534 ln := &oneConnListener{conn: conn} 5535 for i := 0; i < b.N; i++ { 5536 conn.Reader = bytes.NewReader(req) 5537 ln.conn = conn 5538 _ = Serve(ln, h) 5539 <-conn.closec 5540 } 5541 } 5542 5543 func BenchmarkCloseNotifier(b *testing.B) { 5544 b.ReportAllocs() 5545 b.StopTimer() 5546 sawClose := make(chan bool) 5547 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 5548 <-rw.(CloseNotifier).CloseNotify() 5549 sawClose <- true 5550 })) 5551 defer ts.Close() 5552 tot := time.NewTimer(5 * time.Second) 5553 defer tot.Stop() 5554 b.StartTimer() 5555 for i := 0; i < b.N; i++ { 5556 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 5557 if err != nil { 5558 b.Fatalf("error dialing: %v", err) 5559 } 5560 _, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n") 5561 if err != nil { 5562 b.Fatal(err) 5563 } 5564 _ = conn.Close() 5565 tot.Reset(5 * time.Second) 5566 select { 5567 case <-sawClose: 5568 case <-tot.C: 5569 b.Fatal("timeout") 5570 } 5571 } 5572 b.StopTimer() 5573 } 5574 5575 // Verify this doesn't race (Issue 16505) 5576 func TestConcurrentServerServe(t *testing.T) { 5577 setParallel(t) 5578 for i := 0; i < 100; i++ { 5579 ln1 := &oneConnListener{conn: nil} 5580 ln2 := &oneConnListener{conn: nil} 5581 srv := Server{} 5582 go func() { 5583 _ = srv.Serve(ln1) 5584 }() 5585 go func() { 5586 _ = srv.Serve(ln2) 5587 }() 5588 } 5589 } 5590 5591 func TestServerIdleTimeout(t *testing.T) { 5592 if testing.Short() { 5593 t.Skip("skipping in short mode") 5594 } 5595 setParallel(t) 5596 defer afterTest(t) 5597 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5598 _, _ = io.Copy(io.Discard, r.Body) 5599 _, _ = io.WriteString(w, r.RemoteAddr) 5600 })) 5601 ts.Config.ReadHeaderTimeout = 1 * time.Second 5602 ts.Config.IdleTimeout = 2 * time.Second 5603 ts.Start() 5604 defer ts.Close() 5605 c := ts.Client() 5606 5607 get := func() string { 5608 res, err := c.Get(ts.URL) 5609 if err != nil { 5610 t.Fatal(err) 5611 } 5612 defer func(Body io.ReadCloser) { 5613 _ = Body.Close() 5614 }(res.Body) 5615 slurp, err := io.ReadAll(res.Body) 5616 if err != nil { 5617 t.Fatal(err) 5618 } 5619 return string(slurp) 5620 } 5621 5622 a1, a2 := get(), get() 5623 if a1 != a2 { 5624 t.Fatalf("did requests on different connections") 5625 } 5626 time.Sleep(3 * time.Second) 5627 a3 := get() 5628 if a2 == a3 { 5629 t.Fatal("request three unexpectedly on same connection") 5630 } 5631 5632 // And test that ReadHeaderTimeout still works: 5633 conn, err := net.Dial("tcp", ts.Listener.Addr().String()) 5634 if err != nil { 5635 t.Fatal(err) 5636 } 5637 defer func(conn net.Conn) { 5638 _ = conn.Close() 5639 }(conn) 5640 _, _ = conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo.com\r\n")) 5641 time.Sleep(2 * time.Second) 5642 if _, err := io.CopyN(io.Discard, conn, 1); err == nil { 5643 t.Fatal("copy byte succeeded; want err") 5644 } 5645 } 5646 5647 func get(t *testing.T, c *Client, url string) string { 5648 res, err := c.Get(url) 5649 if err != nil { 5650 t.Fatal(err) 5651 } 5652 defer func(Body io.ReadCloser) { 5653 _ = Body.Close() 5654 }(res.Body) 5655 slurp, err := io.ReadAll(res.Body) 5656 if err != nil { 5657 t.Fatal(err) 5658 } 5659 return string(slurp) 5660 } 5661 5662 // Tests that calls to Server.SetKeepAlivesEnabled(false) closes any 5663 // currently-open connections. 5664 func TestServerSetKeepAlivesEnabledClosesConns(t *testing.T) { 5665 setParallel(t) 5666 defer afterTest(t) 5667 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5668 _, _ = io.WriteString(w, r.RemoteAddr) 5669 })) 5670 defer ts.Close() 5671 5672 c := ts.Client() 5673 tr := c.Transport.(*Transport) 5674 5675 get := func() string { return get(t, c, ts.URL) } 5676 5677 a1, a2 := get(), get() 5678 if a1 != a2 { 5679 t.Fatal("expected first two requests on same connection") 5680 } 5681 //goland:noinspection HttpUrlsUsage 5682 addr := strings.TrimPrefix(ts.URL, "http://") 5683 5684 // The two requests should have used the same connection, 5685 // and there should not have been a second connection that 5686 // was created by racing dial against reuse. 5687 // (The first get was completed when the second get started.) 5688 n := tr.IdleConnCountForTesting("http", addr) 5689 if n != 1 { 5690 t.Fatalf("idle count for %q after 2 gets = %d, want 1", addr, n) 5691 } 5692 5693 // SetKeepAlivesEnabled should discard idle conns. 5694 ts.Config.SetKeepAlivesEnabled(false) 5695 5696 var idle1 int 5697 if !waitCondition(2*time.Second, 10*time.Millisecond, func() bool { 5698 idle1 = tr.IdleConnCountForTesting("http", addr) 5699 return idle1 == 0 5700 }) { 5701 t.Fatalf("idle count after SetKeepAlivesEnabled called = %v; want 0", idle1) 5702 } 5703 5704 a3 := get() 5705 if a3 == a2 { 5706 t.Fatal("expected third request on new connection") 5707 } 5708 } 5709 5710 func TestServerShutdown_h1(t *testing.T) { 5711 testServerShutdown(t, h1Mode) 5712 } 5713 func TestServerShutdown_h2(t *testing.T) { 5714 testServerShutdown(t, h2Mode) 5715 } 5716 5717 func testServerShutdown(t *testing.T, h2 bool) { 5718 setParallel(t) 5719 defer afterTest(t) 5720 var doShutdown func() // set later 5721 var doStateCount func() 5722 var shutdownRes = make(chan error, 1) 5723 var statesRes = make(chan map[ConnState]int, 1) 5724 var gotOnShutdown = make(chan struct{}, 1) 5725 handler := HandlerFunc(func(w ResponseWriter, r *Request) { 5726 doStateCount() 5727 go doShutdown() 5728 // Shutdown is graceful, so it should not interrupt 5729 // this in-flight response. Add a tiny sleep here to 5730 // increase the odds of a failure if shutdown has 5731 // bugs. 5732 time.Sleep(20 * time.Millisecond) 5733 _, _ = io.WriteString(w, r.RemoteAddr) 5734 }) 5735 cst := newClientServerTest(t, h2, handler, func(srv *httptest.Server) { 5736 srv.Config.RegisterOnShutdown(func() { gotOnShutdown <- struct{}{} }) 5737 }) 5738 defer cst.close() 5739 5740 doShutdown = func() { 5741 shutdownRes <- cst.ts.Config.Shutdown(context.Background()) 5742 } 5743 doStateCount = func() { 5744 statesRes <- cst.ts.Config.ExportAllConnsByState() 5745 } 5746 get(t, cst.c, cst.ts.URL) // calls t.Fail on failure 5747 5748 if err := <-shutdownRes; err != nil { 5749 t.Fatalf("Shutdown: %v", err) 5750 } 5751 select { 5752 case <-gotOnShutdown: 5753 case <-time.After(5 * time.Second): 5754 t.Errorf("onShutdown callback not called, RegisterOnShutdown broken?") 5755 } 5756 5757 if states := <-statesRes; states[StateActive] != 1 { 5758 t.Errorf("connection in wrong state, %v", states) 5759 } 5760 5761 res, err := cst.c.Get(cst.ts.URL) 5762 if err == nil { 5763 _ = res.Body.Close() 5764 t.Fatal("second request should fail. server should be shut down") 5765 } 5766 } 5767 5768 func TestServerShutdownStateNew(t *testing.T) { 5769 if testing.Short() { 5770 t.Skip("test takes 5-6 seconds; skipping in short mode") 5771 } 5772 setParallel(t) 5773 defer afterTest(t) 5774 5775 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5776 // nothing. 5777 })) 5778 var connAccepted sync.WaitGroup 5779 ts.Config.ConnState = func(conn net.Conn, state ConnState) { 5780 if state == StateNew { 5781 connAccepted.Done() 5782 } 5783 } 5784 ts.Start() 5785 defer ts.Close() 5786 5787 // Start a connection but never write to it. 5788 connAccepted.Add(1) 5789 c, err := net.Dial("tcp", ts.Listener.Addr().String()) 5790 if err != nil { 5791 t.Fatal(err) 5792 } 5793 defer func(c net.Conn) { 5794 _ = c.Close() 5795 }(c) 5796 5797 // Wait for the connection to be accepted by the server. Otherwise, if 5798 // Shutdown happens to run first, the server will be closed when 5799 // encountering the connection, in which case it will be rejected 5800 // immediately. 5801 connAccepted.Wait() 5802 5803 shutdownRes := make(chan error, 1) 5804 go func() { 5805 shutdownRes <- ts.Config.Shutdown(context.Background()) 5806 }() 5807 readRes := make(chan error, 1) 5808 go func() { 5809 _, err := c.Read([]byte{0}) 5810 readRes <- err 5811 }() 5812 5813 const expectTimeout = 5 * time.Second 5814 t0 := time.Now() 5815 select { 5816 case got := <-shutdownRes: 5817 d := time.Since(t0) 5818 if got != nil { 5819 t.Fatalf("shutdown error after %v: %v", d, err) 5820 } 5821 if d < expectTimeout/2 { 5822 t.Errorf("shutdown too soon after %v", d) 5823 } 5824 case <-time.After(expectTimeout * 3 / 2): 5825 t.Fatalf("timeout waiting for shutdown") 5826 } 5827 5828 // Wait for c.Read to unblock; should be already done at this point, 5829 // or within a few milliseconds. 5830 select { 5831 case err := <-readRes: 5832 if err == nil { 5833 t.Error("expected error from Read") 5834 } 5835 case <-time.After(2 * time.Second): 5836 t.Errorf("timeout waiting for Read to unblock") 5837 } 5838 } 5839 5840 // Issue 17878: tests that we can call Close twice. 5841 func TestServerCloseDeadlock(t *testing.T) { 5842 var s Server 5843 _ = s.Close() 5844 _ = s.Close() 5845 } 5846 5847 // Issue 17717: tests that Server.SetKeepAlivesEnabled is respected by 5848 // both HTTP/1 and HTTP/2. 5849 func TestServerKeepAlivesEnabled_h1(t *testing.T) { testServerKeepAlivesEnabled(t, h1Mode) } 5850 func TestServerKeepAlivesEnabled_h2(t *testing.T) { testServerKeepAlivesEnabled(t, h2Mode) } 5851 func testServerKeepAlivesEnabled(t *testing.T, h2 bool) { 5852 if h2 { 5853 restore := ExportSetH2GoawayTimeout(10 * time.Millisecond) 5854 defer restore() 5855 } 5856 // Not parallel: messes with global variable. (http2goAwayTimeout) 5857 defer afterTest(t) 5858 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 5859 _, _ = fmt.Fprintf(w, "%v", r.RemoteAddr) 5860 })) 5861 defer cst.close() 5862 srv := cst.ts.Config 5863 srv.SetKeepAlivesEnabled(false) 5864 a := cst.getURL(cst.ts.URL) 5865 if !waitCondition(2*time.Second, 10*time.Millisecond, srv.ExportAllConnsIdle) { 5866 t.Fatalf("test server has active conns") 5867 } 5868 b := cst.getURL(cst.ts.URL) 5869 if a == b { 5870 t.Errorf("got same connection between first and second requests") 5871 } 5872 if !waitCondition(2*time.Second, 10*time.Millisecond, srv.ExportAllConnsIdle) { 5873 t.Fatalf("test server has active conns") 5874 } 5875 } 5876 5877 // Issue 18447: test that the Server's ReadTimeout is stopped while 5878 // the server's doing its 1-byte background read between requests, 5879 // waiting for the connection to maybe close. 5880 func TestServerCancelsReadTimeoutWhenIdle(t *testing.T) { 5881 setParallel(t) 5882 defer afterTest(t) 5883 runTimeSensitiveTest(t, []time.Duration{ 5884 10 * time.Millisecond, 5885 50 * time.Millisecond, 5886 250 * time.Millisecond, 5887 time.Second, 5888 2 * time.Second, 5889 }, func(t *testing.T, timeout time.Duration) error { 5890 ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 5891 select { 5892 case <-time.After(2 * timeout): 5893 _, _ = fmt.Fprint(w, "ok") 5894 case <-r.Context().Done(): 5895 _, _ = fmt.Fprint(w, r.Context().Err()) 5896 } 5897 })) 5898 ts.Config.ReadTimeout = timeout 5899 ts.Start() 5900 defer ts.Close() 5901 5902 c := ts.Client() 5903 5904 res, err := c.Get(ts.URL) 5905 if err != nil { 5906 //goland:noinspection GoErrorStringFormat 5907 return fmt.Errorf("Get: %v", err) 5908 } 5909 slurp, err := io.ReadAll(res.Body) 5910 _ = res.Body.Close() 5911 if err != nil { 5912 //goland:noinspection GoErrorStringFormat 5913 return fmt.Errorf("Body ReadAll: %v", err) 5914 } 5915 if string(slurp) != "ok" { 5916 return fmt.Errorf("got: %q, want ok", slurp) 5917 } 5918 return nil 5919 }) 5920 } 5921 5922 // runTimeSensitiveTest runs test with the provided durations until one passes. 5923 // If they all fail, t.Fatal is called with the last one's duration and error value. 5924 func runTimeSensitiveTest(t *testing.T, durations []time.Duration, test func(t *testing.T, d time.Duration) error) { 5925 for i, d := range durations { 5926 err := test(t, d) 5927 if err == nil { 5928 return 5929 } 5930 if i == len(durations)-1 { 5931 t.Fatalf("failed with duration %v: %v", d, err) 5932 } 5933 } 5934 } 5935 5936 // Issue 18535: test that the Server doesn't try to do a background 5937 // read if it's already done one. 5938 func TestServerDuplicateBackgroundRead(t *testing.T) { 5939 if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm" { 5940 testenv.SkipFlaky(t, 24826) 5941 } 5942 5943 setParallel(t) 5944 defer afterTest(t) 5945 5946 goroutines := 5 5947 requests := 2000 5948 if testing.Short() { 5949 goroutines = 3 5950 requests = 100 5951 } 5952 5953 hts := httptest.NewServer(HandlerFunc(NotFound)) 5954 defer hts.Close() 5955 5956 reqBytes := []byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n") 5957 5958 var wg sync.WaitGroup 5959 for i := 0; i < goroutines; i++ { 5960 wg.Add(1) 5961 go func() { 5962 defer wg.Done() 5963 cn, err := net.Dial("tcp", hts.Listener.Addr().String()) 5964 if err != nil { 5965 t.Error(err) 5966 return 5967 } 5968 defer func(cn net.Conn) { 5969 _ = cn.Close() 5970 }(cn) 5971 5972 wg.Add(1) 5973 go func() { 5974 defer wg.Done() 5975 _, _ = io.Copy(io.Discard, cn) 5976 }() 5977 5978 for j := 0; j < requests; j++ { 5979 if t.Failed() { 5980 return 5981 } 5982 _, err := cn.Write(reqBytes) 5983 if err != nil { 5984 t.Error(err) 5985 return 5986 } 5987 } 5988 }() 5989 } 5990 wg.Wait() 5991 } 5992 5993 // Test that the bufio.Reader returned by Hijack includes any buffered 5994 // byte (from the Server's backgroundRead) in its buffer. We want the 5995 // Handler code to be able to tell that a byte is available via 5996 // bufio.Reader.Buffered(), without resorting to Reading it 5997 // (potentially blocking) to get at it. 5998 func TestServerHijackGetsBackgroundByte(t *testing.T) { 5999 if runtime.GOOS == "plan9" { 6000 t.Skip("skipping test; see https://golang.org/issue/18657") 6001 } 6002 setParallel(t) 6003 defer afterTest(t) 6004 done := make(chan struct{}) 6005 inHandler := make(chan bool, 1) 6006 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 6007 defer close(done) 6008 6009 // Tell the client to send more data after the GET request. 6010 inHandler <- true 6011 6012 conn, buf, err := w.(Hijacker).Hijack() 6013 if err != nil { 6014 t.Error(err) 6015 return 6016 } 6017 defer func(conn net.Conn) { 6018 _ = conn.Close() 6019 }(conn) 6020 6021 peek, err := buf.Reader.Peek(3) 6022 if string(peek) != "foo" || err != nil { 6023 t.Errorf("Peek = %q, %v; want foo, nil", peek, err) 6024 } 6025 6026 select { 6027 case <-r.Context().Done(): 6028 t.Error("context unexpectedly canceled") 6029 default: 6030 } 6031 })) 6032 defer ts.Close() 6033 6034 cn, err := net.Dial("tcp", ts.Listener.Addr().String()) 6035 if err != nil { 6036 t.Fatal(err) 6037 } 6038 defer func(cn net.Conn) { 6039 _ = cn.Close() 6040 }(cn) 6041 if _, err := cn.Write([]byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n")); err != nil { 6042 t.Fatal(err) 6043 } 6044 <-inHandler 6045 if _, err := cn.Write([]byte("foo")); err != nil { 6046 t.Fatal(err) 6047 } 6048 6049 if err := cn.(*net.TCPConn).CloseWrite(); err != nil { 6050 t.Fatal(err) 6051 } 6052 select { 6053 case <-done: 6054 case <-time.After(2 * time.Second): 6055 t.Error("timeout") 6056 } 6057 } 6058 6059 // Like TestServerHijackGetsBackgroundByte above but sending a 6060 // immediate 1MB of data to the server to fill up the server's 4KB 6061 // buffer. 6062 func TestServerHijackGetsBackgroundByte_big(t *testing.T) { 6063 if runtime.GOOS == "plan9" { 6064 t.Skip("skipping test; see https://golang.org/issue/18657") 6065 } 6066 setParallel(t) 6067 defer afterTest(t) 6068 done := make(chan struct{}) 6069 const size = 8 << 10 6070 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 6071 defer close(done) 6072 6073 conn, buf, err := w.(Hijacker).Hijack() 6074 if err != nil { 6075 t.Error(err) 6076 return 6077 } 6078 defer func(conn net.Conn) { 6079 _ = conn.Close() 6080 }(conn) 6081 slurp, err := io.ReadAll(buf.Reader) 6082 if err != nil { 6083 t.Errorf("Copy: %v", err) 6084 } 6085 allX := true 6086 for _, v := range slurp { 6087 if v != 'x' { 6088 allX = false 6089 } 6090 } 6091 if len(slurp) != size { 6092 t.Errorf("read %d; want %d", len(slurp), size) 6093 } else if !allX { 6094 t.Errorf("read %q; want %d 'x'", slurp, size) 6095 } 6096 })) 6097 defer ts.Close() 6098 6099 cn, err := net.Dial("tcp", ts.Listener.Addr().String()) 6100 if err != nil { 6101 t.Fatal(err) 6102 } 6103 defer func(cn net.Conn) { 6104 _ = cn.Close() 6105 }(cn) 6106 if _, err := fmt.Fprintf(cn, "GET / HTTP/1.1\r\nHost: e.com\r\n\r\n%s", 6107 strings.Repeat("x", size)); err != nil { 6108 t.Fatal(err) 6109 } 6110 if err := cn.(*net.TCPConn).CloseWrite(); err != nil { 6111 t.Fatal(err) 6112 } 6113 6114 select { 6115 case <-done: 6116 case <-time.After(2 * time.Second): 6117 t.Error("timeout") 6118 } 6119 } 6120 6121 // Issue 18319: test that the Server validates the request method. 6122 func TestServerValidatesMethod(t *testing.T) { 6123 tests := []struct { 6124 method string 6125 want int 6126 }{ 6127 {"GET", 200}, 6128 {"GE(T", 400}, 6129 } 6130 for _, tt := range tests { 6131 conn := &testConn{closec: make(chan bool, 1)} 6132 _, _ = io.WriteString(&conn.readBuf, tt.method+" / HTTP/1.1\r\nHost: foo.example\r\n\r\n") 6133 6134 ln := &oneConnListener{conn} 6135 go func() { 6136 _ = Serve(ln, serve(200)) 6137 }() 6138 <-conn.closec 6139 res, err := ReadResponse(bufio.NewReader(&conn.writeBuf), nil) 6140 if err != nil { 6141 t.Errorf("For %s, ReadResponse: %v", tt.method, res) 6142 continue 6143 } 6144 if res.StatusCode != tt.want { 6145 t.Errorf("For %s, Status = %d; want %d", tt.method, res.StatusCode, tt.want) 6146 } 6147 } 6148 } 6149 6150 // Listener for TestServerListenNotComparableListener. 6151 type eofListenerNotComparable []int 6152 6153 func (eofListenerNotComparable) Accept() (net.Conn, error) { return nil, io.EOF } 6154 func (eofListenerNotComparable) Addr() net.Addr { return nil } 6155 func (eofListenerNotComparable) Close() error { return nil } 6156 6157 // Issue 24812: don't crash on non-comparable Listener 6158 func TestServerListenNotComparableListener(t *testing.T) { 6159 var s Server 6160 _ = s.Serve(make(eofListenerNotComparable, 1)) // used to panic 6161 } 6162 6163 // countCloseListener is a Listener wrapper that counts the number of Close calls. 6164 type countCloseListener struct { 6165 net.Listener 6166 closes int32 // atomic 6167 } 6168 6169 func (p *countCloseListener) Close() error { 6170 var err error 6171 if n := atomic.AddInt32(&p.closes, 1); n == 1 && p.Listener != nil { 6172 err = p.Listener.Close() 6173 } 6174 return err 6175 } 6176 6177 // Issue 24803: don't call Listener.Close on Server.Shutdown. 6178 func TestServerCloseListenerOnce(t *testing.T) { 6179 setParallel(t) 6180 defer afterTest(t) 6181 6182 ln := newLocalListener(t) 6183 defer func(ln net.Listener) { 6184 _ = ln.Close() 6185 }(ln) 6186 6187 cl := &countCloseListener{Listener: ln} 6188 server := &Server{} 6189 sdone := make(chan bool, 1) 6190 6191 go func() { 6192 _ = server.Serve(cl) 6193 sdone <- true 6194 }() 6195 time.Sleep(10 * time.Millisecond) 6196 _ = server.Shutdown(context.Background()) 6197 _ = ln.Close() 6198 <-sdone 6199 6200 nclose := atomic.LoadInt32(&cl.closes) 6201 if nclose != 1 { 6202 t.Errorf("Close calls = %v; want 1", nclose) 6203 } 6204 } 6205 6206 // Issue 20239: don't block in Serve if Shutdown is called first. 6207 func TestServerShutdownThenServe(t *testing.T) { 6208 var srv Server 6209 cl := &countCloseListener{Listener: nil} 6210 _ = srv.Shutdown(context.Background()) 6211 got := srv.Serve(cl) 6212 if got != ErrServerClosed { 6213 t.Errorf("Serve err = %v; want ErrServerClosed", got) 6214 } 6215 nclose := atomic.LoadInt32(&cl.closes) 6216 if nclose != 1 { 6217 t.Errorf("Close calls = %v; want 1", nclose) 6218 } 6219 } 6220 6221 // Issue 23351: document and test behavior of ServeMux with ports 6222 func TestStripPortFromHost(t *testing.T) { 6223 mux := NewServeMux() 6224 6225 mux.HandleFunc("example.com/", func(w ResponseWriter, r *Request) { 6226 _, _ = fmt.Fprintf(w, "OK") 6227 }) 6228 mux.HandleFunc("example.com:9000/", func(w ResponseWriter, r *Request) { 6229 _, _ = fmt.Fprintf(w, "uh-oh!") 6230 }) 6231 6232 //goland:noinspection HttpUrlsUsage 6233 req := httptest.NewRequest("GET", "http://example.com:9000/", nil) 6234 rw := httptest.NewRecorder() 6235 6236 mux.ServeHTTP(rw, req) 6237 6238 response := rw.Body.String() 6239 if response != "OK" { 6240 t.Errorf("Response gotten was %q", response) 6241 } 6242 } 6243 6244 func TestServerContexts(t *testing.T) { 6245 setParallel(t) 6246 defer afterTest(t) 6247 type baseKey struct{} 6248 type connKey struct{} 6249 ch := make(chan context.Context, 1) 6250 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 6251 ch <- r.Context() 6252 })) 6253 ts.Config.BaseContext = func(ln net.Listener) context.Context { 6254 if strings.Contains(reflect.TypeOf(ln).String(), "onceClose") { 6255 t.Errorf("unexpected onceClose listener type %T", ln) 6256 } 6257 return context.WithValue(context.Background(), baseKey{}, "base") 6258 } 6259 ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { 6260 if got, want := ctx.Value(baseKey{}), "base"; got != want { 6261 t.Errorf("in ConnContext, base context key = %#v; want %q", got, want) 6262 } 6263 return context.WithValue(ctx, connKey{}, "conn") 6264 } 6265 ts.Start() 6266 defer ts.Close() 6267 res, err := ts.Client().Get(ts.URL) 6268 if err != nil { 6269 t.Fatal(err) 6270 } 6271 _ = res.Body.Close() 6272 ctx := <-ch 6273 if got, want := ctx.Value(baseKey{}), "base"; got != want { 6274 t.Errorf("base context key = %#v; want %q", got, want) 6275 } 6276 if got, want := ctx.Value(connKey{}), "conn"; got != want { 6277 t.Errorf("conn context key = %#v; want %q", got, want) 6278 } 6279 } 6280 6281 func TestServerContextsHTTP2(t *testing.T) { 6282 setParallel(t) 6283 defer afterTest(t) 6284 type baseKey struct{} 6285 type connKey struct{} 6286 ch := make(chan context.Context, 1) 6287 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 6288 if r.ProtoMajor != 2 { 6289 t.Errorf("unexpected HTTP/1.x request") 6290 } 6291 ch <- r.Context() 6292 })) 6293 ts.Config.BaseContext = func(ln net.Listener) context.Context { 6294 if strings.Contains(reflect.TypeOf(ln).String(), "onceClose") { 6295 t.Errorf("unexpected onceClose listener type %T", ln) 6296 } 6297 return context.WithValue(context.Background(), baseKey{}, "base") 6298 } 6299 ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { 6300 if got, want := ctx.Value(baseKey{}), "base"; got != want { 6301 t.Errorf("in ConnContext, base context key = %#v; want %q", got, want) 6302 } 6303 return context.WithValue(ctx, connKey{}, "conn") 6304 } 6305 ts.TLS = &tls.Config{ 6306 NextProtos: []string{"h2", "http/1.1"}, 6307 } 6308 ts.StartTLS() 6309 defer ts.Close() 6310 ts.Client().Transport.(*Transport).ForceAttemptHTTP2 = true 6311 res, err := ts.Client().Get(ts.URL) 6312 if err != nil { 6313 t.Fatal(err) 6314 } 6315 _ = res.Body.Close() 6316 ctx := <-ch 6317 if got, want := ctx.Value(baseKey{}), "base"; got != want { 6318 t.Errorf("base context key = %#v; want %q", got, want) 6319 } 6320 if got, want := ctx.Value(connKey{}), "conn"; got != want { 6321 t.Errorf("conn context key = %#v; want %q", got, want) 6322 } 6323 } 6324 6325 // Issue 35750: check ConnContext not modifying context for other connections 6326 func TestConnContextNotModifyingAllContexts(t *testing.T) { 6327 setParallel(t) 6328 defer afterTest(t) 6329 type connKey struct{} 6330 ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { 6331 rw.Header().Set("Connection", "close") 6332 })) 6333 ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { 6334 if got := ctx.Value(connKey{}); got != nil { 6335 t.Errorf("in ConnContext, unexpected context key = %#v", got) 6336 } 6337 return context.WithValue(ctx, connKey{}, "conn") 6338 } 6339 ts.Start() 6340 defer ts.Close() 6341 6342 var res *Response 6343 var err error 6344 6345 res, err = ts.Client().Get(ts.URL) 6346 if err != nil { 6347 t.Fatal(err) 6348 } 6349 _ = res.Body.Close() 6350 6351 res, err = ts.Client().Get(ts.URL) 6352 if err != nil { 6353 t.Fatal(err) 6354 } 6355 _ = res.Body.Close() 6356 } 6357 6358 // Issue 30710: ensure that as per the spec, a server responds 6359 // with 501 Not Implemented for unsupported transfer-encodings. 6360 func TestUnsupportedTransferEncodingsReturn501(t *testing.T) { 6361 cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 6362 _, _ = w.Write([]byte("Hello, World!")) 6363 })) 6364 defer cst.Close() 6365 6366 serverURL, err := url.Parse(cst.URL) 6367 if err != nil { 6368 t.Fatalf("Failed to parse server URL: %v", err) 6369 } 6370 6371 unsupportedTEs := []string{ 6372 "fugazi", 6373 "foo-bar", 6374 "unknown", 6375 } 6376 6377 for _, badTE := range unsupportedTEs { 6378 http1ReqBody := fmt.Sprintf(""+ 6379 "POST / HTTP/1.1\r\nConnection: close\r\n"+ 6380 "Host: localhost\r\nTransfer-Encoding: %s\r\n\r\n", badTE) 6381 6382 gotBody, err := fetchWireResponse(serverURL.Host, []byte(http1ReqBody)) 6383 if err != nil { 6384 t.Errorf("%q. unexpected error: %v", badTE, err) 6385 continue 6386 } 6387 6388 wantBody := fmt.Sprintf("" + 6389 "HTTP/1.1 501 Not Implemented\r\nContent-Type: text/plain; charset=utf-8\r\n" + 6390 "Connection: close\r\n\r\nUnsupported transfer encoding") 6391 6392 if string(gotBody) != wantBody { 6393 t.Errorf("%q. body\ngot\n%q\nwant\n%q", badTE, gotBody, wantBody) 6394 } 6395 } 6396 } 6397 6398 func TestContentEncodingNoSniffing_h1(t *testing.T) { 6399 testContentEncodingNoSniffing(t, h1Mode) 6400 } 6401 6402 func TestContentEncodingNoSniffing_h2(t *testing.T) { 6403 testContentEncodingNoSniffing(t, h2Mode) 6404 } 6405 6406 // Issue 31753: don't sniff when Content-Encoding is set 6407 func testContentEncodingNoSniffing(t *testing.T, h2 bool) { 6408 setParallel(t) 6409 defer afterTest(t) 6410 6411 type setting struct { 6412 name string 6413 body []byte 6414 6415 // setting contentEncoding as an interface instead of a string 6416 // directly, so as to differentiate between 3 states: 6417 // unset, empty string "" and set string "foo/bar". 6418 contentEncoding interface{} 6419 wantContentType string 6420 } 6421 6422 settings := []*setting{ 6423 { 6424 name: "gzip content-encoding, gzipped", // don't sniff. 6425 contentEncoding: "application/gzip", 6426 wantContentType: "", 6427 body: func() []byte { 6428 buf := new(bytes.Buffer) 6429 gzw := gzip.NewWriter(buf) 6430 _, _ = gzw.Write([]byte("doctype html><p>Hello</p>")) 6431 _ = gzw.Close() 6432 return buf.Bytes() 6433 }(), 6434 }, 6435 { 6436 name: "zlib content-encoding, zlibbed", // don't sniff. 6437 contentEncoding: "application/zlib", 6438 wantContentType: "", 6439 body: func() []byte { 6440 buf := new(bytes.Buffer) 6441 zw := zlib.NewWriter(buf) 6442 _, _ = zw.Write([]byte("doctype html><p>Hello</p>")) 6443 _ = zw.Close() 6444 return buf.Bytes() 6445 }(), 6446 }, 6447 { 6448 name: "no content-encoding", // must sniff. 6449 wantContentType: "application/x-gzip", 6450 body: func() []byte { 6451 buf := new(bytes.Buffer) 6452 gzw := gzip.NewWriter(buf) 6453 _, _ = gzw.Write([]byte("doctype html><p>Hello</p>")) 6454 _ = gzw.Close() 6455 return buf.Bytes() 6456 }(), 6457 }, 6458 { 6459 name: "phony content-encoding", // don't sniff. 6460 contentEncoding: "foo/bar", 6461 body: []byte("doctype html><p>Hello</p>"), 6462 }, 6463 { 6464 name: "empty but set content-encoding", 6465 contentEncoding: "", 6466 wantContentType: "audio/mpeg", 6467 body: []byte("ID3"), 6468 }, 6469 } 6470 6471 for _, tt := range settings { 6472 t.Run(tt.name, func(t *testing.T) { 6473 cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, r *Request) { 6474 if tt.contentEncoding != nil { 6475 rw.Header().Set("Content-Encoding", tt.contentEncoding.(string)) 6476 } 6477 _, _ = rw.Write(tt.body) 6478 })) 6479 defer cst.close() 6480 6481 res, err := cst.c.Get(cst.ts.URL) 6482 if err != nil { 6483 t.Fatalf("Failed to fetch URL: %v", err) 6484 } 6485 defer func(Body io.ReadCloser) { 6486 _ = Body.Close() 6487 }(res.Body) 6488 6489 if g, w := res.Header.Get("Content-Encoding"), tt.contentEncoding; g != w { 6490 if w != nil { // The case where contentEncoding was set explicitly. 6491 t.Errorf("Content-Encoding mismatch\n\tgot: %q\n\twant: %q", g, w) 6492 } else if g != "" { // "" should be the equivalent when the contentEncoding is unset. 6493 t.Errorf("Unexpected Content-Encoding %q", g) 6494 } 6495 } 6496 6497 if g, w := res.Header.Get("Content-Type"), tt.wantContentType; g != w { 6498 t.Errorf("Content-Type mismatch\n\tgot: %q\n\twant: %q", g, w) 6499 } 6500 }) 6501 } 6502 } 6503 6504 // Issue 30803: ensure that TimeoutHandler logs spurious 6505 // WriteHeader calls, for consistency with other Handlers. 6506 func TestTimeoutHandlerSuperfluousLogs(t *testing.T) { 6507 if testing.Short() { 6508 t.Skip("skipping in short mode") 6509 } 6510 6511 setParallel(t) 6512 defer afterTest(t) 6513 6514 pc, curFile, _, _ := runtime.Caller(0) 6515 curFileBaseName := filepath.Base(curFile) 6516 testFuncName := runtime.FuncForPC(pc).Name() 6517 6518 timeoutMsg := "timed out here!" 6519 6520 tests := []struct { 6521 name string 6522 mustTimeout bool 6523 wantResp string 6524 }{ 6525 { 6526 name: "return before timeout", 6527 wantResp: "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n", 6528 }, 6529 { 6530 name: "return after timeout", 6531 mustTimeout: true, 6532 wantResp: fmt.Sprintf("HTTP/1.1 503 Service Unavailable\r\nContent-Length: %d\r\n\r\n%s", 6533 len(timeoutMsg), timeoutMsg), 6534 }, 6535 } 6536 6537 for _, tt := range tests { 6538 tt := tt 6539 t.Run(tt.name, func(t *testing.T) { 6540 exitHandler := make(chan bool, 1) 6541 defer close(exitHandler) 6542 lastLine := make(chan int, 1) 6543 6544 sh := HandlerFunc(func(w ResponseWriter, r *Request) { 6545 w.WriteHeader(404) 6546 w.WriteHeader(404) 6547 w.WriteHeader(404) 6548 w.WriteHeader(404) 6549 _, _, line, _ := runtime.Caller(0) 6550 lastLine <- line 6551 <-exitHandler 6552 }) 6553 6554 if !tt.mustTimeout { 6555 exitHandler <- true 6556 } 6557 6558 logBuf := new(bytes.Buffer) 6559 srvLog := log.New(logBuf, "", 0) 6560 // When expecting to timeout, we'll keep the duration short. 6561 dur := 20 * time.Millisecond 6562 if !tt.mustTimeout { 6563 // Otherwise, make it arbitrarily long to reduce the risk of flakes. 6564 dur = 10 * time.Second 6565 } 6566 th := TimeoutHandler(sh, dur, timeoutMsg) 6567 cst := newClientServerTest(t, h1Mode /* the test is protocol-agnostic */, th, optWithServerLog(srvLog)) 6568 defer cst.close() 6569 6570 res, err := cst.c.Get(cst.ts.URL) 6571 if err != nil { 6572 t.Fatalf("Unexpected error: %v", err) 6573 } 6574 6575 // Deliberately removing the "Date" header since it is highly ephemeral 6576 // and will cause failure if we try to match it exactly. 6577 res.Header.Del("Date") 6578 res.Header.Del("Content-Type") 6579 6580 // Match the response. 6581 blob, _ := httputil.DumpResponse(res, true) 6582 if g, w := string(blob), tt.wantResp; g != w { 6583 t.Errorf("Response mismatch\nGot\n%q\n\nWant\n%q", g, w) 6584 } 6585 6586 // Given 4 w.WriteHeader calls, only the first one is valid 6587 // and the rest should be reported as the 3 spurious logs. 6588 logEntries := strings.Split(strings.TrimSpace(logBuf.String()), "\n") 6589 if g, w := len(logEntries), 3; g != w { 6590 blob, _ := json.MarshalIndent(logEntries, "", " ") 6591 t.Fatalf("Server logs count mismatch\ngot %d, want %d\n\nGot\n%s\n", g, w, blob) 6592 } 6593 6594 lastSpuriousLine := <-lastLine 6595 firstSpuriousLine := lastSpuriousLine - 3 6596 // Now ensure that the regexes match exactly. 6597 // "http: superfluous response.WriteHeader call from <fn>.func\d.\d (<curFile>:lastSpuriousLine-[1, 3]" 6598 for i, logEntry := range logEntries { 6599 wantLine := firstSpuriousLine + i 6600 pat := fmt.Sprintf("^http: superfluous response.WriteHeader call from %s.func\\d+.\\d+ \\(%s:%d\\)$", 6601 testFuncName, curFileBaseName, wantLine) 6602 re := regexp.MustCompile(pat) 6603 if !re.MatchString(logEntry) { 6604 t.Errorf("Log entry mismatch\n\t%s\ndoes not match\n\t%s", logEntry, pat) 6605 } 6606 } 6607 }) 6608 } 6609 } 6610 6611 // fetchWireResponse is a helper for dialing to host, 6612 // sending http1ReqBody as the payload and retrieving 6613 // the response as it was sent on the wire. 6614 func fetchWireResponse(host string, http1ReqBody []byte) ([]byte, error) { 6615 conn, err := net.Dial("tcp", host) 6616 if err != nil { 6617 return nil, err 6618 } 6619 defer func(conn net.Conn) { 6620 _ = conn.Close() 6621 }(conn) 6622 6623 if _, err := conn.Write(http1ReqBody); err != nil { 6624 return nil, err 6625 } 6626 return io.ReadAll(conn) 6627 } 6628 6629 func BenchmarkResponseStatusLine(b *testing.B) { 6630 b.ReportAllocs() 6631 b.RunParallel(func(pb *testing.PB) { 6632 bw := bufio.NewWriter(io.Discard) 6633 var buf3 [3]byte 6634 for pb.Next() { 6635 Export_writeStatusLine(bw, true, 200, buf3[:]) 6636 } 6637 }) 6638 } 6639 func TestDisableKeepAliveUpgrade(t *testing.T) { 6640 if testing.Short() { 6641 t.Skip("skipping in short mode") 6642 } 6643 6644 setParallel(t) 6645 defer afterTest(t) 6646 6647 s := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { 6648 w.Header().Set("Connection", "Upgrade") 6649 w.Header().Set("Upgrade", "someProto") 6650 w.WriteHeader(StatusSwitchingProtocols) 6651 c, buf, err := w.(Hijacker).Hijack() 6652 if err != nil { 6653 return 6654 } 6655 defer func(c net.Conn) { 6656 _ = c.Close() 6657 }(c) 6658 6659 // Copy from the *bufio.ReadWriter, which may contain buffered data. 6660 // Copy to the net.Conn, to avoid buffering the output. 6661 _, _ = io.Copy(c, buf) 6662 })) 6663 s.Config.SetKeepAlivesEnabled(false) 6664 s.Start() 6665 defer s.Close() 6666 6667 cl := s.Client() 6668 cl.Transport.(*Transport).DisableKeepAlives = true 6669 6670 resp, err := cl.Get(s.URL) 6671 if err != nil { 6672 t.Fatalf("failed to perform request: %v", err) 6673 } 6674 defer func(Body io.ReadCloser) { 6675 _ = Body.Close() 6676 }(resp.Body) 6677 6678 if resp.StatusCode != StatusSwitchingProtocols { 6679 t.Fatalf("unexpected status code: %v", resp.StatusCode) 6680 } 6681 6682 rwc, ok := resp.Body.(io.ReadWriteCloser) 6683 if !ok { 6684 t.Fatalf("Response.Body is not a io.ReadWriteCloser: %T", resp.Body) 6685 } 6686 6687 _, err = rwc.Write([]byte("hello")) 6688 if err != nil { 6689 t.Fatalf("failed to write to body: %v", err) 6690 } 6691 6692 b := make([]byte, 5) 6693 _, err = io.ReadFull(rwc, b) 6694 if err != nil { 6695 t.Fatalf("failed to read from body: %v", err) 6696 } 6697 6698 if string(b) != "hello" { 6699 t.Fatalf("unexpected value read from body:\ngot: %q\nwant: %q", b, "hello") 6700 } 6701 } 6702 6703 func TestMuxRedirectRelative(t *testing.T) { 6704 setParallel(t) 6705 //goland:noinspection HttpUrlsUsage 6706 req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET http://example.com HTTP/1.1\r\nHost: test\r\n\r\n"))) 6707 if err != nil { 6708 t.Errorf("%s", err) 6709 } 6710 mux := NewServeMux() 6711 resp := httptest.NewRecorder() 6712 mux.ServeHTTP(resp, req) 6713 if got, want := resp.Header().Get("Location"), "/"; got != want { 6714 t.Errorf("Location header expected %q; got %q", want, got) 6715 } 6716 if got, want := resp.Code, StatusMovedPermanently; got != want { 6717 t.Errorf("Expected response code %d; got %d", want, got) 6718 } 6719 } 6720 6721 // TestQuerySemicolon tests the behavior of semicolons in queries. See Issue 25192. 6722 //goland:noinspection GoBoolExpressions 6723 func TestQuerySemicolon(t *testing.T) { 6724 t.Cleanup(func() { afterTest(t) }) 6725 6726 tests := []struct { 6727 query string 6728 xNoSemicolons string 6729 xWithSemicolons string 6730 warning bool 6731 }{ 6732 {"?a=1;x=bad&x=good", "good", "bad", true}, 6733 {"?a=1;b=bad&x=good", "good", "good", true}, 6734 {"?a=1%3Bx=bad&x=good%3B", "good;", "good;", false}, 6735 {"?a=1;x=good;x=bad", "", "good", true}, 6736 } 6737 6738 for _, tt := range tests { 6739 t.Run(tt.query+"/allow=false", func(t *testing.T) { 6740 allowSemicolons := false 6741 testQuerySemicolon(t, tt.query, tt.xNoSemicolons, allowSemicolons, tt.warning) 6742 }) 6743 t.Run(tt.query+"/allow=true", func(t *testing.T) { 6744 allowSemicolons, expectWarning := true, false 6745 testQuerySemicolon(t, tt.query, tt.xWithSemicolons, allowSemicolons, expectWarning) 6746 }) 6747 } 6748 } 6749 6750 func testQuerySemicolon(t *testing.T, query string, wantX string, allowSemicolons, expectWarning bool) { 6751 setParallel(t) 6752 6753 writeBackX := func(w ResponseWriter, r *Request) { 6754 x := r.URL.Query().Get("x") 6755 if expectWarning { 6756 if err := r.ParseForm(); err == nil || !strings.Contains(err.Error(), "semicolon") { 6757 t.Errorf("expected error mentioning semicolons from ParseForm, got %v", err) 6758 } 6759 } else { 6760 if err := r.ParseForm(); err != nil { 6761 t.Errorf("expected no error from ParseForm, got %v", err) 6762 } 6763 } 6764 if got := r.FormValue("x"); x != got { 6765 t.Errorf("got %q from FormValue, want %q", got, x) 6766 } 6767 _, _ = fmt.Fprintf(w, "%s", x) 6768 } 6769 6770 h := Handler(HandlerFunc(writeBackX)) 6771 if allowSemicolons { 6772 h = AllowQuerySemicolons(h) 6773 } 6774 6775 ts := httptest.NewUnstartedServer(h) 6776 logBuf := &bytes.Buffer{} 6777 ts.Config.ErrorLog = log.New(logBuf, "", 0) 6778 ts.Start() 6779 defer ts.Close() 6780 6781 req, _ := NewRequest("GET", ts.URL+query, nil) 6782 res, err := ts.Client().Do(req) 6783 if err != nil { 6784 t.Fatal(err) 6785 } 6786 slurp, _ := io.ReadAll(res.Body) 6787 _ = res.Body.Close() 6788 if got, want := res.StatusCode, 200; got != want { 6789 t.Errorf("Status = %d; want = %d", got, want) 6790 } 6791 if got, want := string(slurp), wantX; got != want { 6792 t.Errorf("Body = %q; want = %q", got, want) 6793 } 6794 6795 if expectWarning { 6796 if !strings.Contains(logBuf.String(), "semicolon") { 6797 t.Errorf("got %q from ErrorLog, expected a mention of semicolons", logBuf.String()) 6798 } 6799 } else { 6800 if strings.Contains(logBuf.String(), "semicolon") { 6801 t.Errorf("got %q from ErrorLog, expected no mention of semicolons", logBuf.String()) 6802 } 6803 } 6804 }