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