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