github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/net/http/transport_test.go (about) 1 // Copyright 2011 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 // Tests for transport.go. 6 // 7 // More tests are in clientserver_test.go (for things testing both client & server for both 8 // HTTP/1 and HTTP/2). This 9 10 package http_test 11 12 import ( 13 "bufio" 14 "bytes" 15 "compress/gzip" 16 "crypto/rand" 17 "crypto/tls" 18 "errors" 19 "fmt" 20 "io" 21 "io/ioutil" 22 "log" 23 "net" 24 . "net/http" 25 "net/http/httptest" 26 "net/http/httputil" 27 "net/url" 28 "os" 29 "reflect" 30 "runtime" 31 "strconv" 32 "strings" 33 "sync" 34 "testing" 35 "time" 36 ) 37 38 // TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close 39 // and then verify that the final 2 responses get errors back. 40 41 // hostPortHandler writes back the client's "host:port". 42 var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) { 43 if r.FormValue("close") == "true" { 44 w.Header().Set("Connection", "close") 45 } 46 w.Header().Set("X-Saw-Close", fmt.Sprint(r.Close)) 47 w.Write([]byte(r.RemoteAddr)) 48 }) 49 50 // testCloseConn is a net.Conn tracked by a testConnSet. 51 type testCloseConn struct { 52 net.Conn 53 set *testConnSet 54 } 55 56 func (c *testCloseConn) Close() error { 57 c.set.remove(c) 58 return c.Conn.Close() 59 } 60 61 // testConnSet tracks a set of TCP connections and whether they've 62 // been closed. 63 type testConnSet struct { 64 t *testing.T 65 mu sync.Mutex // guards closed and list 66 closed map[net.Conn]bool 67 list []net.Conn // in order created 68 } 69 70 func (tcs *testConnSet) insert(c net.Conn) { 71 tcs.mu.Lock() 72 defer tcs.mu.Unlock() 73 tcs.closed[c] = false 74 tcs.list = append(tcs.list, c) 75 } 76 77 func (tcs *testConnSet) remove(c net.Conn) { 78 tcs.mu.Lock() 79 defer tcs.mu.Unlock() 80 tcs.closed[c] = true 81 } 82 83 // some tests use this to manage raw tcp connections for later inspection 84 func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) { 85 connSet := &testConnSet{ 86 t: t, 87 closed: make(map[net.Conn]bool), 88 } 89 dial := func(n, addr string) (net.Conn, error) { 90 c, err := net.Dial(n, addr) 91 if err != nil { 92 return nil, err 93 } 94 tc := &testCloseConn{c, connSet} 95 connSet.insert(tc) 96 return tc, nil 97 } 98 return connSet, dial 99 } 100 101 func (tcs *testConnSet) check(t *testing.T) { 102 tcs.mu.Lock() 103 defer tcs.mu.Unlock() 104 for i := 4; i >= 0; i-- { 105 for i, c := range tcs.list { 106 if tcs.closed[c] { 107 continue 108 } 109 if i != 0 { 110 tcs.mu.Unlock() 111 time.Sleep(50 * time.Millisecond) 112 tcs.mu.Lock() 113 continue 114 } 115 t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list)) 116 } 117 } 118 } 119 120 // Two subsequent requests and verify their response is the same. 121 // The response from the server is our own IP:port 122 func TestTransportKeepAlives(t *testing.T) { 123 defer afterTest(t) 124 ts := httptest.NewServer(hostPortHandler) 125 defer ts.Close() 126 127 for _, disableKeepAlive := range []bool{false, true} { 128 tr := &Transport{DisableKeepAlives: disableKeepAlive} 129 defer tr.CloseIdleConnections() 130 c := &Client{Transport: tr} 131 132 fetch := func(n int) string { 133 res, err := c.Get(ts.URL) 134 if err != nil { 135 t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err) 136 } 137 body, err := ioutil.ReadAll(res.Body) 138 if err != nil { 139 t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err) 140 } 141 return string(body) 142 } 143 144 body1 := fetch(1) 145 body2 := fetch(2) 146 147 bodiesDiffer := body1 != body2 148 if bodiesDiffer != disableKeepAlive { 149 t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q", 150 disableKeepAlive, bodiesDiffer, body1, body2) 151 } 152 } 153 } 154 155 func TestTransportConnectionCloseOnResponse(t *testing.T) { 156 defer afterTest(t) 157 ts := httptest.NewServer(hostPortHandler) 158 defer ts.Close() 159 160 connSet, testDial := makeTestDial(t) 161 162 for _, connectionClose := range []bool{false, true} { 163 tr := &Transport{ 164 Dial: testDial, 165 } 166 c := &Client{Transport: tr} 167 168 fetch := func(n int) string { 169 req := new(Request) 170 var err error 171 req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose)) 172 if err != nil { 173 t.Fatalf("URL parse error: %v", err) 174 } 175 req.Method = "GET" 176 req.Proto = "HTTP/1.1" 177 req.ProtoMajor = 1 178 req.ProtoMinor = 1 179 180 res, err := c.Do(req) 181 if err != nil { 182 t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err) 183 } 184 defer res.Body.Close() 185 body, err := ioutil.ReadAll(res.Body) 186 if err != nil { 187 t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err) 188 } 189 return string(body) 190 } 191 192 body1 := fetch(1) 193 body2 := fetch(2) 194 bodiesDiffer := body1 != body2 195 if bodiesDiffer != connectionClose { 196 t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q", 197 connectionClose, bodiesDiffer, body1, body2) 198 } 199 200 tr.CloseIdleConnections() 201 } 202 203 connSet.check(t) 204 } 205 206 func TestTransportConnectionCloseOnRequest(t *testing.T) { 207 defer afterTest(t) 208 ts := httptest.NewServer(hostPortHandler) 209 defer ts.Close() 210 211 connSet, testDial := makeTestDial(t) 212 213 for _, connectionClose := range []bool{false, true} { 214 tr := &Transport{ 215 Dial: testDial, 216 } 217 c := &Client{Transport: tr} 218 219 fetch := func(n int) string { 220 req := new(Request) 221 var err error 222 req.URL, err = url.Parse(ts.URL) 223 if err != nil { 224 t.Fatalf("URL parse error: %v", err) 225 } 226 req.Method = "GET" 227 req.Proto = "HTTP/1.1" 228 req.ProtoMajor = 1 229 req.ProtoMinor = 1 230 req.Close = connectionClose 231 232 res, err := c.Do(req) 233 if err != nil { 234 t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err) 235 } 236 if got, want := res.Header.Get("X-Saw-Close"), fmt.Sprint(connectionClose); got != want { 237 t.Errorf("For connectionClose = %v; handler's X-Saw-Close was %v; want %v", 238 connectionClose, got, !connectionClose) 239 } 240 body, err := ioutil.ReadAll(res.Body) 241 if err != nil { 242 t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err) 243 } 244 return string(body) 245 } 246 247 body1 := fetch(1) 248 body2 := fetch(2) 249 bodiesDiffer := body1 != body2 250 if bodiesDiffer != connectionClose { 251 t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q", 252 connectionClose, bodiesDiffer, body1, body2) 253 } 254 255 tr.CloseIdleConnections() 256 } 257 258 connSet.check(t) 259 } 260 261 // if the Transport's DisableKeepAlives is set, all requests should 262 // send Connection: close. 263 // HTTP/1-only (Connection: close doesn't exist in h2) 264 func TestTransportConnectionCloseOnRequestDisableKeepAlive(t *testing.T) { 265 defer afterTest(t) 266 ts := httptest.NewServer(hostPortHandler) 267 defer ts.Close() 268 269 tr := &Transport{ 270 DisableKeepAlives: true, 271 } 272 c := &Client{Transport: tr} 273 res, err := c.Get(ts.URL) 274 if err != nil { 275 t.Fatal(err) 276 } 277 res.Body.Close() 278 if res.Header.Get("X-Saw-Close") != "true" { 279 t.Errorf("handler didn't see Connection: close ") 280 } 281 } 282 283 func TestTransportIdleCacheKeys(t *testing.T) { 284 defer afterTest(t) 285 ts := httptest.NewServer(hostPortHandler) 286 defer ts.Close() 287 288 tr := &Transport{DisableKeepAlives: false} 289 c := &Client{Transport: tr} 290 291 if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g { 292 t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g) 293 } 294 295 resp, err := c.Get(ts.URL) 296 if err != nil { 297 t.Error(err) 298 } 299 ioutil.ReadAll(resp.Body) 300 301 keys := tr.IdleConnKeysForTesting() 302 if e, g := 1, len(keys); e != g { 303 t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g) 304 } 305 306 if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e { 307 t.Errorf("Expected idle cache key %q; got %q", e, keys[0]) 308 } 309 310 tr.CloseIdleConnections() 311 if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g { 312 t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g) 313 } 314 } 315 316 // Tests that the HTTP transport re-uses connections when a client 317 // reads to the end of a response Body without closing it. 318 func TestTransportReadToEndReusesConn(t *testing.T) { 319 defer afterTest(t) 320 const msg = "foobar" 321 322 var addrSeen map[string]int 323 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 324 addrSeen[r.RemoteAddr]++ 325 if r.URL.Path == "/chunked/" { 326 w.WriteHeader(200) 327 w.(Flusher).Flush() 328 } else { 329 w.Header().Set("Content-Type", strconv.Itoa(len(msg))) 330 w.WriteHeader(200) 331 } 332 w.Write([]byte(msg)) 333 })) 334 defer ts.Close() 335 336 buf := make([]byte, len(msg)) 337 338 for pi, path := range []string{"/content-length/", "/chunked/"} { 339 wantLen := []int{len(msg), -1}[pi] 340 addrSeen = make(map[string]int) 341 for i := 0; i < 3; i++ { 342 res, err := Get(ts.URL + path) 343 if err != nil { 344 t.Errorf("Get %s: %v", path, err) 345 continue 346 } 347 // We want to close this body eventually (before the 348 // defer afterTest at top runs), but not before the 349 // len(addrSeen) check at the bottom of this test, 350 // since Closing this early in the loop would risk 351 // making connections be re-used for the wrong reason. 352 defer res.Body.Close() 353 354 if res.ContentLength != int64(wantLen) { 355 t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen) 356 } 357 n, err := res.Body.Read(buf) 358 if n != len(msg) || err != io.EOF { 359 t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg)) 360 } 361 } 362 if len(addrSeen) != 1 { 363 t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen)) 364 } 365 } 366 } 367 368 func TestTransportMaxPerHostIdleConns(t *testing.T) { 369 defer afterTest(t) 370 resch := make(chan string) 371 gotReq := make(chan bool) 372 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 373 gotReq <- true 374 msg := <-resch 375 _, err := w.Write([]byte(msg)) 376 if err != nil { 377 t.Fatalf("Write: %v", err) 378 } 379 })) 380 defer ts.Close() 381 maxIdleConns := 2 382 tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns} 383 c := &Client{Transport: tr} 384 385 // Start 3 outstanding requests and wait for the server to get them. 386 // Their responses will hang until we write to resch, though. 387 donech := make(chan bool) 388 doReq := func() { 389 resp, err := c.Get(ts.URL) 390 if err != nil { 391 t.Error(err) 392 return 393 } 394 if _, err := ioutil.ReadAll(resp.Body); err != nil { 395 t.Errorf("ReadAll: %v", err) 396 return 397 } 398 donech <- true 399 } 400 go doReq() 401 <-gotReq 402 go doReq() 403 <-gotReq 404 go doReq() 405 <-gotReq 406 407 if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g { 408 t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g) 409 } 410 411 resch <- "res1" 412 <-donech 413 keys := tr.IdleConnKeysForTesting() 414 if e, g := 1, len(keys); e != g { 415 t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g) 416 } 417 cacheKey := "|http|" + ts.Listener.Addr().String() 418 if keys[0] != cacheKey { 419 t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0]) 420 } 421 if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g { 422 t.Errorf("after first response, expected %d idle conns; got %d", e, g) 423 } 424 425 resch <- "res2" 426 <-donech 427 if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g { 428 t.Errorf("after second response, expected %d idle conns; got %d", e, g) 429 } 430 431 resch <- "res3" 432 <-donech 433 if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g { 434 t.Errorf("after third response, still expected %d idle conns; got %d", e, g) 435 } 436 } 437 438 func TestTransportServerClosingUnexpectedly(t *testing.T) { 439 defer afterTest(t) 440 ts := httptest.NewServer(hostPortHandler) 441 defer ts.Close() 442 443 tr := &Transport{} 444 c := &Client{Transport: tr} 445 446 fetch := func(n, retries int) string { 447 condFatalf := func(format string, arg ...interface{}) { 448 if retries <= 0 { 449 t.Fatalf(format, arg...) 450 } 451 t.Logf("retrying shortly after expected error: "+format, arg...) 452 time.Sleep(time.Second / time.Duration(retries)) 453 } 454 for retries >= 0 { 455 retries-- 456 res, err := c.Get(ts.URL) 457 if err != nil { 458 condFatalf("error in req #%d, GET: %v", n, err) 459 continue 460 } 461 body, err := ioutil.ReadAll(res.Body) 462 if err != nil { 463 condFatalf("error in req #%d, ReadAll: %v", n, err) 464 continue 465 } 466 res.Body.Close() 467 return string(body) 468 } 469 panic("unreachable") 470 } 471 472 body1 := fetch(1, 0) 473 body2 := fetch(2, 0) 474 475 ts.CloseClientConnections() // surprise! 476 477 // This test has an expected race. Sleeping for 25 ms prevents 478 // it on most fast machines, causing the next fetch() call to 479 // succeed quickly. But if we do get errors, fetch() will retry 5 480 // times with some delays between. 481 time.Sleep(25 * time.Millisecond) 482 483 body3 := fetch(3, 5) 484 485 if body1 != body2 { 486 t.Errorf("expected body1 and body2 to be equal") 487 } 488 if body2 == body3 { 489 t.Errorf("expected body2 and body3 to be different") 490 } 491 } 492 493 // Test for https://golang.org/issue/2616 (appropriate issue number) 494 // This fails pretty reliably with GOMAXPROCS=100 or something high. 495 func TestStressSurpriseServerCloses(t *testing.T) { 496 defer afterTest(t) 497 if testing.Short() { 498 t.Skip("skipping test in short mode") 499 } 500 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 501 w.Header().Set("Content-Length", "5") 502 w.Header().Set("Content-Type", "text/plain") 503 w.Write([]byte("Hello")) 504 w.(Flusher).Flush() 505 conn, buf, _ := w.(Hijacker).Hijack() 506 buf.Flush() 507 conn.Close() 508 })) 509 defer ts.Close() 510 511 tr := &Transport{DisableKeepAlives: false} 512 c := &Client{Transport: tr} 513 defer tr.CloseIdleConnections() 514 515 // Do a bunch of traffic from different goroutines. Send to activityc 516 // after each request completes, regardless of whether it failed. 517 // If these are too high, OS X exhausts its ephemeral ports 518 // and hangs waiting for them to transition TCP states. That's 519 // not what we want to test. TODO(bradfitz): use an io.Pipe 520 // dialer for this test instead? 521 const ( 522 numClients = 20 523 reqsPerClient = 25 524 ) 525 activityc := make(chan bool) 526 for i := 0; i < numClients; i++ { 527 go func() { 528 for i := 0; i < reqsPerClient; i++ { 529 res, err := c.Get(ts.URL) 530 if err == nil { 531 // We expect errors since the server is 532 // hanging up on us after telling us to 533 // send more requests, so we don't 534 // actually care what the error is. 535 // But we want to close the body in cases 536 // where we won the race. 537 res.Body.Close() 538 } 539 activityc <- true 540 } 541 }() 542 } 543 544 // Make sure all the request come back, one way or another. 545 for i := 0; i < numClients*reqsPerClient; i++ { 546 select { 547 case <-activityc: 548 case <-time.After(5 * time.Second): 549 t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile") 550 } 551 } 552 } 553 554 // TestTransportHeadResponses verifies that we deal with Content-Lengths 555 // with no bodies properly 556 func TestTransportHeadResponses(t *testing.T) { 557 defer afterTest(t) 558 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 559 if r.Method != "HEAD" { 560 panic("expected HEAD; got " + r.Method) 561 } 562 w.Header().Set("Content-Length", "123") 563 w.WriteHeader(200) 564 })) 565 defer ts.Close() 566 567 tr := &Transport{DisableKeepAlives: false} 568 c := &Client{Transport: tr} 569 for i := 0; i < 2; i++ { 570 res, err := c.Head(ts.URL) 571 if err != nil { 572 t.Errorf("error on loop %d: %v", i, err) 573 continue 574 } 575 if e, g := "123", res.Header.Get("Content-Length"); e != g { 576 t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g) 577 } 578 if e, g := int64(123), res.ContentLength; e != g { 579 t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g) 580 } 581 if all, err := ioutil.ReadAll(res.Body); err != nil { 582 t.Errorf("loop %d: Body ReadAll: %v", i, err) 583 } else if len(all) != 0 { 584 t.Errorf("Bogus body %q", all) 585 } 586 } 587 } 588 589 // TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding 590 // on responses to HEAD requests. 591 func TestTransportHeadChunkedResponse(t *testing.T) { 592 defer afterTest(t) 593 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 594 if r.Method != "HEAD" { 595 panic("expected HEAD; got " + r.Method) 596 } 597 w.Header().Set("Transfer-Encoding", "chunked") // client should ignore 598 w.Header().Set("x-client-ipport", r.RemoteAddr) 599 w.WriteHeader(200) 600 })) 601 defer ts.Close() 602 603 tr := &Transport{DisableKeepAlives: false} 604 c := &Client{Transport: tr} 605 defer tr.CloseIdleConnections() 606 607 // Ensure that we wait for the readLoop to complete before 608 // calling Head again 609 didRead := make(chan bool) 610 SetReadLoopBeforeNextReadHook(func() { didRead <- true }) 611 defer SetReadLoopBeforeNextReadHook(nil) 612 613 res1, err := c.Head(ts.URL) 614 <-didRead 615 616 if err != nil { 617 t.Fatalf("request 1 error: %v", err) 618 } 619 620 res2, err := c.Head(ts.URL) 621 <-didRead 622 623 if err != nil { 624 t.Fatalf("request 2 error: %v", err) 625 } 626 if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 { 627 t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2) 628 } 629 } 630 631 var roundTripTests = []struct { 632 accept string 633 expectAccept string 634 compressed bool 635 }{ 636 // Requests with no accept-encoding header use transparent compression 637 {"", "gzip", false}, 638 // Requests with other accept-encoding should pass through unmodified 639 {"foo", "foo", false}, 640 // Requests with accept-encoding == gzip should be passed through 641 {"gzip", "gzip", true}, 642 } 643 644 // Test that the modification made to the Request by the RoundTripper is cleaned up 645 func TestRoundTripGzip(t *testing.T) { 646 defer afterTest(t) 647 const responseBody = "test response body" 648 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 649 accept := req.Header.Get("Accept-Encoding") 650 if expect := req.FormValue("expect_accept"); accept != expect { 651 t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q", 652 req.FormValue("testnum"), accept, expect) 653 } 654 if accept == "gzip" { 655 rw.Header().Set("Content-Encoding", "gzip") 656 gz := gzip.NewWriter(rw) 657 gz.Write([]byte(responseBody)) 658 gz.Close() 659 } else { 660 rw.Header().Set("Content-Encoding", accept) 661 rw.Write([]byte(responseBody)) 662 } 663 })) 664 defer ts.Close() 665 666 for i, test := range roundTripTests { 667 // Test basic request (no accept-encoding) 668 req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil) 669 if test.accept != "" { 670 req.Header.Set("Accept-Encoding", test.accept) 671 } 672 res, err := DefaultTransport.RoundTrip(req) 673 var body []byte 674 if test.compressed { 675 var r *gzip.Reader 676 r, err = gzip.NewReader(res.Body) 677 if err != nil { 678 t.Errorf("%d. gzip NewReader: %v", i, err) 679 continue 680 } 681 body, err = ioutil.ReadAll(r) 682 res.Body.Close() 683 } else { 684 body, err = ioutil.ReadAll(res.Body) 685 } 686 if err != nil { 687 t.Errorf("%d. Error: %q", i, err) 688 continue 689 } 690 if g, e := string(body), responseBody; g != e { 691 t.Errorf("%d. body = %q; want %q", i, g, e) 692 } 693 if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e { 694 t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e) 695 } 696 if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e { 697 t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e) 698 } 699 } 700 701 } 702 703 func TestTransportGzip(t *testing.T) { 704 defer afterTest(t) 705 const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 706 const nRandBytes = 1024 * 1024 707 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 708 if req.Method == "HEAD" { 709 if g := req.Header.Get("Accept-Encoding"); g != "" { 710 t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g) 711 } 712 return 713 } 714 if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e { 715 t.Errorf("Accept-Encoding = %q, want %q", g, e) 716 } 717 rw.Header().Set("Content-Encoding", "gzip") 718 719 var w io.Writer = rw 720 var buf bytes.Buffer 721 if req.FormValue("chunked") == "0" { 722 w = &buf 723 defer io.Copy(rw, &buf) 724 defer func() { 725 rw.Header().Set("Content-Length", strconv.Itoa(buf.Len())) 726 }() 727 } 728 gz := gzip.NewWriter(w) 729 gz.Write([]byte(testString)) 730 if req.FormValue("body") == "large" { 731 io.CopyN(gz, rand.Reader, nRandBytes) 732 } 733 gz.Close() 734 })) 735 defer ts.Close() 736 737 for _, chunked := range []string{"1", "0"} { 738 c := &Client{Transport: &Transport{}} 739 740 // First fetch something large, but only read some of it. 741 res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked) 742 if err != nil { 743 t.Fatalf("large get: %v", err) 744 } 745 buf := make([]byte, len(testString)) 746 n, err := io.ReadFull(res.Body, buf) 747 if err != nil { 748 t.Fatalf("partial read of large response: size=%d, %v", n, err) 749 } 750 if e, g := testString, string(buf); e != g { 751 t.Errorf("partial read got %q, expected %q", g, e) 752 } 753 res.Body.Close() 754 // Read on the body, even though it's closed 755 n, err = res.Body.Read(buf) 756 if n != 0 || err == nil { 757 t.Errorf("expected error post-closed large Read; got = %d, %v", n, err) 758 } 759 760 // Then something small. 761 res, err = c.Get(ts.URL + "/?chunked=" + chunked) 762 if err != nil { 763 t.Fatal(err) 764 } 765 body, err := ioutil.ReadAll(res.Body) 766 if err != nil { 767 t.Fatal(err) 768 } 769 if g, e := string(body), testString; g != e { 770 t.Fatalf("body = %q; want %q", g, e) 771 } 772 if g, e := res.Header.Get("Content-Encoding"), ""; g != e { 773 t.Fatalf("Content-Encoding = %q; want %q", g, e) 774 } 775 776 // Read on the body after it's been fully read: 777 n, err = res.Body.Read(buf) 778 if n != 0 || err == nil { 779 t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err) 780 } 781 res.Body.Close() 782 n, err = res.Body.Read(buf) 783 if n != 0 || err == nil { 784 t.Errorf("expected Read error after Close; got %d, %v", n, err) 785 } 786 } 787 788 // And a HEAD request too, because they're always weird. 789 c := &Client{Transport: &Transport{}} 790 res, err := c.Head(ts.URL) 791 if err != nil { 792 t.Fatalf("Head: %v", err) 793 } 794 if res.StatusCode != 200 { 795 t.Errorf("Head status=%d; want=200", res.StatusCode) 796 } 797 } 798 799 // If a request has Expect:100-continue header, the request blocks sending body until the first response. 800 // Premature consumption of the request body should not be occurred. 801 func TestTransportExpect100Continue(t *testing.T) { 802 defer afterTest(t) 803 804 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 805 switch req.URL.Path { 806 case "/100": 807 // This endpoint implicitly responds 100 Continue and reads body. 808 if _, err := io.Copy(ioutil.Discard, req.Body); err != nil { 809 t.Error("Failed to read Body", err) 810 } 811 rw.WriteHeader(StatusOK) 812 case "/200": 813 // Go 1.5 adds Connection: close header if the client expect 814 // continue but not entire request body is consumed. 815 rw.WriteHeader(StatusOK) 816 case "/500": 817 rw.WriteHeader(StatusInternalServerError) 818 case "/keepalive": 819 // This hijacked endpoint responds error without Connection:close. 820 _, bufrw, err := rw.(Hijacker).Hijack() 821 if err != nil { 822 log.Fatal(err) 823 } 824 bufrw.WriteString("HTTP/1.1 500 Internal Server Error\r\n") 825 bufrw.WriteString("Content-Length: 0\r\n\r\n") 826 bufrw.Flush() 827 case "/timeout": 828 // This endpoint tries to read body without 100 (Continue) response. 829 // After ExpectContinueTimeout, the reading will be started. 830 conn, bufrw, err := rw.(Hijacker).Hijack() 831 if err != nil { 832 log.Fatal(err) 833 } 834 if _, err := io.CopyN(ioutil.Discard, bufrw, req.ContentLength); err != nil { 835 t.Error("Failed to read Body", err) 836 } 837 bufrw.WriteString("HTTP/1.1 200 OK\r\n\r\n") 838 bufrw.Flush() 839 conn.Close() 840 } 841 842 })) 843 defer ts.Close() 844 845 tests := []struct { 846 path string 847 body []byte 848 sent int 849 status int 850 }{ 851 {path: "/100", body: []byte("hello"), sent: 5, status: 200}, // Got 100 followed by 200, entire body is sent. 852 {path: "/200", body: []byte("hello"), sent: 0, status: 200}, // Got 200 without 100. body isn't sent. 853 {path: "/500", body: []byte("hello"), sent: 0, status: 500}, // Got 500 without 100. body isn't sent. 854 {path: "/keepalive", body: []byte("hello"), sent: 0, status: 500}, // Althogh without Connection:close, body isn't sent. 855 {path: "/timeout", body: []byte("hello"), sent: 5, status: 200}, // Timeout exceeded and entire body is sent. 856 } 857 858 for i, v := range tests { 859 tr := &Transport{ExpectContinueTimeout: 2 * time.Second} 860 defer tr.CloseIdleConnections() 861 c := &Client{Transport: tr} 862 863 body := bytes.NewReader(v.body) 864 req, err := NewRequest("PUT", ts.URL+v.path, body) 865 if err != nil { 866 t.Fatal(err) 867 } 868 req.Header.Set("Expect", "100-continue") 869 req.ContentLength = int64(len(v.body)) 870 871 resp, err := c.Do(req) 872 if err != nil { 873 t.Fatal(err) 874 } 875 resp.Body.Close() 876 877 sent := len(v.body) - body.Len() 878 if v.status != resp.StatusCode { 879 t.Errorf("test %d: status code should be %d but got %d. (%s)", i, v.status, resp.StatusCode, v.path) 880 } 881 if v.sent != sent { 882 t.Errorf("test %d: sent body should be %d but sent %d. (%s)", i, v.sent, sent, v.path) 883 } 884 } 885 } 886 887 func TestTransportProxy(t *testing.T) { 888 defer afterTest(t) 889 ch := make(chan string, 1) 890 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 891 ch <- "real server" 892 })) 893 defer ts.Close() 894 proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 895 ch <- "proxy for " + r.URL.String() 896 })) 897 defer proxy.Close() 898 899 pu, err := url.Parse(proxy.URL) 900 if err != nil { 901 t.Fatal(err) 902 } 903 c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}} 904 c.Head(ts.URL) 905 got := <-ch 906 want := "proxy for " + ts.URL + "/" 907 if got != want { 908 t.Errorf("want %q, got %q", want, got) 909 } 910 } 911 912 // TestTransportGzipRecursive sends a gzip quine and checks that the 913 // client gets the same value back. This is more cute than anything, 914 // but checks that we don't recurse forever, and checks that 915 // Content-Encoding is removed. 916 func TestTransportGzipRecursive(t *testing.T) { 917 defer afterTest(t) 918 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 919 w.Header().Set("Content-Encoding", "gzip") 920 w.Write(rgz) 921 })) 922 defer ts.Close() 923 924 c := &Client{Transport: &Transport{}} 925 res, err := c.Get(ts.URL) 926 if err != nil { 927 t.Fatal(err) 928 } 929 body, err := ioutil.ReadAll(res.Body) 930 if err != nil { 931 t.Fatal(err) 932 } 933 if !bytes.Equal(body, rgz) { 934 t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x", 935 body, rgz) 936 } 937 if g, e := res.Header.Get("Content-Encoding"), ""; g != e { 938 t.Fatalf("Content-Encoding = %q; want %q", g, e) 939 } 940 } 941 942 // golang.org/issue/7750: request fails when server replies with 943 // a short gzip body 944 func TestTransportGzipShort(t *testing.T) { 945 defer afterTest(t) 946 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 947 w.Header().Set("Content-Encoding", "gzip") 948 w.Write([]byte{0x1f, 0x8b}) 949 })) 950 defer ts.Close() 951 952 tr := &Transport{} 953 defer tr.CloseIdleConnections() 954 c := &Client{Transport: tr} 955 res, err := c.Get(ts.URL) 956 if err != nil { 957 t.Fatal(err) 958 } 959 defer res.Body.Close() 960 _, err = ioutil.ReadAll(res.Body) 961 if err == nil { 962 t.Fatal("Expect an error from reading a body.") 963 } 964 if err != io.ErrUnexpectedEOF { 965 t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err) 966 } 967 } 968 969 // tests that persistent goroutine connections shut down when no longer desired. 970 func TestTransportPersistConnLeak(t *testing.T) { 971 defer afterTest(t) 972 gotReqCh := make(chan bool) 973 unblockCh := make(chan bool) 974 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 975 gotReqCh <- true 976 <-unblockCh 977 w.Header().Set("Content-Length", "0") 978 w.WriteHeader(204) 979 })) 980 defer ts.Close() 981 982 tr := &Transport{} 983 c := &Client{Transport: tr} 984 985 n0 := runtime.NumGoroutine() 986 987 const numReq = 25 988 didReqCh := make(chan bool) 989 for i := 0; i < numReq; i++ { 990 go func() { 991 res, err := c.Get(ts.URL) 992 didReqCh <- true 993 if err != nil { 994 t.Errorf("client fetch error: %v", err) 995 return 996 } 997 res.Body.Close() 998 }() 999 } 1000 1001 // Wait for all goroutines to be stuck in the Handler. 1002 for i := 0; i < numReq; i++ { 1003 <-gotReqCh 1004 } 1005 1006 nhigh := runtime.NumGoroutine() 1007 1008 // Tell all handlers to unblock and reply. 1009 for i := 0; i < numReq; i++ { 1010 unblockCh <- true 1011 } 1012 1013 // Wait for all HTTP clients to be done. 1014 for i := 0; i < numReq; i++ { 1015 <-didReqCh 1016 } 1017 1018 tr.CloseIdleConnections() 1019 time.Sleep(100 * time.Millisecond) 1020 runtime.GC() 1021 runtime.GC() // even more. 1022 nfinal := runtime.NumGoroutine() 1023 1024 growth := nfinal - n0 1025 1026 // We expect 0 or 1 extra goroutine, empirically. Allow up to 5. 1027 // Previously we were leaking one per numReq. 1028 if int(growth) > 5 { 1029 t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth) 1030 t.Error("too many new goroutines") 1031 } 1032 } 1033 1034 // golang.org/issue/4531: Transport leaks goroutines when 1035 // request.ContentLength is explicitly short 1036 func TestTransportPersistConnLeakShortBody(t *testing.T) { 1037 defer afterTest(t) 1038 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1039 })) 1040 defer ts.Close() 1041 1042 tr := &Transport{} 1043 c := &Client{Transport: tr} 1044 1045 n0 := runtime.NumGoroutine() 1046 body := []byte("Hello") 1047 for i := 0; i < 20; i++ { 1048 req, err := NewRequest("POST", ts.URL, bytes.NewReader(body)) 1049 if err != nil { 1050 t.Fatal(err) 1051 } 1052 req.ContentLength = int64(len(body) - 2) // explicitly short 1053 _, err = c.Do(req) 1054 if err == nil { 1055 t.Fatal("Expect an error from writing too long of a body.") 1056 } 1057 } 1058 nhigh := runtime.NumGoroutine() 1059 tr.CloseIdleConnections() 1060 time.Sleep(400 * time.Millisecond) 1061 runtime.GC() 1062 nfinal := runtime.NumGoroutine() 1063 1064 growth := nfinal - n0 1065 1066 // We expect 0 or 1 extra goroutine, empirically. Allow up to 5. 1067 // Previously we were leaking one per numReq. 1068 t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth) 1069 if int(growth) > 5 { 1070 t.Error("too many new goroutines") 1071 } 1072 } 1073 1074 // This used to crash; https://golang.org/issue/3266 1075 func TestTransportIdleConnCrash(t *testing.T) { 1076 defer afterTest(t) 1077 tr := &Transport{} 1078 c := &Client{Transport: tr} 1079 1080 unblockCh := make(chan bool, 1) 1081 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1082 <-unblockCh 1083 tr.CloseIdleConnections() 1084 })) 1085 defer ts.Close() 1086 1087 didreq := make(chan bool) 1088 go func() { 1089 res, err := c.Get(ts.URL) 1090 if err != nil { 1091 t.Error(err) 1092 } else { 1093 res.Body.Close() // returns idle conn 1094 } 1095 didreq <- true 1096 }() 1097 unblockCh <- true 1098 <-didreq 1099 } 1100 1101 // Test that the transport doesn't close the TCP connection early, 1102 // before the response body has been read. This was a regression 1103 // which sadly lacked a triggering test. The large response body made 1104 // the old race easier to trigger. 1105 func TestIssue3644(t *testing.T) { 1106 defer afterTest(t) 1107 const numFoos = 5000 1108 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1109 w.Header().Set("Connection", "close") 1110 for i := 0; i < numFoos; i++ { 1111 w.Write([]byte("foo ")) 1112 } 1113 })) 1114 defer ts.Close() 1115 tr := &Transport{} 1116 c := &Client{Transport: tr} 1117 res, err := c.Get(ts.URL) 1118 if err != nil { 1119 t.Fatal(err) 1120 } 1121 defer res.Body.Close() 1122 bs, err := ioutil.ReadAll(res.Body) 1123 if err != nil { 1124 t.Fatal(err) 1125 } 1126 if len(bs) != numFoos*len("foo ") { 1127 t.Errorf("unexpected response length") 1128 } 1129 } 1130 1131 // Test that a client receives a server's reply, even if the server doesn't read 1132 // the entire request body. 1133 func TestIssue3595(t *testing.T) { 1134 defer afterTest(t) 1135 const deniedMsg = "sorry, denied." 1136 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1137 Error(w, deniedMsg, StatusUnauthorized) 1138 })) 1139 defer ts.Close() 1140 tr := &Transport{} 1141 c := &Client{Transport: tr} 1142 res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a')) 1143 if err != nil { 1144 t.Errorf("Post: %v", err) 1145 return 1146 } 1147 got, err := ioutil.ReadAll(res.Body) 1148 if err != nil { 1149 t.Fatalf("Body ReadAll: %v", err) 1150 } 1151 if !strings.Contains(string(got), deniedMsg) { 1152 t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg) 1153 } 1154 } 1155 1156 // From https://golang.org/issue/4454 , 1157 // "client fails to handle requests with no body and chunked encoding" 1158 func TestChunkedNoContent(t *testing.T) { 1159 defer afterTest(t) 1160 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1161 w.WriteHeader(StatusNoContent) 1162 })) 1163 defer ts.Close() 1164 1165 for _, closeBody := range []bool{true, false} { 1166 c := &Client{Transport: &Transport{}} 1167 const n = 4 1168 for i := 1; i <= n; i++ { 1169 res, err := c.Get(ts.URL) 1170 if err != nil { 1171 t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err) 1172 } else { 1173 if closeBody { 1174 res.Body.Close() 1175 } 1176 } 1177 } 1178 } 1179 } 1180 1181 func TestTransportConcurrency(t *testing.T) { 1182 defer afterTest(t) 1183 maxProcs, numReqs := 16, 500 1184 if testing.Short() { 1185 maxProcs, numReqs = 4, 50 1186 } 1187 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) 1188 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1189 fmt.Fprintf(w, "%v", r.FormValue("echo")) 1190 })) 1191 defer ts.Close() 1192 1193 var wg sync.WaitGroup 1194 wg.Add(numReqs) 1195 1196 // Due to the Transport's "socket late binding" (see 1197 // idleConnCh in transport.go), the numReqs HTTP requests 1198 // below can finish with a dial still outstanding. To keep 1199 // the leak checker happy, keep track of pending dials and 1200 // wait for them to finish (and be closed or returned to the 1201 // idle pool) before we close idle connections. 1202 SetPendingDialHooks(func() { wg.Add(1) }, wg.Done) 1203 defer SetPendingDialHooks(nil, nil) 1204 1205 tr := &Transport{} 1206 defer tr.CloseIdleConnections() 1207 1208 c := &Client{Transport: tr} 1209 reqs := make(chan string) 1210 defer close(reqs) 1211 1212 for i := 0; i < maxProcs*2; i++ { 1213 go func() { 1214 for req := range reqs { 1215 res, err := c.Get(ts.URL + "/?echo=" + req) 1216 if err != nil { 1217 t.Errorf("error on req %s: %v", req, err) 1218 wg.Done() 1219 continue 1220 } 1221 all, err := ioutil.ReadAll(res.Body) 1222 if err != nil { 1223 t.Errorf("read error on req %s: %v", req, err) 1224 wg.Done() 1225 continue 1226 } 1227 if string(all) != req { 1228 t.Errorf("body of req %s = %q; want %q", req, all, req) 1229 } 1230 res.Body.Close() 1231 wg.Done() 1232 } 1233 }() 1234 } 1235 for i := 0; i < numReqs; i++ { 1236 reqs <- fmt.Sprintf("request-%d", i) 1237 } 1238 wg.Wait() 1239 } 1240 1241 func TestIssue4191_InfiniteGetTimeout(t *testing.T) { 1242 if runtime.GOOS == "plan9" { 1243 t.Skip("skipping test; see https://golang.org/issue/7237") 1244 } 1245 defer afterTest(t) 1246 const debug = false 1247 mux := NewServeMux() 1248 mux.HandleFunc("/get", func(w ResponseWriter, r *Request) { 1249 io.Copy(w, neverEnding('a')) 1250 }) 1251 ts := httptest.NewServer(mux) 1252 timeout := 100 * time.Millisecond 1253 1254 client := &Client{ 1255 Transport: &Transport{ 1256 Dial: func(n, addr string) (net.Conn, error) { 1257 conn, err := net.Dial(n, addr) 1258 if err != nil { 1259 return nil, err 1260 } 1261 conn.SetDeadline(time.Now().Add(timeout)) 1262 if debug { 1263 conn = NewLoggingConn("client", conn) 1264 } 1265 return conn, nil 1266 }, 1267 DisableKeepAlives: true, 1268 }, 1269 } 1270 1271 getFailed := false 1272 nRuns := 5 1273 if testing.Short() { 1274 nRuns = 1 1275 } 1276 for i := 0; i < nRuns; i++ { 1277 if debug { 1278 println("run", i+1, "of", nRuns) 1279 } 1280 sres, err := client.Get(ts.URL + "/get") 1281 if err != nil { 1282 if !getFailed { 1283 // Make the timeout longer, once. 1284 getFailed = true 1285 t.Logf("increasing timeout") 1286 i-- 1287 timeout *= 10 1288 continue 1289 } 1290 t.Errorf("Error issuing GET: %v", err) 1291 break 1292 } 1293 _, err = io.Copy(ioutil.Discard, sres.Body) 1294 if err == nil { 1295 t.Errorf("Unexpected successful copy") 1296 break 1297 } 1298 } 1299 if debug { 1300 println("tests complete; waiting for handlers to finish") 1301 } 1302 ts.Close() 1303 } 1304 1305 func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) { 1306 if runtime.GOOS == "plan9" { 1307 t.Skip("skipping test; see https://golang.org/issue/7237") 1308 } 1309 defer afterTest(t) 1310 const debug = false 1311 mux := NewServeMux() 1312 mux.HandleFunc("/get", func(w ResponseWriter, r *Request) { 1313 io.Copy(w, neverEnding('a')) 1314 }) 1315 mux.HandleFunc("/put", func(w ResponseWriter, r *Request) { 1316 defer r.Body.Close() 1317 io.Copy(ioutil.Discard, r.Body) 1318 }) 1319 ts := httptest.NewServer(mux) 1320 timeout := 100 * time.Millisecond 1321 1322 client := &Client{ 1323 Transport: &Transport{ 1324 Dial: func(n, addr string) (net.Conn, error) { 1325 conn, err := net.Dial(n, addr) 1326 if err != nil { 1327 return nil, err 1328 } 1329 conn.SetDeadline(time.Now().Add(timeout)) 1330 if debug { 1331 conn = NewLoggingConn("client", conn) 1332 } 1333 return conn, nil 1334 }, 1335 DisableKeepAlives: true, 1336 }, 1337 } 1338 1339 getFailed := false 1340 nRuns := 5 1341 if testing.Short() { 1342 nRuns = 1 1343 } 1344 for i := 0; i < nRuns; i++ { 1345 if debug { 1346 println("run", i+1, "of", nRuns) 1347 } 1348 sres, err := client.Get(ts.URL + "/get") 1349 if err != nil { 1350 if !getFailed { 1351 // Make the timeout longer, once. 1352 getFailed = true 1353 t.Logf("increasing timeout") 1354 i-- 1355 timeout *= 10 1356 continue 1357 } 1358 t.Errorf("Error issuing GET: %v", err) 1359 break 1360 } 1361 req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body) 1362 _, err = client.Do(req) 1363 if err == nil { 1364 sres.Body.Close() 1365 t.Errorf("Unexpected successful PUT") 1366 break 1367 } 1368 sres.Body.Close() 1369 } 1370 if debug { 1371 println("tests complete; waiting for handlers to finish") 1372 } 1373 ts.Close() 1374 } 1375 1376 func TestTransportResponseHeaderTimeout(t *testing.T) { 1377 defer afterTest(t) 1378 if testing.Short() { 1379 t.Skip("skipping timeout test in -short mode") 1380 } 1381 inHandler := make(chan bool, 1) 1382 mux := NewServeMux() 1383 mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) { 1384 inHandler <- true 1385 }) 1386 mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) { 1387 inHandler <- true 1388 time.Sleep(2 * time.Second) 1389 }) 1390 ts := httptest.NewServer(mux) 1391 defer ts.Close() 1392 1393 tr := &Transport{ 1394 ResponseHeaderTimeout: 500 * time.Millisecond, 1395 } 1396 defer tr.CloseIdleConnections() 1397 c := &Client{Transport: tr} 1398 1399 tests := []struct { 1400 path string 1401 want int 1402 wantErr string 1403 }{ 1404 {path: "/fast", want: 200}, 1405 {path: "/slow", wantErr: "timeout awaiting response headers"}, 1406 {path: "/fast", want: 200}, 1407 } 1408 for i, tt := range tests { 1409 res, err := c.Get(ts.URL + tt.path) 1410 select { 1411 case <-inHandler: 1412 case <-time.After(5 * time.Second): 1413 t.Errorf("never entered handler for test index %d, %s", i, tt.path) 1414 continue 1415 } 1416 if err != nil { 1417 uerr, ok := err.(*url.Error) 1418 if !ok { 1419 t.Errorf("error is not an url.Error; got: %#v", err) 1420 continue 1421 } 1422 nerr, ok := uerr.Err.(net.Error) 1423 if !ok { 1424 t.Errorf("error does not satisfy net.Error interface; got: %#v", err) 1425 continue 1426 } 1427 if !nerr.Timeout() { 1428 t.Errorf("want timeout error; got: %q", nerr) 1429 continue 1430 } 1431 if strings.Contains(err.Error(), tt.wantErr) { 1432 continue 1433 } 1434 t.Errorf("%d. unexpected error: %v", i, err) 1435 continue 1436 } 1437 if tt.wantErr != "" { 1438 t.Errorf("%d. no error. expected error: %v", i, tt.wantErr) 1439 continue 1440 } 1441 if res.StatusCode != tt.want { 1442 t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want) 1443 } 1444 } 1445 } 1446 1447 func TestTransportCancelRequest(t *testing.T) { 1448 defer afterTest(t) 1449 if testing.Short() { 1450 t.Skip("skipping test in -short mode") 1451 } 1452 unblockc := make(chan bool) 1453 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1454 fmt.Fprintf(w, "Hello") 1455 w.(Flusher).Flush() // send headers and some body 1456 <-unblockc 1457 })) 1458 defer ts.Close() 1459 defer close(unblockc) 1460 1461 tr := &Transport{} 1462 defer tr.CloseIdleConnections() 1463 c := &Client{Transport: tr} 1464 1465 req, _ := NewRequest("GET", ts.URL, nil) 1466 res, err := c.Do(req) 1467 if err != nil { 1468 t.Fatal(err) 1469 } 1470 go func() { 1471 time.Sleep(1 * time.Second) 1472 tr.CancelRequest(req) 1473 }() 1474 t0 := time.Now() 1475 body, err := ioutil.ReadAll(res.Body) 1476 d := time.Since(t0) 1477 1478 if err != ExportErrRequestCanceled { 1479 t.Errorf("Body.Read error = %v; want errRequestCanceled", err) 1480 } 1481 if string(body) != "Hello" { 1482 t.Errorf("Body = %q; want Hello", body) 1483 } 1484 if d < 500*time.Millisecond { 1485 t.Errorf("expected ~1 second delay; got %v", d) 1486 } 1487 // Verify no outstanding requests after readLoop/writeLoop 1488 // goroutines shut down. 1489 for tries := 5; tries > 0; tries-- { 1490 n := tr.NumPendingRequestsForTesting() 1491 if n == 0 { 1492 break 1493 } 1494 time.Sleep(100 * time.Millisecond) 1495 if tries == 1 { 1496 t.Errorf("pending requests = %d; want 0", n) 1497 } 1498 } 1499 } 1500 1501 func TestTransportCancelRequestInDial(t *testing.T) { 1502 defer afterTest(t) 1503 if testing.Short() { 1504 t.Skip("skipping test in -short mode") 1505 } 1506 var logbuf bytes.Buffer 1507 eventLog := log.New(&logbuf, "", 0) 1508 1509 unblockDial := make(chan bool) 1510 defer close(unblockDial) 1511 1512 inDial := make(chan bool) 1513 tr := &Transport{ 1514 Dial: func(network, addr string) (net.Conn, error) { 1515 eventLog.Println("dial: blocking") 1516 inDial <- true 1517 <-unblockDial 1518 return nil, errors.New("nope") 1519 }, 1520 } 1521 cl := &Client{Transport: tr} 1522 gotres := make(chan bool) 1523 req, _ := NewRequest("GET", "http://something.no-network.tld/", nil) 1524 go func() { 1525 _, err := cl.Do(req) 1526 eventLog.Printf("Get = %v", err) 1527 gotres <- true 1528 }() 1529 1530 select { 1531 case <-inDial: 1532 case <-time.After(5 * time.Second): 1533 t.Fatal("timeout; never saw blocking dial") 1534 } 1535 1536 eventLog.Printf("canceling") 1537 tr.CancelRequest(req) 1538 tr.CancelRequest(req) // used to panic on second call 1539 1540 select { 1541 case <-gotres: 1542 case <-time.After(5 * time.Second): 1543 panic("hang. events are: " + logbuf.String()) 1544 } 1545 1546 got := logbuf.String() 1547 want := `dial: blocking 1548 canceling 1549 Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection 1550 ` 1551 if got != want { 1552 t.Errorf("Got events:\n%s\nWant:\n%s", got, want) 1553 } 1554 } 1555 1556 func TestCancelRequestWithChannel(t *testing.T) { 1557 defer afterTest(t) 1558 if testing.Short() { 1559 t.Skip("skipping test in -short mode") 1560 } 1561 unblockc := make(chan bool) 1562 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1563 fmt.Fprintf(w, "Hello") 1564 w.(Flusher).Flush() // send headers and some body 1565 <-unblockc 1566 })) 1567 defer ts.Close() 1568 defer close(unblockc) 1569 1570 tr := &Transport{} 1571 defer tr.CloseIdleConnections() 1572 c := &Client{Transport: tr} 1573 1574 req, _ := NewRequest("GET", ts.URL, nil) 1575 ch := make(chan struct{}) 1576 req.Cancel = ch 1577 1578 res, err := c.Do(req) 1579 if err != nil { 1580 t.Fatal(err) 1581 } 1582 go func() { 1583 time.Sleep(1 * time.Second) 1584 close(ch) 1585 }() 1586 t0 := time.Now() 1587 body, err := ioutil.ReadAll(res.Body) 1588 d := time.Since(t0) 1589 1590 if err != ExportErrRequestCanceled { 1591 t.Errorf("Body.Read error = %v; want errRequestCanceled", err) 1592 } 1593 if string(body) != "Hello" { 1594 t.Errorf("Body = %q; want Hello", body) 1595 } 1596 if d < 500*time.Millisecond { 1597 t.Errorf("expected ~1 second delay; got %v", d) 1598 } 1599 // Verify no outstanding requests after readLoop/writeLoop 1600 // goroutines shut down. 1601 for tries := 5; tries > 0; tries-- { 1602 n := tr.NumPendingRequestsForTesting() 1603 if n == 0 { 1604 break 1605 } 1606 time.Sleep(100 * time.Millisecond) 1607 if tries == 1 { 1608 t.Errorf("pending requests = %d; want 0", n) 1609 } 1610 } 1611 } 1612 1613 func TestCancelRequestWithChannelBeforeDo(t *testing.T) { 1614 defer afterTest(t) 1615 unblockc := make(chan bool) 1616 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1617 <-unblockc 1618 })) 1619 defer ts.Close() 1620 defer close(unblockc) 1621 1622 // Don't interfere with the next test on plan9. 1623 // Cf. https://golang.org/issues/11476 1624 if runtime.GOOS == "plan9" { 1625 defer time.Sleep(500 * time.Millisecond) 1626 } 1627 1628 tr := &Transport{} 1629 defer tr.CloseIdleConnections() 1630 c := &Client{Transport: tr} 1631 1632 req, _ := NewRequest("GET", ts.URL, nil) 1633 ch := make(chan struct{}) 1634 req.Cancel = ch 1635 close(ch) 1636 1637 _, err := c.Do(req) 1638 if err == nil || !strings.Contains(err.Error(), "canceled") { 1639 t.Errorf("Do error = %v; want cancelation", err) 1640 } 1641 } 1642 1643 // Issue 11020. The returned error message should be errRequestCanceled 1644 func TestTransportCancelBeforeResponseHeaders(t *testing.T) { 1645 t.Skip("Skipping flaky test; see Issue 11894") 1646 defer afterTest(t) 1647 1648 serverConnCh := make(chan net.Conn, 1) 1649 tr := &Transport{ 1650 Dial: func(network, addr string) (net.Conn, error) { 1651 cc, sc := net.Pipe() 1652 serverConnCh <- sc 1653 return cc, nil 1654 }, 1655 } 1656 defer tr.CloseIdleConnections() 1657 errc := make(chan error, 1) 1658 req, _ := NewRequest("GET", "http://example.com/", nil) 1659 go func() { 1660 _, err := tr.RoundTrip(req) 1661 errc <- err 1662 }() 1663 1664 sc := <-serverConnCh 1665 verb := make([]byte, 3) 1666 if _, err := io.ReadFull(sc, verb); err != nil { 1667 t.Errorf("Error reading HTTP verb from server: %v", err) 1668 } 1669 if string(verb) != "GET" { 1670 t.Errorf("server received %q; want GET", verb) 1671 } 1672 defer sc.Close() 1673 1674 tr.CancelRequest(req) 1675 1676 err := <-errc 1677 if err == nil { 1678 t.Fatalf("unexpected success from RoundTrip") 1679 } 1680 if err != ExportErrRequestCanceled { 1681 t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err) 1682 } 1683 } 1684 1685 // golang.org/issue/3672 -- Client can't close HTTP stream 1686 // Calling Close on a Response.Body used to just read until EOF. 1687 // Now it actually closes the TCP connection. 1688 func TestTransportCloseResponseBody(t *testing.T) { 1689 defer afterTest(t) 1690 writeErr := make(chan error, 1) 1691 msg := []byte("young\n") 1692 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1693 for { 1694 _, err := w.Write(msg) 1695 if err != nil { 1696 writeErr <- err 1697 return 1698 } 1699 w.(Flusher).Flush() 1700 } 1701 })) 1702 defer ts.Close() 1703 1704 tr := &Transport{} 1705 defer tr.CloseIdleConnections() 1706 c := &Client{Transport: tr} 1707 1708 req, _ := NewRequest("GET", ts.URL, nil) 1709 defer tr.CancelRequest(req) 1710 1711 res, err := c.Do(req) 1712 if err != nil { 1713 t.Fatal(err) 1714 } 1715 1716 const repeats = 3 1717 buf := make([]byte, len(msg)*repeats) 1718 want := bytes.Repeat(msg, repeats) 1719 1720 _, err = io.ReadFull(res.Body, buf) 1721 if err != nil { 1722 t.Fatal(err) 1723 } 1724 if !bytes.Equal(buf, want) { 1725 t.Fatalf("read %q; want %q", buf, want) 1726 } 1727 didClose := make(chan error, 1) 1728 go func() { 1729 didClose <- res.Body.Close() 1730 }() 1731 select { 1732 case err := <-didClose: 1733 if err != nil { 1734 t.Errorf("Close = %v", err) 1735 } 1736 case <-time.After(10 * time.Second): 1737 t.Fatal("too long waiting for close") 1738 } 1739 select { 1740 case err := <-writeErr: 1741 if err == nil { 1742 t.Errorf("expected non-nil write error") 1743 } 1744 case <-time.After(10 * time.Second): 1745 t.Fatal("too long waiting for write error") 1746 } 1747 } 1748 1749 type fooProto struct{} 1750 1751 func (fooProto) RoundTrip(req *Request) (*Response, error) { 1752 res := &Response{ 1753 Status: "200 OK", 1754 StatusCode: 200, 1755 Header: make(Header), 1756 Body: ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())), 1757 } 1758 return res, nil 1759 } 1760 1761 func TestTransportAltProto(t *testing.T) { 1762 defer afterTest(t) 1763 tr := &Transport{} 1764 c := &Client{Transport: tr} 1765 tr.RegisterProtocol("foo", fooProto{}) 1766 res, err := c.Get("foo://bar.com/path") 1767 if err != nil { 1768 t.Fatal(err) 1769 } 1770 bodyb, err := ioutil.ReadAll(res.Body) 1771 if err != nil { 1772 t.Fatal(err) 1773 } 1774 body := string(bodyb) 1775 if e := "You wanted foo://bar.com/path"; body != e { 1776 t.Errorf("got response %q, want %q", body, e) 1777 } 1778 } 1779 1780 func TestTransportNoHost(t *testing.T) { 1781 defer afterTest(t) 1782 tr := &Transport{} 1783 _, err := tr.RoundTrip(&Request{ 1784 Header: make(Header), 1785 URL: &url.URL{ 1786 Scheme: "http", 1787 }, 1788 }) 1789 want := "http: no Host in request URL" 1790 if got := fmt.Sprint(err); got != want { 1791 t.Errorf("error = %v; want %q", err, want) 1792 } 1793 } 1794 1795 // Issue 13311 1796 func TestTransportEmptyMethod(t *testing.T) { 1797 req, _ := NewRequest("GET", "http://foo.com/", nil) 1798 req.Method = "" // docs say "For client requests an empty string means GET" 1799 got, err := httputil.DumpRequestOut(req, false) // DumpRequestOut uses Transport 1800 if err != nil { 1801 t.Fatal(err) 1802 } 1803 if !strings.Contains(string(got), "GET ") { 1804 t.Fatalf("expected substring 'GET '; got: %s", got) 1805 } 1806 } 1807 1808 func TestTransportSocketLateBinding(t *testing.T) { 1809 defer afterTest(t) 1810 1811 mux := NewServeMux() 1812 fooGate := make(chan bool, 1) 1813 mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) { 1814 w.Header().Set("foo-ipport", r.RemoteAddr) 1815 w.(Flusher).Flush() 1816 <-fooGate 1817 }) 1818 mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) { 1819 w.Header().Set("bar-ipport", r.RemoteAddr) 1820 }) 1821 ts := httptest.NewServer(mux) 1822 defer ts.Close() 1823 1824 dialGate := make(chan bool, 1) 1825 tr := &Transport{ 1826 Dial: func(n, addr string) (net.Conn, error) { 1827 if <-dialGate { 1828 return net.Dial(n, addr) 1829 } 1830 return nil, errors.New("manually closed") 1831 }, 1832 DisableKeepAlives: false, 1833 } 1834 defer tr.CloseIdleConnections() 1835 c := &Client{ 1836 Transport: tr, 1837 } 1838 1839 dialGate <- true // only allow one dial 1840 fooRes, err := c.Get(ts.URL + "/foo") 1841 if err != nil { 1842 t.Fatal(err) 1843 } 1844 fooAddr := fooRes.Header.Get("foo-ipport") 1845 if fooAddr == "" { 1846 t.Fatal("No addr on /foo request") 1847 } 1848 time.AfterFunc(200*time.Millisecond, func() { 1849 // let the foo response finish so we can use its 1850 // connection for /bar 1851 fooGate <- true 1852 io.Copy(ioutil.Discard, fooRes.Body) 1853 fooRes.Body.Close() 1854 }) 1855 1856 barRes, err := c.Get(ts.URL + "/bar") 1857 if err != nil { 1858 t.Fatal(err) 1859 } 1860 barAddr := barRes.Header.Get("bar-ipport") 1861 if barAddr != fooAddr { 1862 t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr) 1863 } 1864 barRes.Body.Close() 1865 dialGate <- false 1866 } 1867 1868 // Issue 2184 1869 func TestTransportReading100Continue(t *testing.T) { 1870 defer afterTest(t) 1871 1872 const numReqs = 5 1873 reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) } 1874 reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) } 1875 1876 send100Response := func(w *io.PipeWriter, r *io.PipeReader) { 1877 defer w.Close() 1878 defer r.Close() 1879 br := bufio.NewReader(r) 1880 n := 0 1881 for { 1882 n++ 1883 req, err := ReadRequest(br) 1884 if err == io.EOF { 1885 return 1886 } 1887 if err != nil { 1888 t.Error(err) 1889 return 1890 } 1891 slurp, err := ioutil.ReadAll(req.Body) 1892 if err != nil { 1893 t.Errorf("Server request body slurp: %v", err) 1894 return 1895 } 1896 id := req.Header.Get("Request-Id") 1897 resCode := req.Header.Get("X-Want-Response-Code") 1898 if resCode == "" { 1899 resCode = "100 Continue" 1900 if string(slurp) != reqBody(n) { 1901 t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n)) 1902 } 1903 } 1904 body := fmt.Sprintf("Response number %d", n) 1905 v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s 1906 Date: Thu, 28 Feb 2013 17:55:41 GMT 1907 1908 HTTP/1.1 200 OK 1909 Content-Type: text/html 1910 Echo-Request-Id: %s 1911 Content-Length: %d 1912 1913 %s`, resCode, id, len(body), body), "\n", "\r\n", -1)) 1914 w.Write(v) 1915 if id == reqID(numReqs) { 1916 return 1917 } 1918 } 1919 1920 } 1921 1922 tr := &Transport{ 1923 Dial: func(n, addr string) (net.Conn, error) { 1924 sr, sw := io.Pipe() // server read/write 1925 cr, cw := io.Pipe() // client read/write 1926 conn := &rwTestConn{ 1927 Reader: cr, 1928 Writer: sw, 1929 closeFunc: func() error { 1930 sw.Close() 1931 cw.Close() 1932 return nil 1933 }, 1934 } 1935 go send100Response(cw, sr) 1936 return conn, nil 1937 }, 1938 DisableKeepAlives: false, 1939 } 1940 defer tr.CloseIdleConnections() 1941 c := &Client{Transport: tr} 1942 1943 testResponse := func(req *Request, name string, wantCode int) { 1944 res, err := c.Do(req) 1945 if err != nil { 1946 t.Fatalf("%s: Do: %v", name, err) 1947 } 1948 if res.StatusCode != wantCode { 1949 t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode) 1950 } 1951 if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack { 1952 t.Errorf("%s: response id %q != request id %q", name, idBack, id) 1953 } 1954 _, err = ioutil.ReadAll(res.Body) 1955 if err != nil { 1956 t.Fatalf("%s: Slurp error: %v", name, err) 1957 } 1958 } 1959 1960 // Few 100 responses, making sure we're not off-by-one. 1961 for i := 1; i <= numReqs; i++ { 1962 req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i))) 1963 req.Header.Set("Request-Id", reqID(i)) 1964 testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200) 1965 } 1966 1967 // And some other informational 1xx but non-100 responses, to test 1968 // we return them but don't re-use the connection. 1969 for i := 1; i <= numReqs; i++ { 1970 req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i))) 1971 req.Header.Set("X-Want-Response-Code", "123 Sesame Street") 1972 testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123) 1973 } 1974 } 1975 1976 type proxyFromEnvTest struct { 1977 req string // URL to fetch; blank means "http://example.com" 1978 1979 env string // HTTP_PROXY 1980 httpsenv string // HTTPS_PROXY 1981 noenv string // NO_RPXY 1982 1983 want string 1984 wanterr error 1985 } 1986 1987 func (t proxyFromEnvTest) String() string { 1988 var buf bytes.Buffer 1989 space := func() { 1990 if buf.Len() > 0 { 1991 buf.WriteByte(' ') 1992 } 1993 } 1994 if t.env != "" { 1995 fmt.Fprintf(&buf, "http_proxy=%q", t.env) 1996 } 1997 if t.httpsenv != "" { 1998 space() 1999 fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv) 2000 } 2001 if t.noenv != "" { 2002 space() 2003 fmt.Fprintf(&buf, "no_proxy=%q", t.noenv) 2004 } 2005 req := "http://example.com" 2006 if t.req != "" { 2007 req = t.req 2008 } 2009 space() 2010 fmt.Fprintf(&buf, "req=%q", req) 2011 return strings.TrimSpace(buf.String()) 2012 } 2013 2014 var proxyFromEnvTests = []proxyFromEnvTest{ 2015 {env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"}, 2016 {env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"}, 2017 {env: "cache.corp.example.com", want: "http://cache.corp.example.com"}, 2018 {env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"}, 2019 {env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"}, 2020 {env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"}, 2021 2022 // Don't use secure for http 2023 {req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"}, 2024 // Use secure for https. 2025 {req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"}, 2026 {req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"}, 2027 2028 {want: "<nil>"}, 2029 2030 {noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"}, 2031 {noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"}, 2032 {noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"}, 2033 {noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"}, 2034 {noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"}, 2035 } 2036 2037 func TestProxyFromEnvironment(t *testing.T) { 2038 ResetProxyEnv() 2039 for _, tt := range proxyFromEnvTests { 2040 os.Setenv("HTTP_PROXY", tt.env) 2041 os.Setenv("HTTPS_PROXY", tt.httpsenv) 2042 os.Setenv("NO_PROXY", tt.noenv) 2043 ResetCachedEnvironment() 2044 reqURL := tt.req 2045 if reqURL == "" { 2046 reqURL = "http://example.com" 2047 } 2048 req, _ := NewRequest("GET", reqURL, nil) 2049 url, err := ProxyFromEnvironment(req) 2050 if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e { 2051 t.Errorf("%v: got error = %q, want %q", tt, g, e) 2052 continue 2053 } 2054 if got := fmt.Sprintf("%s", url); got != tt.want { 2055 t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want) 2056 } 2057 } 2058 } 2059 2060 func TestIdleConnChannelLeak(t *testing.T) { 2061 var mu sync.Mutex 2062 var n int 2063 2064 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2065 mu.Lock() 2066 n++ 2067 mu.Unlock() 2068 })) 2069 defer ts.Close() 2070 2071 const nReqs = 5 2072 didRead := make(chan bool, nReqs) 2073 SetReadLoopBeforeNextReadHook(func() { didRead <- true }) 2074 defer SetReadLoopBeforeNextReadHook(nil) 2075 2076 tr := &Transport{ 2077 Dial: func(netw, addr string) (net.Conn, error) { 2078 return net.Dial(netw, ts.Listener.Addr().String()) 2079 }, 2080 } 2081 defer tr.CloseIdleConnections() 2082 2083 c := &Client{Transport: tr} 2084 2085 // First, without keep-alives. 2086 for _, disableKeep := range []bool{true, false} { 2087 tr.DisableKeepAlives = disableKeep 2088 for i := 0; i < nReqs; i++ { 2089 _, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i)) 2090 if err != nil { 2091 t.Fatal(err) 2092 } 2093 // Note: no res.Body.Close is needed here, since the 2094 // response Content-Length is zero. Perhaps the test 2095 // should be more explicit and use a HEAD, but tests 2096 // elsewhere guarantee that zero byte responses generate 2097 // a "Content-Length: 0" instead of chunking. 2098 } 2099 2100 // At this point, each of the 5 Transport.readLoop goroutines 2101 // are scheduling noting that there are no response bodies (see 2102 // earlier comment), and are then calling putIdleConn, which 2103 // decrements this count. Usually that happens quickly, which is 2104 // why this test has seemed to work for ages. But it's still 2105 // racey: we have wait for them to finish first. See Issue 10427 2106 for i := 0; i < nReqs; i++ { 2107 <-didRead 2108 } 2109 2110 if got := tr.IdleConnChMapSizeForTesting(); got != 0 { 2111 t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got) 2112 } 2113 } 2114 } 2115 2116 // Verify the status quo: that the Client.Post function coerces its 2117 // body into a ReadCloser if it's a Closer, and that the Transport 2118 // then closes it. 2119 func TestTransportClosesRequestBody(t *testing.T) { 2120 defer afterTest(t) 2121 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2122 io.Copy(ioutil.Discard, r.Body) 2123 })) 2124 defer ts.Close() 2125 2126 tr := &Transport{} 2127 defer tr.CloseIdleConnections() 2128 cl := &Client{Transport: tr} 2129 2130 closes := 0 2131 2132 res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")}) 2133 if err != nil { 2134 t.Fatal(err) 2135 } 2136 res.Body.Close() 2137 if closes != 1 { 2138 t.Errorf("closes = %d; want 1", closes) 2139 } 2140 } 2141 2142 func TestTransportTLSHandshakeTimeout(t *testing.T) { 2143 defer afterTest(t) 2144 if testing.Short() { 2145 t.Skip("skipping in short mode") 2146 } 2147 ln := newLocalListener(t) 2148 defer ln.Close() 2149 testdonec := make(chan struct{}) 2150 defer close(testdonec) 2151 2152 go func() { 2153 c, err := ln.Accept() 2154 if err != nil { 2155 t.Error(err) 2156 return 2157 } 2158 <-testdonec 2159 c.Close() 2160 }() 2161 2162 getdonec := make(chan struct{}) 2163 go func() { 2164 defer close(getdonec) 2165 tr := &Transport{ 2166 Dial: func(_, _ string) (net.Conn, error) { 2167 return net.Dial("tcp", ln.Addr().String()) 2168 }, 2169 TLSHandshakeTimeout: 250 * time.Millisecond, 2170 } 2171 cl := &Client{Transport: tr} 2172 _, err := cl.Get("https://dummy.tld/") 2173 if err == nil { 2174 t.Error("expected error") 2175 return 2176 } 2177 ue, ok := err.(*url.Error) 2178 if !ok { 2179 t.Errorf("expected url.Error; got %#v", err) 2180 return 2181 } 2182 ne, ok := ue.Err.(net.Error) 2183 if !ok { 2184 t.Errorf("expected net.Error; got %#v", err) 2185 return 2186 } 2187 if !ne.Timeout() { 2188 t.Errorf("expected timeout error; got %v", err) 2189 } 2190 if !strings.Contains(err.Error(), "handshake timeout") { 2191 t.Errorf("expected 'handshake timeout' in error; got %v", err) 2192 } 2193 }() 2194 select { 2195 case <-getdonec: 2196 case <-time.After(5 * time.Second): 2197 t.Error("test timeout; TLS handshake hung?") 2198 } 2199 } 2200 2201 // Trying to repro golang.org/issue/3514 2202 func TestTLSServerClosesConnection(t *testing.T) { 2203 defer afterTest(t) 2204 if runtime.GOOS == "windows" { 2205 t.Skip("skipping flaky test on Windows; golang.org/issue/7634") 2206 } 2207 closedc := make(chan bool, 1) 2208 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2209 if strings.Contains(r.URL.Path, "/keep-alive-then-die") { 2210 conn, _, _ := w.(Hijacker).Hijack() 2211 conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) 2212 conn.Close() 2213 closedc <- true 2214 return 2215 } 2216 fmt.Fprintf(w, "hello") 2217 })) 2218 defer ts.Close() 2219 tr := &Transport{ 2220 TLSClientConfig: &tls.Config{ 2221 InsecureSkipVerify: true, 2222 }, 2223 } 2224 defer tr.CloseIdleConnections() 2225 client := &Client{Transport: tr} 2226 2227 var nSuccess = 0 2228 var errs []error 2229 const trials = 20 2230 for i := 0; i < trials; i++ { 2231 tr.CloseIdleConnections() 2232 res, err := client.Get(ts.URL + "/keep-alive-then-die") 2233 if err != nil { 2234 t.Fatal(err) 2235 } 2236 <-closedc 2237 slurp, err := ioutil.ReadAll(res.Body) 2238 if err != nil { 2239 t.Fatal(err) 2240 } 2241 if string(slurp) != "foo" { 2242 t.Errorf("Got %q, want foo", slurp) 2243 } 2244 2245 // Now try again and see if we successfully 2246 // pick a new connection. 2247 res, err = client.Get(ts.URL + "/") 2248 if err != nil { 2249 errs = append(errs, err) 2250 continue 2251 } 2252 slurp, err = ioutil.ReadAll(res.Body) 2253 if err != nil { 2254 errs = append(errs, err) 2255 continue 2256 } 2257 nSuccess++ 2258 } 2259 if nSuccess > 0 { 2260 t.Logf("successes = %d of %d", nSuccess, trials) 2261 } else { 2262 t.Errorf("All runs failed:") 2263 } 2264 for _, err := range errs { 2265 t.Logf(" err: %v", err) 2266 } 2267 } 2268 2269 // byteFromChanReader is an io.Reader that reads a single byte at a 2270 // time from the channel. When the channel is closed, the reader 2271 // returns io.EOF. 2272 type byteFromChanReader chan byte 2273 2274 func (c byteFromChanReader) Read(p []byte) (n int, err error) { 2275 if len(p) == 0 { 2276 return 2277 } 2278 b, ok := <-c 2279 if !ok { 2280 return 0, io.EOF 2281 } 2282 p[0] = b 2283 return 1, nil 2284 } 2285 2286 // Verifies that the Transport doesn't reuse a connection in the case 2287 // where the server replies before the request has been fully 2288 // written. We still honor that reply (see TestIssue3595), but don't 2289 // send future requests on the connection because it's then in a 2290 // questionable state. 2291 // golang.org/issue/7569 2292 func TestTransportNoReuseAfterEarlyResponse(t *testing.T) { 2293 defer afterTest(t) 2294 var sconn struct { 2295 sync.Mutex 2296 c net.Conn 2297 } 2298 var getOkay bool 2299 closeConn := func() { 2300 sconn.Lock() 2301 defer sconn.Unlock() 2302 if sconn.c != nil { 2303 sconn.c.Close() 2304 sconn.c = nil 2305 if !getOkay { 2306 t.Logf("Closed server connection") 2307 } 2308 } 2309 } 2310 defer closeConn() 2311 2312 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2313 if r.Method == "GET" { 2314 io.WriteString(w, "bar") 2315 return 2316 } 2317 conn, _, _ := w.(Hijacker).Hijack() 2318 sconn.Lock() 2319 sconn.c = conn 2320 sconn.Unlock() 2321 conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive 2322 go io.Copy(ioutil.Discard, conn) 2323 })) 2324 defer ts.Close() 2325 tr := &Transport{} 2326 defer tr.CloseIdleConnections() 2327 client := &Client{Transport: tr} 2328 2329 const bodySize = 256 << 10 2330 finalBit := make(byteFromChanReader, 1) 2331 req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit)) 2332 req.ContentLength = bodySize 2333 res, err := client.Do(req) 2334 if err := wantBody(res, err, "foo"); err != nil { 2335 t.Errorf("POST response: %v", err) 2336 } 2337 donec := make(chan bool) 2338 go func() { 2339 defer close(donec) 2340 res, err = client.Get(ts.URL) 2341 if err := wantBody(res, err, "bar"); err != nil { 2342 t.Errorf("GET response: %v", err) 2343 return 2344 } 2345 getOkay = true // suppress test noise 2346 }() 2347 time.AfterFunc(5*time.Second, closeConn) 2348 select { 2349 case <-donec: 2350 finalBit <- 'x' // unblock the writeloop of the first Post 2351 close(finalBit) 2352 case <-time.After(7 * time.Second): 2353 t.Fatal("timeout waiting for GET request to finish") 2354 } 2355 } 2356 2357 // Tests that we don't leak Transport persistConn.readLoop goroutines 2358 // when a server hangs up immediately after saying it would keep-alive. 2359 func TestTransportIssue10457(t *testing.T) { 2360 defer afterTest(t) // used to fail in goroutine leak check 2361 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2362 // Send a response with no body, keep-alive 2363 // (implicit), and then lie and immediately close the 2364 // connection. This forces the Transport's readLoop to 2365 // immediately Peek an io.EOF and get to the point 2366 // that used to hang. 2367 conn, _, _ := w.(Hijacker).Hijack() 2368 conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive 2369 conn.Close() 2370 })) 2371 defer ts.Close() 2372 tr := &Transport{} 2373 defer tr.CloseIdleConnections() 2374 cl := &Client{Transport: tr} 2375 res, err := cl.Get(ts.URL) 2376 if err != nil { 2377 t.Fatalf("Get: %v", err) 2378 } 2379 defer res.Body.Close() 2380 2381 // Just a sanity check that we at least get the response. The real 2382 // test here is that the "defer afterTest" above doesn't find any 2383 // leaked goroutines. 2384 if got, want := res.Header.Get("Foo"), "Bar"; got != want { 2385 t.Errorf("Foo header = %q; want %q", got, want) 2386 } 2387 } 2388 2389 type errorReader struct { 2390 err error 2391 } 2392 2393 func (e errorReader) Read(p []byte) (int, error) { return 0, e.err } 2394 2395 type plan9SleepReader struct{} 2396 2397 func (plan9SleepReader) Read(p []byte) (int, error) { 2398 if runtime.GOOS == "plan9" { 2399 // After the fix to unblock TCP Reads in 2400 // https://golang.org/cl/15941, this sleep is required 2401 // on plan9 to make sure TCP Writes before an 2402 // immediate TCP close go out on the wire. On Plan 9, 2403 // it seems that a hangup of a TCP connection with 2404 // queued data doesn't send the queued data first. 2405 // https://golang.org/issue/9554 2406 time.Sleep(50 * time.Millisecond) 2407 } 2408 return 0, io.EOF 2409 } 2410 2411 type closerFunc func() error 2412 2413 func (f closerFunc) Close() error { return f() } 2414 2415 // Issue 4677. If we try to reuse a connection that the server is in the 2416 // process of closing, we may end up successfully writing out our request (or a 2417 // portion of our request) only to find a connection error when we try to read 2418 // from (or finish writing to) the socket. 2419 // 2420 // NOTE: we resend a request only if the request is idempotent, we reused a 2421 // keep-alive connection, and we haven't yet received any header data. This 2422 // automatically prevents an infinite resend loop because we'll run out of the 2423 // cached keep-alive connections eventually. 2424 func TestRetryIdempotentRequestsOnError(t *testing.T) { 2425 defer afterTest(t) 2426 2427 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2428 })) 2429 defer ts.Close() 2430 2431 tr := &Transport{} 2432 c := &Client{Transport: tr} 2433 2434 const N = 2 2435 retryc := make(chan struct{}, N) 2436 SetRoundTripRetried(func() { 2437 retryc <- struct{}{} 2438 }) 2439 defer SetRoundTripRetried(nil) 2440 2441 for n := 0; n < 100; n++ { 2442 // open 2 conns 2443 errc := make(chan error, N) 2444 for i := 0; i < N; i++ { 2445 // start goroutines, send on errc 2446 go func() { 2447 res, err := c.Get(ts.URL) 2448 if err == nil { 2449 res.Body.Close() 2450 } 2451 errc <- err 2452 }() 2453 } 2454 for i := 0; i < N; i++ { 2455 if err := <-errc; err != nil { 2456 t.Fatal(err) 2457 } 2458 } 2459 2460 ts.CloseClientConnections() 2461 for i := 0; i < N; i++ { 2462 go func() { 2463 res, err := c.Get(ts.URL) 2464 if err == nil { 2465 res.Body.Close() 2466 } 2467 errc <- err 2468 }() 2469 } 2470 2471 for i := 0; i < N; i++ { 2472 if err := <-errc; err != nil { 2473 t.Fatal(err) 2474 } 2475 } 2476 for i := 0; i < N; i++ { 2477 select { 2478 case <-retryc: 2479 // we triggered a retry, test was successful 2480 t.Logf("finished after %d runs\n", n) 2481 return 2482 default: 2483 } 2484 } 2485 } 2486 t.Fatal("did not trigger any retries") 2487 } 2488 2489 // Issue 6981 2490 func TestTransportClosesBodyOnError(t *testing.T) { 2491 defer afterTest(t) 2492 readBody := make(chan error, 1) 2493 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2494 _, err := ioutil.ReadAll(r.Body) 2495 readBody <- err 2496 })) 2497 defer ts.Close() 2498 fakeErr := errors.New("fake error") 2499 didClose := make(chan bool, 1) 2500 req, _ := NewRequest("POST", ts.URL, struct { 2501 io.Reader 2502 io.Closer 2503 }{ 2504 io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), plan9SleepReader{}, errorReader{fakeErr}), 2505 closerFunc(func() error { 2506 select { 2507 case didClose <- true: 2508 default: 2509 } 2510 return nil 2511 }), 2512 }) 2513 res, err := DefaultClient.Do(req) 2514 if res != nil { 2515 defer res.Body.Close() 2516 } 2517 if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) { 2518 t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error()) 2519 } 2520 select { 2521 case err := <-readBody: 2522 if err == nil { 2523 t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'") 2524 } 2525 case <-time.After(5 * time.Second): 2526 t.Error("timeout waiting for server handler to complete") 2527 } 2528 select { 2529 case <-didClose: 2530 default: 2531 t.Errorf("didn't see Body.Close") 2532 } 2533 } 2534 2535 func TestTransportDialTLS(t *testing.T) { 2536 var mu sync.Mutex // guards following 2537 var gotReq, didDial bool 2538 2539 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2540 mu.Lock() 2541 gotReq = true 2542 mu.Unlock() 2543 })) 2544 defer ts.Close() 2545 tr := &Transport{ 2546 DialTLS: func(netw, addr string) (net.Conn, error) { 2547 mu.Lock() 2548 didDial = true 2549 mu.Unlock() 2550 c, err := tls.Dial(netw, addr, &tls.Config{ 2551 InsecureSkipVerify: true, 2552 }) 2553 if err != nil { 2554 return nil, err 2555 } 2556 return c, c.Handshake() 2557 }, 2558 } 2559 defer tr.CloseIdleConnections() 2560 client := &Client{Transport: tr} 2561 res, err := client.Get(ts.URL) 2562 if err != nil { 2563 t.Fatal(err) 2564 } 2565 res.Body.Close() 2566 mu.Lock() 2567 if !gotReq { 2568 t.Error("didn't get request") 2569 } 2570 if !didDial { 2571 t.Error("didn't use dial hook") 2572 } 2573 } 2574 2575 // Test for issue 8755 2576 // Ensure that if a proxy returns an error, it is exposed by RoundTrip 2577 func TestRoundTripReturnsProxyError(t *testing.T) { 2578 badProxy := func(*Request) (*url.URL, error) { 2579 return nil, errors.New("errorMessage") 2580 } 2581 2582 tr := &Transport{Proxy: badProxy} 2583 2584 req, _ := NewRequest("GET", "http://example.com", nil) 2585 2586 _, err := tr.RoundTrip(req) 2587 2588 if err == nil { 2589 t.Error("Expected proxy error to be returned by RoundTrip") 2590 } 2591 } 2592 2593 // tests that putting an idle conn after a call to CloseIdleConns does return it 2594 func TestTransportCloseIdleConnsThenReturn(t *testing.T) { 2595 tr := &Transport{} 2596 wantIdle := func(when string, n int) bool { 2597 got := tr.IdleConnCountForTesting("|http|example.com") // key used by PutIdleTestConn 2598 if got == n { 2599 return true 2600 } 2601 t.Errorf("%s: idle conns = %d; want %d", when, got, n) 2602 return false 2603 } 2604 wantIdle("start", 0) 2605 if !tr.PutIdleTestConn() { 2606 t.Fatal("put failed") 2607 } 2608 if !tr.PutIdleTestConn() { 2609 t.Fatal("second put failed") 2610 } 2611 wantIdle("after put", 2) 2612 tr.CloseIdleConnections() 2613 if !tr.IsIdleForTesting() { 2614 t.Error("should be idle after CloseIdleConnections") 2615 } 2616 wantIdle("after close idle", 0) 2617 if tr.PutIdleTestConn() { 2618 t.Fatal("put didn't fail") 2619 } 2620 wantIdle("after second put", 0) 2621 2622 tr.RequestIdleConnChForTesting() // should toggle the transport out of idle mode 2623 if tr.IsIdleForTesting() { 2624 t.Error("shouldn't be idle after RequestIdleConnChForTesting") 2625 } 2626 if !tr.PutIdleTestConn() { 2627 t.Fatal("after re-activation") 2628 } 2629 wantIdle("after final put", 1) 2630 } 2631 2632 // This tests that an client requesting a content range won't also 2633 // implicitly ask for gzip support. If they want that, they need to do it 2634 // on their own. 2635 // golang.org/issue/8923 2636 func TestTransportRangeAndGzip(t *testing.T) { 2637 defer afterTest(t) 2638 reqc := make(chan *Request, 1) 2639 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2640 reqc <- r 2641 })) 2642 defer ts.Close() 2643 2644 req, _ := NewRequest("GET", ts.URL, nil) 2645 req.Header.Set("Range", "bytes=7-11") 2646 res, err := DefaultClient.Do(req) 2647 if err != nil { 2648 t.Fatal(err) 2649 } 2650 2651 select { 2652 case r := <-reqc: 2653 if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { 2654 t.Error("Transport advertised gzip support in the Accept header") 2655 } 2656 if r.Header.Get("Range") == "" { 2657 t.Error("no Range in request") 2658 } 2659 case <-time.After(10 * time.Second): 2660 t.Fatal("timeout") 2661 } 2662 res.Body.Close() 2663 } 2664 2665 // Test for issue 10474 2666 func TestTransportResponseCancelRace(t *testing.T) { 2667 defer afterTest(t) 2668 2669 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2670 // important that this response has a body. 2671 var b [1024]byte 2672 w.Write(b[:]) 2673 })) 2674 defer ts.Close() 2675 2676 tr := &Transport{} 2677 defer tr.CloseIdleConnections() 2678 2679 req, err := NewRequest("GET", ts.URL, nil) 2680 if err != nil { 2681 t.Fatal(err) 2682 } 2683 res, err := tr.RoundTrip(req) 2684 if err != nil { 2685 t.Fatal(err) 2686 } 2687 // If we do an early close, Transport just throws the connection away and 2688 // doesn't reuse it. In order to trigger the bug, it has to reuse the connection 2689 // so read the body 2690 if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { 2691 t.Fatal(err) 2692 } 2693 2694 req2, err := NewRequest("GET", ts.URL, nil) 2695 if err != nil { 2696 t.Fatal(err) 2697 } 2698 tr.CancelRequest(req) 2699 res, err = tr.RoundTrip(req2) 2700 if err != nil { 2701 t.Fatal(err) 2702 } 2703 res.Body.Close() 2704 } 2705 2706 func TestTransportDialCancelRace(t *testing.T) { 2707 defer afterTest(t) 2708 2709 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 2710 defer ts.Close() 2711 2712 tr := &Transport{} 2713 defer tr.CloseIdleConnections() 2714 2715 req, err := NewRequest("GET", ts.URL, nil) 2716 if err != nil { 2717 t.Fatal(err) 2718 } 2719 SetEnterRoundTripHook(func() { 2720 tr.CancelRequest(req) 2721 }) 2722 defer SetEnterRoundTripHook(nil) 2723 res, err := tr.RoundTrip(req) 2724 if err != ExportErrRequestCanceled { 2725 t.Errorf("expected canceled request error; got %v", err) 2726 if err == nil { 2727 res.Body.Close() 2728 } 2729 } 2730 } 2731 2732 // logWritesConn is a net.Conn that logs each Write call to writes 2733 // and then proxies to w. 2734 // It proxies Read calls to a reader it receives from rch. 2735 type logWritesConn struct { 2736 net.Conn // nil. crash on use. 2737 2738 w io.Writer 2739 2740 rch <-chan io.Reader 2741 r io.Reader // nil until received by rch 2742 2743 mu sync.Mutex 2744 writes []string 2745 } 2746 2747 func (c *logWritesConn) Write(p []byte) (n int, err error) { 2748 c.mu.Lock() 2749 defer c.mu.Unlock() 2750 c.writes = append(c.writes, string(p)) 2751 return c.w.Write(p) 2752 } 2753 2754 func (c *logWritesConn) Read(p []byte) (n int, err error) { 2755 if c.r == nil { 2756 c.r = <-c.rch 2757 } 2758 return c.r.Read(p) 2759 } 2760 2761 func (c *logWritesConn) Close() error { return nil } 2762 2763 // Issue 6574 2764 func TestTransportFlushesBodyChunks(t *testing.T) { 2765 defer afterTest(t) 2766 resBody := make(chan io.Reader, 1) 2767 connr, connw := io.Pipe() // connection pipe pair 2768 lw := &logWritesConn{ 2769 rch: resBody, 2770 w: connw, 2771 } 2772 tr := &Transport{ 2773 Dial: func(network, addr string) (net.Conn, error) { 2774 return lw, nil 2775 }, 2776 } 2777 bodyr, bodyw := io.Pipe() // body pipe pair 2778 go func() { 2779 defer bodyw.Close() 2780 for i := 0; i < 3; i++ { 2781 fmt.Fprintf(bodyw, "num%d\n", i) 2782 } 2783 }() 2784 resc := make(chan *Response) 2785 go func() { 2786 req, _ := NewRequest("POST", "http://localhost:8080", bodyr) 2787 req.Header.Set("User-Agent", "x") // known value for test 2788 res, err := tr.RoundTrip(req) 2789 if err != nil { 2790 t.Errorf("RoundTrip: %v", err) 2791 close(resc) 2792 return 2793 } 2794 resc <- res 2795 2796 }() 2797 // Fully consume the request before checking the Write log vs. want. 2798 req, err := ReadRequest(bufio.NewReader(connr)) 2799 if err != nil { 2800 t.Fatal(err) 2801 } 2802 io.Copy(ioutil.Discard, req.Body) 2803 2804 // Unblock the transport's roundTrip goroutine. 2805 resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n") 2806 res, ok := <-resc 2807 if !ok { 2808 return 2809 } 2810 defer res.Body.Close() 2811 2812 want := []string{ 2813 // Because Request.ContentLength = 0, the body is sniffed for 1 byte to determine whether there's content. 2814 // That explains the initial "num0" being split into "n" and "um0". 2815 // The first byte is included with the request headers Write. Perhaps in the future 2816 // we will want to flush the headers out early if the first byte of the request body is 2817 // taking a long time to arrive. But not yet. 2818 "POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n" + 2819 "1\r\nn\r\n", 2820 "4\r\num0\n\r\n", 2821 "5\r\nnum1\n\r\n", 2822 "5\r\nnum2\n\r\n", 2823 "0\r\n\r\n", 2824 } 2825 if !reflect.DeepEqual(lw.writes, want) { 2826 t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want) 2827 } 2828 } 2829 2830 // Issue 11745. 2831 func TestTransportPrefersResponseOverWriteError(t *testing.T) { 2832 if testing.Short() { 2833 t.Skip("skipping in short mode") 2834 } 2835 defer afterTest(t) 2836 const contentLengthLimit = 1024 * 1024 // 1MB 2837 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2838 if r.ContentLength >= contentLengthLimit { 2839 w.WriteHeader(StatusBadRequest) 2840 r.Body.Close() 2841 return 2842 } 2843 w.WriteHeader(StatusOK) 2844 })) 2845 defer ts.Close() 2846 2847 fail := 0 2848 count := 100 2849 bigBody := strings.Repeat("a", contentLengthLimit*2) 2850 for i := 0; i < count; i++ { 2851 req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody)) 2852 if err != nil { 2853 t.Fatal(err) 2854 } 2855 tr := new(Transport) 2856 defer tr.CloseIdleConnections() 2857 client := &Client{Transport: tr} 2858 resp, err := client.Do(req) 2859 if err != nil { 2860 fail++ 2861 t.Logf("%d = %#v", i, err) 2862 if ue, ok := err.(*url.Error); ok { 2863 t.Logf("urlErr = %#v", ue.Err) 2864 if ne, ok := ue.Err.(*net.OpError); ok { 2865 t.Logf("netOpError = %#v", ne.Err) 2866 } 2867 } 2868 } else { 2869 resp.Body.Close() 2870 if resp.StatusCode != 400 { 2871 t.Errorf("Expected status code 400, got %v", resp.Status) 2872 } 2873 } 2874 } 2875 if fail > 0 { 2876 t.Errorf("Failed %v out of %v\n", fail, count) 2877 } 2878 } 2879 2880 func TestTransportAutomaticHTTP2(t *testing.T) { 2881 tr := &Transport{} 2882 _, err := tr.RoundTrip(new(Request)) 2883 if err == nil { 2884 t.Error("expected error from RoundTrip") 2885 } 2886 if tr.TLSNextProto["h2"] == nil { 2887 t.Errorf("HTTP/2 not registered.") 2888 } 2889 2890 // Now with TLSNextProto set: 2891 tr = &Transport{TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper)} 2892 _, err = tr.RoundTrip(new(Request)) 2893 if err == nil { 2894 t.Error("expected error from RoundTrip") 2895 } 2896 if tr.TLSNextProto["h2"] != nil { 2897 t.Errorf("HTTP/2 registered, despite non-nil TLSNextProto field") 2898 } 2899 } 2900 2901 // Issue 13633: there was a race where we returned bodyless responses 2902 // to callers before recycling the persistent connection, which meant 2903 // a client doing two subsequent requests could end up on different 2904 // connections. It's somewhat harmless but enough tests assume it's 2905 // not true in order to test other things that it's worth fixing. 2906 // Plus it's nice to be consistent and not have timing-dependent 2907 // behavior. 2908 func TestTransportReuseConnEmptyResponseBody(t *testing.T) { 2909 defer afterTest(t) 2910 cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) { 2911 w.Header().Set("X-Addr", r.RemoteAddr) 2912 // Empty response body. 2913 })) 2914 defer cst.close() 2915 n := 100 2916 if testing.Short() { 2917 n = 10 2918 } 2919 var firstAddr string 2920 for i := 0; i < n; i++ { 2921 res, err := cst.c.Get(cst.ts.URL) 2922 if err != nil { 2923 log.Fatal(err) 2924 } 2925 addr := res.Header.Get("X-Addr") 2926 if i == 0 { 2927 firstAddr = addr 2928 } else if addr != firstAddr { 2929 t.Fatalf("On request %d, addr %q != original addr %q", i+1, addr, firstAddr) 2930 } 2931 res.Body.Close() 2932 } 2933 } 2934 2935 func wantBody(res *Response, err error, want string) error { 2936 if err != nil { 2937 return err 2938 } 2939 slurp, err := ioutil.ReadAll(res.Body) 2940 if err != nil { 2941 return fmt.Errorf("error reading body: %v", err) 2942 } 2943 if string(slurp) != want { 2944 return fmt.Errorf("body = %q; want %q", slurp, want) 2945 } 2946 if err := res.Body.Close(); err != nil { 2947 return fmt.Errorf("body Close = %v", err) 2948 } 2949 return nil 2950 } 2951 2952 func newLocalListener(t *testing.T) net.Listener { 2953 ln, err := net.Listen("tcp", "127.0.0.1:0") 2954 if err != nil { 2955 ln, err = net.Listen("tcp6", "[::1]:0") 2956 } 2957 if err != nil { 2958 t.Fatal(err) 2959 } 2960 return ln 2961 } 2962 2963 type countCloseReader struct { 2964 n *int 2965 io.Reader 2966 } 2967 2968 func (cr countCloseReader) Close() error { 2969 (*cr.n)++ 2970 return nil 2971 } 2972 2973 // rgz is a gzip quine that uncompresses to itself. 2974 var rgz = []byte{ 2975 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 2976 0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 2977 0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0, 2978 0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 2979 0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 2980 0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60, 2981 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2, 2982 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00, 2983 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 2984 0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16, 2985 0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05, 2986 0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff, 2987 0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00, 2988 0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 2989 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 2990 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 2991 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 2992 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 2993 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 2994 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 2995 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 2996 0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff, 2997 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00, 2998 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 2999 0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 3000 0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 3001 0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 3002 0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06, 3003 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00, 3004 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00, 3005 0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00, 3006 0x00, 0x00, 3007 }