github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/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 "encoding/binary" 20 "errors" 21 "fmt" 22 "internal/nettrace" 23 "internal/testenv" 24 "io" 25 "io/ioutil" 26 "log" 27 "net" 28 . "net/http" 29 "net/http/httptest" 30 "net/http/httptrace" 31 "net/http/httputil" 32 "net/http/internal" 33 "net/url" 34 "os" 35 "reflect" 36 "runtime" 37 "strconv" 38 "strings" 39 "sync" 40 "sync/atomic" 41 "testing" 42 "time" 43 ) 44 45 // TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close 46 // and then verify that the final 2 responses get errors back. 47 48 // hostPortHandler writes back the client's "host:port". 49 var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) { 50 if r.FormValue("close") == "true" { 51 w.Header().Set("Connection", "close") 52 } 53 w.Header().Set("X-Saw-Close", fmt.Sprint(r.Close)) 54 w.Write([]byte(r.RemoteAddr)) 55 }) 56 57 // testCloseConn is a net.Conn tracked by a testConnSet. 58 type testCloseConn struct { 59 net.Conn 60 set *testConnSet 61 } 62 63 func (c *testCloseConn) Close() error { 64 c.set.remove(c) 65 return c.Conn.Close() 66 } 67 68 // testConnSet tracks a set of TCP connections and whether they've 69 // been closed. 70 type testConnSet struct { 71 t *testing.T 72 mu sync.Mutex // guards closed and list 73 closed map[net.Conn]bool 74 list []net.Conn // in order created 75 } 76 77 func (tcs *testConnSet) insert(c net.Conn) { 78 tcs.mu.Lock() 79 defer tcs.mu.Unlock() 80 tcs.closed[c] = false 81 tcs.list = append(tcs.list, c) 82 } 83 84 func (tcs *testConnSet) remove(c net.Conn) { 85 tcs.mu.Lock() 86 defer tcs.mu.Unlock() 87 tcs.closed[c] = true 88 } 89 90 // some tests use this to manage raw tcp connections for later inspection 91 func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) { 92 connSet := &testConnSet{ 93 t: t, 94 closed: make(map[net.Conn]bool), 95 } 96 dial := func(n, addr string) (net.Conn, error) { 97 c, err := net.Dial(n, addr) 98 if err != nil { 99 return nil, err 100 } 101 tc := &testCloseConn{c, connSet} 102 connSet.insert(tc) 103 return tc, nil 104 } 105 return connSet, dial 106 } 107 108 func (tcs *testConnSet) check(t *testing.T) { 109 tcs.mu.Lock() 110 defer tcs.mu.Unlock() 111 for i := 4; i >= 0; i-- { 112 for i, c := range tcs.list { 113 if tcs.closed[c] { 114 continue 115 } 116 if i != 0 { 117 tcs.mu.Unlock() 118 time.Sleep(50 * time.Millisecond) 119 tcs.mu.Lock() 120 continue 121 } 122 t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list)) 123 } 124 } 125 } 126 127 // Two subsequent requests and verify their response is the same. 128 // The response from the server is our own IP:port 129 func TestTransportKeepAlives(t *testing.T) { 130 defer afterTest(t) 131 ts := httptest.NewServer(hostPortHandler) 132 defer ts.Close() 133 134 c := ts.Client() 135 for _, disableKeepAlive := range []bool{false, true} { 136 c.Transport.(*Transport).DisableKeepAlives = disableKeepAlive 137 fetch := func(n int) string { 138 res, err := c.Get(ts.URL) 139 if err != nil { 140 t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err) 141 } 142 body, err := ioutil.ReadAll(res.Body) 143 if err != nil { 144 t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err) 145 } 146 return string(body) 147 } 148 149 body1 := fetch(1) 150 body2 := fetch(2) 151 152 bodiesDiffer := body1 != body2 153 if bodiesDiffer != disableKeepAlive { 154 t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q", 155 disableKeepAlive, bodiesDiffer, body1, body2) 156 } 157 } 158 } 159 160 func TestTransportConnectionCloseOnResponse(t *testing.T) { 161 defer afterTest(t) 162 ts := httptest.NewServer(hostPortHandler) 163 defer ts.Close() 164 165 connSet, testDial := makeTestDial(t) 166 167 c := ts.Client() 168 tr := c.Transport.(*Transport) 169 tr.Dial = testDial 170 171 for _, connectionClose := range []bool{false, true} { 172 fetch := func(n int) string { 173 req := new(Request) 174 var err error 175 req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose)) 176 if err != nil { 177 t.Fatalf("URL parse error: %v", err) 178 } 179 req.Method = "GET" 180 req.Proto = "HTTP/1.1" 181 req.ProtoMajor = 1 182 req.ProtoMinor = 1 183 184 res, err := c.Do(req) 185 if err != nil { 186 t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err) 187 } 188 defer res.Body.Close() 189 body, err := ioutil.ReadAll(res.Body) 190 if err != nil { 191 t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err) 192 } 193 return string(body) 194 } 195 196 body1 := fetch(1) 197 body2 := fetch(2) 198 bodiesDiffer := body1 != body2 199 if bodiesDiffer != connectionClose { 200 t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q", 201 connectionClose, bodiesDiffer, body1, body2) 202 } 203 204 tr.CloseIdleConnections() 205 } 206 207 connSet.check(t) 208 } 209 210 func TestTransportConnectionCloseOnRequest(t *testing.T) { 211 defer afterTest(t) 212 ts := httptest.NewServer(hostPortHandler) 213 defer ts.Close() 214 215 connSet, testDial := makeTestDial(t) 216 217 c := ts.Client() 218 tr := c.Transport.(*Transport) 219 tr.Dial = testDial 220 for _, connectionClose := range []bool{false, true} { 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 c := ts.Client() 272 c.Transport.(*Transport).DisableKeepAlives = true 273 274 res, err := c.Get(ts.URL) 275 if err != nil { 276 t.Fatal(err) 277 } 278 res.Body.Close() 279 if res.Header.Get("X-Saw-Close") != "true" { 280 t.Errorf("handler didn't see Connection: close ") 281 } 282 } 283 284 func TestTransportIdleCacheKeys(t *testing.T) { 285 defer afterTest(t) 286 ts := httptest.NewServer(hostPortHandler) 287 defer ts.Close() 288 c := ts.Client() 289 tr := c.Transport.(*Transport) 290 291 if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g { 292 t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g) 293 } 294 295 resp, err := c.Get(ts.URL) 296 if err != nil { 297 t.Error(err) 298 } 299 ioutil.ReadAll(resp.Body) 300 301 keys := tr.IdleConnKeysForTesting() 302 if e, g := 1, len(keys); e != g { 303 t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g) 304 } 305 306 if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e { 307 t.Errorf("Expected idle cache key %q; got %q", e, keys[0]) 308 } 309 310 tr.CloseIdleConnections() 311 if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g { 312 t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g) 313 } 314 } 315 316 // Tests that the HTTP transport re-uses connections when a client 317 // reads to the end of a response Body without closing it. 318 func TestTransportReadToEndReusesConn(t *testing.T) { 319 defer afterTest(t) 320 const msg = "foobar" 321 322 var addrSeen map[string]int 323 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 324 addrSeen[r.RemoteAddr]++ 325 if r.URL.Path == "/chunked/" { 326 w.WriteHeader(200) 327 w.(Flusher).Flush() 328 } else { 329 w.Header().Set("Content-Type", strconv.Itoa(len(msg))) 330 w.WriteHeader(200) 331 } 332 w.Write([]byte(msg)) 333 })) 334 defer ts.Close() 335 336 buf := make([]byte, len(msg)) 337 338 for pi, path := range []string{"/content-length/", "/chunked/"} { 339 wantLen := []int{len(msg), -1}[pi] 340 addrSeen = make(map[string]int) 341 for i := 0; i < 3; i++ { 342 res, err := Get(ts.URL + path) 343 if err != nil { 344 t.Errorf("Get %s: %v", path, err) 345 continue 346 } 347 // We want to close this body eventually (before the 348 // defer afterTest at top runs), but not before the 349 // len(addrSeen) check at the bottom of this test, 350 // since Closing this early in the loop would risk 351 // making connections be re-used for the wrong reason. 352 defer res.Body.Close() 353 354 if res.ContentLength != int64(wantLen) { 355 t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen) 356 } 357 n, err := res.Body.Read(buf) 358 if n != len(msg) || err != io.EOF { 359 t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg)) 360 } 361 } 362 if len(addrSeen) != 1 { 363 t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen)) 364 } 365 } 366 } 367 368 func TestTransportMaxPerHostIdleConns(t *testing.T) { 369 defer afterTest(t) 370 resch := make(chan string) 371 gotReq := make(chan bool) 372 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 373 gotReq <- true 374 msg := <-resch 375 _, err := w.Write([]byte(msg)) 376 if err != nil { 377 t.Fatalf("Write: %v", err) 378 } 379 })) 380 defer ts.Close() 381 382 c := ts.Client() 383 tr := c.Transport.(*Transport) 384 maxIdleConnsPerHost := 2 385 tr.MaxIdleConnsPerHost = maxIdleConnsPerHost 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 g, w := tr.IdleConnCountForTesting(cacheKey), 2; g != w { 430 t.Errorf("after second response, idle conns = %d; want %d", g, w) 431 } 432 433 resch <- "res3" 434 <-donech 435 if g, w := tr.IdleConnCountForTesting(cacheKey), maxIdleConnsPerHost; g != w { 436 t.Errorf("after third response, idle conns = %d; want %d", g, w) 437 } 438 } 439 440 func TestTransportRemovesDeadIdleConnections(t *testing.T) { 441 setParallel(t) 442 defer afterTest(t) 443 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 444 io.WriteString(w, r.RemoteAddr) 445 })) 446 defer ts.Close() 447 448 c := ts.Client() 449 tr := c.Transport.(*Transport) 450 451 doReq := func(name string) string { 452 // Do a POST instead of a GET to prevent the Transport's 453 // idempotent request retry logic from kicking in... 454 res, err := c.Post(ts.URL, "", nil) 455 if err != nil { 456 t.Fatalf("%s: %v", name, err) 457 } 458 if res.StatusCode != 200 { 459 t.Fatalf("%s: %v", name, res.Status) 460 } 461 defer res.Body.Close() 462 slurp, err := ioutil.ReadAll(res.Body) 463 if err != nil { 464 t.Fatalf("%s: %v", name, err) 465 } 466 return string(slurp) 467 } 468 469 first := doReq("first") 470 keys1 := tr.IdleConnKeysForTesting() 471 472 ts.CloseClientConnections() 473 474 var keys2 []string 475 if !waitCondition(3*time.Second, 50*time.Millisecond, func() bool { 476 keys2 = tr.IdleConnKeysForTesting() 477 return len(keys2) == 0 478 }) { 479 t.Fatalf("Transport didn't notice idle connection's death.\nbefore: %q\n after: %q\n", keys1, keys2) 480 } 481 482 second := doReq("second") 483 if first == second { 484 t.Errorf("expected a different connection between requests. got %q both times", first) 485 } 486 } 487 488 func TestTransportServerClosingUnexpectedly(t *testing.T) { 489 setParallel(t) 490 defer afterTest(t) 491 ts := httptest.NewServer(hostPortHandler) 492 defer ts.Close() 493 c := ts.Client() 494 495 fetch := func(n, retries int) string { 496 condFatalf := func(format string, arg ...interface{}) { 497 if retries <= 0 { 498 t.Fatalf(format, arg...) 499 } 500 t.Logf("retrying shortly after expected error: "+format, arg...) 501 time.Sleep(time.Second / time.Duration(retries)) 502 } 503 for retries >= 0 { 504 retries-- 505 res, err := c.Get(ts.URL) 506 if err != nil { 507 condFatalf("error in req #%d, GET: %v", n, err) 508 continue 509 } 510 body, err := ioutil.ReadAll(res.Body) 511 if err != nil { 512 condFatalf("error in req #%d, ReadAll: %v", n, err) 513 continue 514 } 515 res.Body.Close() 516 return string(body) 517 } 518 panic("unreachable") 519 } 520 521 body1 := fetch(1, 0) 522 body2 := fetch(2, 0) 523 524 ts.CloseClientConnections() // surprise! 525 526 // This test has an expected race. Sleeping for 25 ms prevents 527 // it on most fast machines, causing the next fetch() call to 528 // succeed quickly. But if we do get errors, fetch() will retry 5 529 // times with some delays between. 530 time.Sleep(25 * time.Millisecond) 531 532 body3 := fetch(3, 5) 533 534 if body1 != body2 { 535 t.Errorf("expected body1 and body2 to be equal") 536 } 537 if body2 == body3 { 538 t.Errorf("expected body2 and body3 to be different") 539 } 540 } 541 542 // Test for https://golang.org/issue/2616 (appropriate issue number) 543 // This fails pretty reliably with GOMAXPROCS=100 or something high. 544 func TestStressSurpriseServerCloses(t *testing.T) { 545 defer afterTest(t) 546 if testing.Short() { 547 t.Skip("skipping test in short mode") 548 } 549 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 550 w.Header().Set("Content-Length", "5") 551 w.Header().Set("Content-Type", "text/plain") 552 w.Write([]byte("Hello")) 553 w.(Flusher).Flush() 554 conn, buf, _ := w.(Hijacker).Hijack() 555 buf.Flush() 556 conn.Close() 557 })) 558 defer ts.Close() 559 c := ts.Client() 560 561 // Do a bunch of traffic from different goroutines. Send to activityc 562 // after each request completes, regardless of whether it failed. 563 // If these are too high, OS X exhausts its ephemeral ports 564 // and hangs waiting for them to transition TCP states. That's 565 // not what we want to test. TODO(bradfitz): use an io.Pipe 566 // dialer for this test instead? 567 const ( 568 numClients = 20 569 reqsPerClient = 25 570 ) 571 activityc := make(chan bool) 572 for i := 0; i < numClients; i++ { 573 go func() { 574 for i := 0; i < reqsPerClient; i++ { 575 res, err := c.Get(ts.URL) 576 if err == nil { 577 // We expect errors since the server is 578 // hanging up on us after telling us to 579 // send more requests, so we don't 580 // actually care what the error is. 581 // But we want to close the body in cases 582 // where we won the race. 583 res.Body.Close() 584 } 585 activityc <- true 586 } 587 }() 588 } 589 590 // Make sure all the request come back, one way or another. 591 for i := 0; i < numClients*reqsPerClient; i++ { 592 select { 593 case <-activityc: 594 case <-time.After(5 * time.Second): 595 t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile") 596 } 597 } 598 } 599 600 // TestTransportHeadResponses verifies that we deal with Content-Lengths 601 // with no bodies properly 602 func TestTransportHeadResponses(t *testing.T) { 603 defer afterTest(t) 604 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 605 if r.Method != "HEAD" { 606 panic("expected HEAD; got " + r.Method) 607 } 608 w.Header().Set("Content-Length", "123") 609 w.WriteHeader(200) 610 })) 611 defer ts.Close() 612 c := ts.Client() 613 614 for i := 0; i < 2; i++ { 615 res, err := c.Head(ts.URL) 616 if err != nil { 617 t.Errorf("error on loop %d: %v", i, err) 618 continue 619 } 620 if e, g := "123", res.Header.Get("Content-Length"); e != g { 621 t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g) 622 } 623 if e, g := int64(123), res.ContentLength; e != g { 624 t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g) 625 } 626 if all, err := ioutil.ReadAll(res.Body); err != nil { 627 t.Errorf("loop %d: Body ReadAll: %v", i, err) 628 } else if len(all) != 0 { 629 t.Errorf("Bogus body %q", all) 630 } 631 } 632 } 633 634 // TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding 635 // on responses to HEAD requests. 636 func TestTransportHeadChunkedResponse(t *testing.T) { 637 defer afterTest(t) 638 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 639 if r.Method != "HEAD" { 640 panic("expected HEAD; got " + r.Method) 641 } 642 w.Header().Set("Transfer-Encoding", "chunked") // client should ignore 643 w.Header().Set("x-client-ipport", r.RemoteAddr) 644 w.WriteHeader(200) 645 })) 646 defer ts.Close() 647 c := ts.Client() 648 649 // Ensure that we wait for the readLoop to complete before 650 // calling Head again 651 didRead := make(chan bool) 652 SetReadLoopBeforeNextReadHook(func() { didRead <- true }) 653 defer SetReadLoopBeforeNextReadHook(nil) 654 655 res1, err := c.Head(ts.URL) 656 <-didRead 657 658 if err != nil { 659 t.Fatalf("request 1 error: %v", err) 660 } 661 662 res2, err := c.Head(ts.URL) 663 <-didRead 664 665 if err != nil { 666 t.Fatalf("request 2 error: %v", err) 667 } 668 if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 { 669 t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2) 670 } 671 } 672 673 var roundTripTests = []struct { 674 accept string 675 expectAccept string 676 compressed bool 677 }{ 678 // Requests with no accept-encoding header use transparent compression 679 {"", "gzip", false}, 680 // Requests with other accept-encoding should pass through unmodified 681 {"foo", "foo", false}, 682 // Requests with accept-encoding == gzip should be passed through 683 {"gzip", "gzip", true}, 684 } 685 686 // Test that the modification made to the Request by the RoundTripper is cleaned up 687 func TestRoundTripGzip(t *testing.T) { 688 setParallel(t) 689 defer afterTest(t) 690 const responseBody = "test response body" 691 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 692 accept := req.Header.Get("Accept-Encoding") 693 if expect := req.FormValue("expect_accept"); accept != expect { 694 t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q", 695 req.FormValue("testnum"), accept, expect) 696 } 697 if accept == "gzip" { 698 rw.Header().Set("Content-Encoding", "gzip") 699 gz := gzip.NewWriter(rw) 700 gz.Write([]byte(responseBody)) 701 gz.Close() 702 } else { 703 rw.Header().Set("Content-Encoding", accept) 704 rw.Write([]byte(responseBody)) 705 } 706 })) 707 defer ts.Close() 708 tr := ts.Client().Transport.(*Transport) 709 710 for i, test := range roundTripTests { 711 // Test basic request (no accept-encoding) 712 req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil) 713 if test.accept != "" { 714 req.Header.Set("Accept-Encoding", test.accept) 715 } 716 res, err := tr.RoundTrip(req) 717 var body []byte 718 if test.compressed { 719 var r *gzip.Reader 720 r, err = gzip.NewReader(res.Body) 721 if err != nil { 722 t.Errorf("%d. gzip NewReader: %v", i, err) 723 continue 724 } 725 body, err = ioutil.ReadAll(r) 726 res.Body.Close() 727 } else { 728 body, err = ioutil.ReadAll(res.Body) 729 } 730 if err != nil { 731 t.Errorf("%d. Error: %q", i, err) 732 continue 733 } 734 if g, e := string(body), responseBody; g != e { 735 t.Errorf("%d. body = %q; want %q", i, g, e) 736 } 737 if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e { 738 t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e) 739 } 740 if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e { 741 t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e) 742 } 743 } 744 745 } 746 747 func TestTransportGzip(t *testing.T) { 748 setParallel(t) 749 defer afterTest(t) 750 const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 751 const nRandBytes = 1024 * 1024 752 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 753 if req.Method == "HEAD" { 754 if g := req.Header.Get("Accept-Encoding"); g != "" { 755 t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g) 756 } 757 return 758 } 759 if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e { 760 t.Errorf("Accept-Encoding = %q, want %q", g, e) 761 } 762 rw.Header().Set("Content-Encoding", "gzip") 763 764 var w io.Writer = rw 765 var buf bytes.Buffer 766 if req.FormValue("chunked") == "0" { 767 w = &buf 768 defer io.Copy(rw, &buf) 769 defer func() { 770 rw.Header().Set("Content-Length", strconv.Itoa(buf.Len())) 771 }() 772 } 773 gz := gzip.NewWriter(w) 774 gz.Write([]byte(testString)) 775 if req.FormValue("body") == "large" { 776 io.CopyN(gz, rand.Reader, nRandBytes) 777 } 778 gz.Close() 779 })) 780 defer ts.Close() 781 c := ts.Client() 782 783 for _, chunked := range []string{"1", "0"} { 784 // First fetch something large, but only read some of it. 785 res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked) 786 if err != nil { 787 t.Fatalf("large get: %v", err) 788 } 789 buf := make([]byte, len(testString)) 790 n, err := io.ReadFull(res.Body, buf) 791 if err != nil { 792 t.Fatalf("partial read of large response: size=%d, %v", n, err) 793 } 794 if e, g := testString, string(buf); e != g { 795 t.Errorf("partial read got %q, expected %q", g, e) 796 } 797 res.Body.Close() 798 // Read on the body, even though it's closed 799 n, err = res.Body.Read(buf) 800 if n != 0 || err == nil { 801 t.Errorf("expected error post-closed large Read; got = %d, %v", n, err) 802 } 803 804 // Then something small. 805 res, err = c.Get(ts.URL + "/?chunked=" + chunked) 806 if err != nil { 807 t.Fatal(err) 808 } 809 body, err := ioutil.ReadAll(res.Body) 810 if err != nil { 811 t.Fatal(err) 812 } 813 if g, e := string(body), testString; g != e { 814 t.Fatalf("body = %q; want %q", g, e) 815 } 816 if g, e := res.Header.Get("Content-Encoding"), ""; g != e { 817 t.Fatalf("Content-Encoding = %q; want %q", g, e) 818 } 819 820 // Read on the body after it's been fully read: 821 n, err = res.Body.Read(buf) 822 if n != 0 || err == nil { 823 t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err) 824 } 825 res.Body.Close() 826 n, err = res.Body.Read(buf) 827 if n != 0 || err == nil { 828 t.Errorf("expected Read error after Close; got %d, %v", n, err) 829 } 830 } 831 832 // And a HEAD request too, because they're always weird. 833 res, err := c.Head(ts.URL) 834 if err != nil { 835 t.Fatalf("Head: %v", err) 836 } 837 if res.StatusCode != 200 { 838 t.Errorf("Head status=%d; want=200", res.StatusCode) 839 } 840 } 841 842 // If a request has Expect:100-continue header, the request blocks sending body until the first response. 843 // Premature consumption of the request body should not be occurred. 844 func TestTransportExpect100Continue(t *testing.T) { 845 setParallel(t) 846 defer afterTest(t) 847 848 ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { 849 switch req.URL.Path { 850 case "/100": 851 // This endpoint implicitly responds 100 Continue and reads body. 852 if _, err := io.Copy(ioutil.Discard, req.Body); err != nil { 853 t.Error("Failed to read Body", err) 854 } 855 rw.WriteHeader(StatusOK) 856 case "/200": 857 // Go 1.5 adds Connection: close header if the client expect 858 // continue but not entire request body is consumed. 859 rw.WriteHeader(StatusOK) 860 case "/500": 861 rw.WriteHeader(StatusInternalServerError) 862 case "/keepalive": 863 // This hijacked endpoint responds error without Connection:close. 864 _, bufrw, err := rw.(Hijacker).Hijack() 865 if err != nil { 866 log.Fatal(err) 867 } 868 bufrw.WriteString("HTTP/1.1 500 Internal Server Error\r\n") 869 bufrw.WriteString("Content-Length: 0\r\n\r\n") 870 bufrw.Flush() 871 case "/timeout": 872 // This endpoint tries to read body without 100 (Continue) response. 873 // After ExpectContinueTimeout, the reading will be started. 874 conn, bufrw, err := rw.(Hijacker).Hijack() 875 if err != nil { 876 log.Fatal(err) 877 } 878 if _, err := io.CopyN(ioutil.Discard, bufrw, req.ContentLength); err != nil { 879 t.Error("Failed to read Body", err) 880 } 881 bufrw.WriteString("HTTP/1.1 200 OK\r\n\r\n") 882 bufrw.Flush() 883 conn.Close() 884 } 885 886 })) 887 defer ts.Close() 888 889 tests := []struct { 890 path string 891 body []byte 892 sent int 893 status int 894 }{ 895 {path: "/100", body: []byte("hello"), sent: 5, status: 200}, // Got 100 followed by 200, entire body is sent. 896 {path: "/200", body: []byte("hello"), sent: 0, status: 200}, // Got 200 without 100. body isn't sent. 897 {path: "/500", body: []byte("hello"), sent: 0, status: 500}, // Got 500 without 100. body isn't sent. 898 {path: "/keepalive", body: []byte("hello"), sent: 0, status: 500}, // Although without Connection:close, body isn't sent. 899 {path: "/timeout", body: []byte("hello"), sent: 5, status: 200}, // Timeout exceeded and entire body is sent. 900 } 901 902 c := ts.Client() 903 for i, v := range tests { 904 tr := &Transport{ 905 ExpectContinueTimeout: 2 * time.Second, 906 } 907 defer tr.CloseIdleConnections() 908 c.Transport = tr 909 body := bytes.NewReader(v.body) 910 req, err := NewRequest("PUT", ts.URL+v.path, body) 911 if err != nil { 912 t.Fatal(err) 913 } 914 req.Header.Set("Expect", "100-continue") 915 req.ContentLength = int64(len(v.body)) 916 917 resp, err := c.Do(req) 918 if err != nil { 919 t.Fatal(err) 920 } 921 resp.Body.Close() 922 923 sent := len(v.body) - body.Len() 924 if v.status != resp.StatusCode { 925 t.Errorf("test %d: status code should be %d but got %d. (%s)", i, v.status, resp.StatusCode, v.path) 926 } 927 if v.sent != sent { 928 t.Errorf("test %d: sent body should be %d but sent %d. (%s)", i, v.sent, sent, v.path) 929 } 930 } 931 } 932 933 func TestSocks5Proxy(t *testing.T) { 934 defer afterTest(t) 935 ch := make(chan string, 1) 936 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 937 ch <- "real server" 938 })) 939 defer ts.Close() 940 l := newLocalListener(t) 941 defer l.Close() 942 go func() { 943 defer close(ch) 944 s, err := l.Accept() 945 if err != nil { 946 t.Errorf("socks5 proxy Accept(): %v", err) 947 return 948 } 949 defer s.Close() 950 var buf [22]byte 951 if _, err := io.ReadFull(s, buf[:3]); err != nil { 952 t.Errorf("socks5 proxy initial read: %v", err) 953 return 954 } 955 if want := []byte{5, 1, 0}; !bytes.Equal(buf[:3], want) { 956 t.Errorf("socks5 proxy initial read: got %v, want %v", buf[:3], want) 957 return 958 } 959 if _, err := s.Write([]byte{5, 0}); err != nil { 960 t.Errorf("socks5 proxy initial write: %v", err) 961 return 962 } 963 if _, err := io.ReadFull(s, buf[:4]); err != nil { 964 t.Errorf("socks5 proxy second read: %v", err) 965 return 966 } 967 if want := []byte{5, 1, 0}; !bytes.Equal(buf[:3], want) { 968 t.Errorf("socks5 proxy second read: got %v, want %v", buf[:3], want) 969 return 970 } 971 var ipLen int 972 switch buf[3] { 973 case 1: 974 ipLen = 4 975 case 4: 976 ipLen = 16 977 default: 978 t.Fatalf("socks5 proxy second read: unexpected address type %v", buf[4]) 979 } 980 if _, err := io.ReadFull(s, buf[4:ipLen+6]); err != nil { 981 t.Errorf("socks5 proxy address read: %v", err) 982 return 983 } 984 ip := net.IP(buf[4 : ipLen+4]) 985 port := binary.BigEndian.Uint16(buf[ipLen+4 : ipLen+6]) 986 copy(buf[:3], []byte{5, 0, 0}) 987 if _, err := s.Write(buf[:ipLen+6]); err != nil { 988 t.Errorf("socks5 proxy connect write: %v", err) 989 return 990 } 991 done := make(chan struct{}) 992 srv := &Server{Handler: HandlerFunc(func(w ResponseWriter, r *Request) { 993 done <- struct{}{} 994 })} 995 srv.Serve(&oneConnListener{conn: s}) 996 <-done 997 srv.Shutdown(context.Background()) 998 ch <- fmt.Sprintf("proxy for %s:%d", ip, port) 999 }() 1000 1001 pu, err := url.Parse("socks5://" + l.Addr().String()) 1002 if err != nil { 1003 t.Fatal(err) 1004 } 1005 c := ts.Client() 1006 c.Transport.(*Transport).Proxy = ProxyURL(pu) 1007 if _, err := c.Head(ts.URL); err != nil { 1008 t.Error(err) 1009 } 1010 var got string 1011 select { 1012 case got = <-ch: 1013 case <-time.After(5 * time.Second): 1014 t.Fatal("timeout connecting to socks5 proxy") 1015 } 1016 tsu, err := url.Parse(ts.URL) 1017 if err != nil { 1018 t.Fatal(err) 1019 } 1020 want := "proxy for " + tsu.Host 1021 if got != want { 1022 t.Errorf("got %q, want %q", got, want) 1023 } 1024 } 1025 1026 func TestTransportProxy(t *testing.T) { 1027 defer afterTest(t) 1028 ch := make(chan string, 1) 1029 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1030 ch <- "real server" 1031 })) 1032 defer ts.Close() 1033 proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1034 ch <- "proxy for " + r.URL.String() 1035 })) 1036 defer proxy.Close() 1037 1038 pu, err := url.Parse(proxy.URL) 1039 if err != nil { 1040 t.Fatal(err) 1041 } 1042 c := ts.Client() 1043 c.Transport.(*Transport).Proxy = ProxyURL(pu) 1044 if _, err := c.Head(ts.URL); err != nil { 1045 t.Error(err) 1046 } 1047 var got string 1048 select { 1049 case got = <-ch: 1050 case <-time.After(5 * time.Second): 1051 t.Fatal("timeout connecting to http proxy") 1052 } 1053 want := "proxy for " + ts.URL + "/" 1054 if got != want { 1055 t.Errorf("got %q, want %q", got, want) 1056 } 1057 } 1058 1059 // Issue 16997: test transport dial preserves typed errors 1060 func TestTransportDialPreservesNetOpProxyError(t *testing.T) { 1061 defer afterTest(t) 1062 1063 var errDial = errors.New("some dial error") 1064 1065 tr := &Transport{ 1066 Proxy: func(*Request) (*url.URL, error) { 1067 return url.Parse("http://proxy.fake.tld/") 1068 }, 1069 Dial: func(string, string) (net.Conn, error) { 1070 return nil, errDial 1071 }, 1072 } 1073 defer tr.CloseIdleConnections() 1074 1075 c := &Client{Transport: tr} 1076 req, _ := NewRequest("GET", "http://fake.tld", nil) 1077 res, err := c.Do(req) 1078 if err == nil { 1079 res.Body.Close() 1080 t.Fatal("wanted a non-nil error") 1081 } 1082 1083 uerr, ok := err.(*url.Error) 1084 if !ok { 1085 t.Fatalf("got %T, want *url.Error", err) 1086 } 1087 oe, ok := uerr.Err.(*net.OpError) 1088 if !ok { 1089 t.Fatalf("url.Error.Err = %T; want *net.OpError", uerr.Err) 1090 } 1091 want := &net.OpError{ 1092 Op: "proxyconnect", 1093 Net: "tcp", 1094 Err: errDial, // original error, unwrapped. 1095 } 1096 if !reflect.DeepEqual(oe, want) { 1097 t.Errorf("Got error %#v; want %#v", oe, want) 1098 } 1099 } 1100 1101 // TestTransportGzipRecursive sends a gzip quine and checks that the 1102 // client gets the same value back. This is more cute than anything, 1103 // but checks that we don't recurse forever, and checks that 1104 // Content-Encoding is removed. 1105 func TestTransportGzipRecursive(t *testing.T) { 1106 defer afterTest(t) 1107 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1108 w.Header().Set("Content-Encoding", "gzip") 1109 w.Write(rgz) 1110 })) 1111 defer ts.Close() 1112 1113 c := ts.Client() 1114 res, err := c.Get(ts.URL) 1115 if err != nil { 1116 t.Fatal(err) 1117 } 1118 body, err := ioutil.ReadAll(res.Body) 1119 if err != nil { 1120 t.Fatal(err) 1121 } 1122 if !bytes.Equal(body, rgz) { 1123 t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x", 1124 body, rgz) 1125 } 1126 if g, e := res.Header.Get("Content-Encoding"), ""; g != e { 1127 t.Fatalf("Content-Encoding = %q; want %q", g, e) 1128 } 1129 } 1130 1131 // golang.org/issue/7750: request fails when server replies with 1132 // a short gzip body 1133 func TestTransportGzipShort(t *testing.T) { 1134 defer afterTest(t) 1135 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1136 w.Header().Set("Content-Encoding", "gzip") 1137 w.Write([]byte{0x1f, 0x8b}) 1138 })) 1139 defer ts.Close() 1140 1141 c := ts.Client() 1142 res, err := c.Get(ts.URL) 1143 if err != nil { 1144 t.Fatal(err) 1145 } 1146 defer res.Body.Close() 1147 _, err = ioutil.ReadAll(res.Body) 1148 if err == nil { 1149 t.Fatal("Expect an error from reading a body.") 1150 } 1151 if err != io.ErrUnexpectedEOF { 1152 t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err) 1153 } 1154 } 1155 1156 // Wait until number of goroutines is no greater than nmax, or time out. 1157 func waitNumGoroutine(nmax int) int { 1158 nfinal := runtime.NumGoroutine() 1159 for ntries := 10; ntries > 0 && nfinal > nmax; ntries-- { 1160 time.Sleep(50 * time.Millisecond) 1161 runtime.GC() 1162 nfinal = runtime.NumGoroutine() 1163 } 1164 return nfinal 1165 } 1166 1167 // tests that persistent goroutine connections shut down when no longer desired. 1168 func TestTransportPersistConnLeak(t *testing.T) { 1169 // Not parallel: counts goroutines 1170 defer afterTest(t) 1171 1172 const numReq = 25 1173 gotReqCh := make(chan bool, numReq) 1174 unblockCh := make(chan bool, numReq) 1175 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1176 gotReqCh <- true 1177 <-unblockCh 1178 w.Header().Set("Content-Length", "0") 1179 w.WriteHeader(204) 1180 })) 1181 defer ts.Close() 1182 c := ts.Client() 1183 tr := c.Transport.(*Transport) 1184 1185 n0 := runtime.NumGoroutine() 1186 1187 didReqCh := make(chan bool, numReq) 1188 failed := make(chan bool, numReq) 1189 for i := 0; i < numReq; i++ { 1190 go func() { 1191 res, err := c.Get(ts.URL) 1192 didReqCh <- true 1193 if err != nil { 1194 t.Errorf("client fetch error: %v", err) 1195 failed <- true 1196 return 1197 } 1198 res.Body.Close() 1199 }() 1200 } 1201 1202 // Wait for all goroutines to be stuck in the Handler. 1203 for i := 0; i < numReq; i++ { 1204 select { 1205 case <-gotReqCh: 1206 // ok 1207 case <-failed: 1208 close(unblockCh) 1209 return 1210 } 1211 } 1212 1213 nhigh := runtime.NumGoroutine() 1214 1215 // Tell all handlers to unblock and reply. 1216 for i := 0; i < numReq; i++ { 1217 unblockCh <- true 1218 } 1219 1220 // Wait for all HTTP clients to be done. 1221 for i := 0; i < numReq; i++ { 1222 <-didReqCh 1223 } 1224 1225 tr.CloseIdleConnections() 1226 nfinal := waitNumGoroutine(n0 + 5) 1227 1228 growth := nfinal - n0 1229 1230 // We expect 0 or 1 extra goroutine, empirically. Allow up to 5. 1231 // Previously we were leaking one per numReq. 1232 if int(growth) > 5 { 1233 t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth) 1234 t.Error("too many new goroutines") 1235 } 1236 } 1237 1238 // golang.org/issue/4531: Transport leaks goroutines when 1239 // request.ContentLength is explicitly short 1240 func TestTransportPersistConnLeakShortBody(t *testing.T) { 1241 // Not parallel: measures goroutines. 1242 defer afterTest(t) 1243 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1244 })) 1245 defer ts.Close() 1246 c := ts.Client() 1247 tr := c.Transport.(*Transport) 1248 1249 n0 := runtime.NumGoroutine() 1250 body := []byte("Hello") 1251 for i := 0; i < 20; i++ { 1252 req, err := NewRequest("POST", ts.URL, bytes.NewReader(body)) 1253 if err != nil { 1254 t.Fatal(err) 1255 } 1256 req.ContentLength = int64(len(body) - 2) // explicitly short 1257 _, err = c.Do(req) 1258 if err == nil { 1259 t.Fatal("Expect an error from writing too long of a body.") 1260 } 1261 } 1262 nhigh := runtime.NumGoroutine() 1263 tr.CloseIdleConnections() 1264 nfinal := waitNumGoroutine(n0 + 5) 1265 1266 growth := nfinal - n0 1267 1268 // We expect 0 or 1 extra goroutine, empirically. Allow up to 5. 1269 // Previously we were leaking one per numReq. 1270 t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth) 1271 if int(growth) > 5 { 1272 t.Error("too many new goroutines") 1273 } 1274 } 1275 1276 // This used to crash; https://golang.org/issue/3266 1277 func TestTransportIdleConnCrash(t *testing.T) { 1278 defer afterTest(t) 1279 var tr *Transport 1280 1281 unblockCh := make(chan bool, 1) 1282 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1283 <-unblockCh 1284 tr.CloseIdleConnections() 1285 })) 1286 defer ts.Close() 1287 c := ts.Client() 1288 tr = c.Transport.(*Transport) 1289 1290 didreq := make(chan bool) 1291 go func() { 1292 res, err := c.Get(ts.URL) 1293 if err != nil { 1294 t.Error(err) 1295 } else { 1296 res.Body.Close() // returns idle conn 1297 } 1298 didreq <- true 1299 }() 1300 unblockCh <- true 1301 <-didreq 1302 } 1303 1304 // Test that the transport doesn't close the TCP connection early, 1305 // before the response body has been read. This was a regression 1306 // which sadly lacked a triggering test. The large response body made 1307 // the old race easier to trigger. 1308 func TestIssue3644(t *testing.T) { 1309 defer afterTest(t) 1310 const numFoos = 5000 1311 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1312 w.Header().Set("Connection", "close") 1313 for i := 0; i < numFoos; i++ { 1314 w.Write([]byte("foo ")) 1315 } 1316 })) 1317 defer ts.Close() 1318 c := ts.Client() 1319 res, err := c.Get(ts.URL) 1320 if err != nil { 1321 t.Fatal(err) 1322 } 1323 defer res.Body.Close() 1324 bs, err := ioutil.ReadAll(res.Body) 1325 if err != nil { 1326 t.Fatal(err) 1327 } 1328 if len(bs) != numFoos*len("foo ") { 1329 t.Errorf("unexpected response length") 1330 } 1331 } 1332 1333 // Test that a client receives a server's reply, even if the server doesn't read 1334 // the entire request body. 1335 func TestIssue3595(t *testing.T) { 1336 setParallel(t) 1337 defer afterTest(t) 1338 const deniedMsg = "sorry, denied." 1339 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1340 Error(w, deniedMsg, StatusUnauthorized) 1341 })) 1342 defer ts.Close() 1343 c := ts.Client() 1344 res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a')) 1345 if err != nil { 1346 t.Errorf("Post: %v", err) 1347 return 1348 } 1349 got, err := ioutil.ReadAll(res.Body) 1350 if err != nil { 1351 t.Fatalf("Body ReadAll: %v", err) 1352 } 1353 if !strings.Contains(string(got), deniedMsg) { 1354 t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg) 1355 } 1356 } 1357 1358 // From https://golang.org/issue/4454 , 1359 // "client fails to handle requests with no body and chunked encoding" 1360 func TestChunkedNoContent(t *testing.T) { 1361 defer afterTest(t) 1362 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1363 w.WriteHeader(StatusNoContent) 1364 })) 1365 defer ts.Close() 1366 1367 c := ts.Client() 1368 for _, closeBody := range []bool{true, false} { 1369 const n = 4 1370 for i := 1; i <= n; i++ { 1371 res, err := c.Get(ts.URL) 1372 if err != nil { 1373 t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err) 1374 } else { 1375 if closeBody { 1376 res.Body.Close() 1377 } 1378 } 1379 } 1380 } 1381 } 1382 1383 func TestTransportConcurrency(t *testing.T) { 1384 // Not parallel: uses global test hooks. 1385 defer afterTest(t) 1386 maxProcs, numReqs := 16, 500 1387 if testing.Short() { 1388 maxProcs, numReqs = 4, 50 1389 } 1390 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) 1391 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1392 fmt.Fprintf(w, "%v", r.FormValue("echo")) 1393 })) 1394 defer ts.Close() 1395 1396 var wg sync.WaitGroup 1397 wg.Add(numReqs) 1398 1399 // Due to the Transport's "socket late binding" (see 1400 // idleConnCh in transport.go), the numReqs HTTP requests 1401 // below can finish with a dial still outstanding. To keep 1402 // the leak checker happy, keep track of pending dials and 1403 // wait for them to finish (and be closed or returned to the 1404 // idle pool) before we close idle connections. 1405 SetPendingDialHooks(func() { wg.Add(1) }, wg.Done) 1406 defer SetPendingDialHooks(nil, nil) 1407 1408 c := ts.Client() 1409 reqs := make(chan string) 1410 defer close(reqs) 1411 1412 for i := 0; i < maxProcs*2; i++ { 1413 go func() { 1414 for req := range reqs { 1415 res, err := c.Get(ts.URL + "/?echo=" + req) 1416 if err != nil { 1417 t.Errorf("error on req %s: %v", req, err) 1418 wg.Done() 1419 continue 1420 } 1421 all, err := ioutil.ReadAll(res.Body) 1422 if err != nil { 1423 t.Errorf("read error on req %s: %v", req, err) 1424 wg.Done() 1425 continue 1426 } 1427 if string(all) != req { 1428 t.Errorf("body of req %s = %q; want %q", req, all, req) 1429 } 1430 res.Body.Close() 1431 wg.Done() 1432 } 1433 }() 1434 } 1435 for i := 0; i < numReqs; i++ { 1436 reqs <- fmt.Sprintf("request-%d", i) 1437 } 1438 wg.Wait() 1439 } 1440 1441 func TestIssue4191_InfiniteGetTimeout(t *testing.T) { 1442 setParallel(t) 1443 defer afterTest(t) 1444 const debug = false 1445 mux := NewServeMux() 1446 mux.HandleFunc("/get", func(w ResponseWriter, r *Request) { 1447 io.Copy(w, neverEnding('a')) 1448 }) 1449 ts := httptest.NewServer(mux) 1450 defer ts.Close() 1451 timeout := 100 * time.Millisecond 1452 1453 c := ts.Client() 1454 c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) { 1455 conn, err := net.Dial(n, addr) 1456 if err != nil { 1457 return nil, err 1458 } 1459 conn.SetDeadline(time.Now().Add(timeout)) 1460 if debug { 1461 conn = NewLoggingConn("client", conn) 1462 } 1463 return conn, nil 1464 } 1465 1466 getFailed := false 1467 nRuns := 5 1468 if testing.Short() { 1469 nRuns = 1 1470 } 1471 for i := 0; i < nRuns; i++ { 1472 if debug { 1473 println("run", i+1, "of", nRuns) 1474 } 1475 sres, err := c.Get(ts.URL + "/get") 1476 if err != nil { 1477 if !getFailed { 1478 // Make the timeout longer, once. 1479 getFailed = true 1480 t.Logf("increasing timeout") 1481 i-- 1482 timeout *= 10 1483 continue 1484 } 1485 t.Errorf("Error issuing GET: %v", err) 1486 break 1487 } 1488 _, err = io.Copy(ioutil.Discard, sres.Body) 1489 if err == nil { 1490 t.Errorf("Unexpected successful copy") 1491 break 1492 } 1493 } 1494 if debug { 1495 println("tests complete; waiting for handlers to finish") 1496 } 1497 } 1498 1499 func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) { 1500 setParallel(t) 1501 defer afterTest(t) 1502 const debug = false 1503 mux := NewServeMux() 1504 mux.HandleFunc("/get", func(w ResponseWriter, r *Request) { 1505 io.Copy(w, neverEnding('a')) 1506 }) 1507 mux.HandleFunc("/put", func(w ResponseWriter, r *Request) { 1508 defer r.Body.Close() 1509 io.Copy(ioutil.Discard, r.Body) 1510 }) 1511 ts := httptest.NewServer(mux) 1512 timeout := 100 * time.Millisecond 1513 1514 c := ts.Client() 1515 c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) { 1516 conn, err := net.Dial(n, addr) 1517 if err != nil { 1518 return nil, err 1519 } 1520 conn.SetDeadline(time.Now().Add(timeout)) 1521 if debug { 1522 conn = NewLoggingConn("client", conn) 1523 } 1524 return conn, nil 1525 } 1526 1527 getFailed := false 1528 nRuns := 5 1529 if testing.Short() { 1530 nRuns = 1 1531 } 1532 for i := 0; i < nRuns; i++ { 1533 if debug { 1534 println("run", i+1, "of", nRuns) 1535 } 1536 sres, err := c.Get(ts.URL + "/get") 1537 if err != nil { 1538 if !getFailed { 1539 // Make the timeout longer, once. 1540 getFailed = true 1541 t.Logf("increasing timeout") 1542 i-- 1543 timeout *= 10 1544 continue 1545 } 1546 t.Errorf("Error issuing GET: %v", err) 1547 break 1548 } 1549 req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body) 1550 _, err = c.Do(req) 1551 if err == nil { 1552 sres.Body.Close() 1553 t.Errorf("Unexpected successful PUT") 1554 break 1555 } 1556 sres.Body.Close() 1557 } 1558 if debug { 1559 println("tests complete; waiting for handlers to finish") 1560 } 1561 ts.Close() 1562 } 1563 1564 func TestTransportResponseHeaderTimeout(t *testing.T) { 1565 setParallel(t) 1566 defer afterTest(t) 1567 if testing.Short() { 1568 t.Skip("skipping timeout test in -short mode") 1569 } 1570 inHandler := make(chan bool, 1) 1571 mux := NewServeMux() 1572 mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) { 1573 inHandler <- true 1574 }) 1575 mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) { 1576 inHandler <- true 1577 time.Sleep(2 * time.Second) 1578 }) 1579 ts := httptest.NewServer(mux) 1580 defer ts.Close() 1581 1582 c := ts.Client() 1583 c.Transport.(*Transport).ResponseHeaderTimeout = 500 * time.Millisecond 1584 1585 tests := []struct { 1586 path string 1587 want int 1588 wantErr string 1589 }{ 1590 {path: "/fast", want: 200}, 1591 {path: "/slow", wantErr: "timeout awaiting response headers"}, 1592 {path: "/fast", want: 200}, 1593 } 1594 for i, tt := range tests { 1595 req, _ := NewRequest("GET", ts.URL+tt.path, nil) 1596 req = req.WithT(t) 1597 res, err := c.Do(req) 1598 select { 1599 case <-inHandler: 1600 case <-time.After(5 * time.Second): 1601 t.Errorf("never entered handler for test index %d, %s", i, tt.path) 1602 continue 1603 } 1604 if err != nil { 1605 uerr, ok := err.(*url.Error) 1606 if !ok { 1607 t.Errorf("error is not an url.Error; got: %#v", err) 1608 continue 1609 } 1610 nerr, ok := uerr.Err.(net.Error) 1611 if !ok { 1612 t.Errorf("error does not satisfy net.Error interface; got: %#v", err) 1613 continue 1614 } 1615 if !nerr.Timeout() { 1616 t.Errorf("want timeout error; got: %q", nerr) 1617 continue 1618 } 1619 if strings.Contains(err.Error(), tt.wantErr) { 1620 continue 1621 } 1622 t.Errorf("%d. unexpected error: %v", i, err) 1623 continue 1624 } 1625 if tt.wantErr != "" { 1626 t.Errorf("%d. no error. expected error: %v", i, tt.wantErr) 1627 continue 1628 } 1629 if res.StatusCode != tt.want { 1630 t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want) 1631 } 1632 } 1633 } 1634 1635 func TestTransportCancelRequest(t *testing.T) { 1636 setParallel(t) 1637 defer afterTest(t) 1638 if testing.Short() { 1639 t.Skip("skipping test in -short mode") 1640 } 1641 unblockc := make(chan bool) 1642 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1643 fmt.Fprintf(w, "Hello") 1644 w.(Flusher).Flush() // send headers and some body 1645 <-unblockc 1646 })) 1647 defer ts.Close() 1648 defer close(unblockc) 1649 1650 c := ts.Client() 1651 tr := c.Transport.(*Transport) 1652 1653 req, _ := NewRequest("GET", ts.URL, nil) 1654 res, err := c.Do(req) 1655 if err != nil { 1656 t.Fatal(err) 1657 } 1658 go func() { 1659 time.Sleep(1 * time.Second) 1660 tr.CancelRequest(req) 1661 }() 1662 t0 := time.Now() 1663 body, err := ioutil.ReadAll(res.Body) 1664 d := time.Since(t0) 1665 1666 if err != ExportErrRequestCanceled { 1667 t.Errorf("Body.Read error = %v; want errRequestCanceled", err) 1668 } 1669 if string(body) != "Hello" { 1670 t.Errorf("Body = %q; want Hello", body) 1671 } 1672 if d < 500*time.Millisecond { 1673 t.Errorf("expected ~1 second delay; got %v", d) 1674 } 1675 // Verify no outstanding requests after readLoop/writeLoop 1676 // goroutines shut down. 1677 for tries := 5; tries > 0; tries-- { 1678 n := tr.NumPendingRequestsForTesting() 1679 if n == 0 { 1680 break 1681 } 1682 time.Sleep(100 * time.Millisecond) 1683 if tries == 1 { 1684 t.Errorf("pending requests = %d; want 0", n) 1685 } 1686 } 1687 } 1688 1689 func TestTransportCancelRequestInDial(t *testing.T) { 1690 defer afterTest(t) 1691 if testing.Short() { 1692 t.Skip("skipping test in -short mode") 1693 } 1694 var logbuf bytes.Buffer 1695 eventLog := log.New(&logbuf, "", 0) 1696 1697 unblockDial := make(chan bool) 1698 defer close(unblockDial) 1699 1700 inDial := make(chan bool) 1701 tr := &Transport{ 1702 Dial: func(network, addr string) (net.Conn, error) { 1703 eventLog.Println("dial: blocking") 1704 inDial <- true 1705 <-unblockDial 1706 return nil, errors.New("nope") 1707 }, 1708 } 1709 cl := &Client{Transport: tr} 1710 gotres := make(chan bool) 1711 req, _ := NewRequest("GET", "http://something.no-network.tld/", nil) 1712 go func() { 1713 _, err := cl.Do(req) 1714 eventLog.Printf("Get = %v", err) 1715 gotres <- true 1716 }() 1717 1718 select { 1719 case <-inDial: 1720 case <-time.After(5 * time.Second): 1721 t.Fatal("timeout; never saw blocking dial") 1722 } 1723 1724 eventLog.Printf("canceling") 1725 tr.CancelRequest(req) 1726 tr.CancelRequest(req) // used to panic on second call 1727 1728 select { 1729 case <-gotres: 1730 case <-time.After(5 * time.Second): 1731 panic("hang. events are: " + logbuf.String()) 1732 } 1733 1734 got := logbuf.String() 1735 want := `dial: blocking 1736 canceling 1737 Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection 1738 ` 1739 if got != want { 1740 t.Errorf("Got events:\n%s\nWant:\n%s", got, want) 1741 } 1742 } 1743 1744 func TestCancelRequestWithChannel(t *testing.T) { 1745 setParallel(t) 1746 defer afterTest(t) 1747 if testing.Short() { 1748 t.Skip("skipping test in -short mode") 1749 } 1750 unblockc := make(chan bool) 1751 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1752 fmt.Fprintf(w, "Hello") 1753 w.(Flusher).Flush() // send headers and some body 1754 <-unblockc 1755 })) 1756 defer ts.Close() 1757 defer close(unblockc) 1758 1759 c := ts.Client() 1760 tr := c.Transport.(*Transport) 1761 1762 req, _ := NewRequest("GET", ts.URL, nil) 1763 ch := make(chan struct{}) 1764 req.Cancel = ch 1765 1766 res, err := c.Do(req) 1767 if err != nil { 1768 t.Fatal(err) 1769 } 1770 go func() { 1771 time.Sleep(1 * time.Second) 1772 close(ch) 1773 }() 1774 t0 := time.Now() 1775 body, err := ioutil.ReadAll(res.Body) 1776 d := time.Since(t0) 1777 1778 if err != ExportErrRequestCanceled { 1779 t.Errorf("Body.Read error = %v; want errRequestCanceled", err) 1780 } 1781 if string(body) != "Hello" { 1782 t.Errorf("Body = %q; want Hello", body) 1783 } 1784 if d < 500*time.Millisecond { 1785 t.Errorf("expected ~1 second delay; got %v", d) 1786 } 1787 // Verify no outstanding requests after readLoop/writeLoop 1788 // goroutines shut down. 1789 for tries := 5; tries > 0; tries-- { 1790 n := tr.NumPendingRequestsForTesting() 1791 if n == 0 { 1792 break 1793 } 1794 time.Sleep(100 * time.Millisecond) 1795 if tries == 1 { 1796 t.Errorf("pending requests = %d; want 0", n) 1797 } 1798 } 1799 } 1800 1801 func TestCancelRequestWithChannelBeforeDo_Cancel(t *testing.T) { 1802 testCancelRequestWithChannelBeforeDo(t, false) 1803 } 1804 func TestCancelRequestWithChannelBeforeDo_Context(t *testing.T) { 1805 testCancelRequestWithChannelBeforeDo(t, true) 1806 } 1807 func testCancelRequestWithChannelBeforeDo(t *testing.T, withCtx bool) { 1808 setParallel(t) 1809 defer afterTest(t) 1810 unblockc := make(chan bool) 1811 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1812 <-unblockc 1813 })) 1814 defer ts.Close() 1815 defer close(unblockc) 1816 1817 c := ts.Client() 1818 1819 req, _ := NewRequest("GET", ts.URL, nil) 1820 if withCtx { 1821 ctx, cancel := context.WithCancel(context.Background()) 1822 cancel() 1823 req = req.WithContext(ctx) 1824 } else { 1825 ch := make(chan struct{}) 1826 req.Cancel = ch 1827 close(ch) 1828 } 1829 1830 _, err := c.Do(req) 1831 if ue, ok := err.(*url.Error); ok { 1832 err = ue.Err 1833 } 1834 if withCtx { 1835 if err != context.Canceled { 1836 t.Errorf("Do error = %v; want %v", err, context.Canceled) 1837 } 1838 } else { 1839 if err == nil || !strings.Contains(err.Error(), "canceled") { 1840 t.Errorf("Do error = %v; want cancelation", err) 1841 } 1842 } 1843 } 1844 1845 // Issue 11020. The returned error message should be errRequestCanceled 1846 func TestTransportCancelBeforeResponseHeaders(t *testing.T) { 1847 defer afterTest(t) 1848 1849 serverConnCh := make(chan net.Conn, 1) 1850 tr := &Transport{ 1851 Dial: func(network, addr string) (net.Conn, error) { 1852 cc, sc := net.Pipe() 1853 serverConnCh <- sc 1854 return cc, nil 1855 }, 1856 } 1857 defer tr.CloseIdleConnections() 1858 errc := make(chan error, 1) 1859 req, _ := NewRequest("GET", "http://example.com/", nil) 1860 go func() { 1861 _, err := tr.RoundTrip(req) 1862 errc <- err 1863 }() 1864 1865 sc := <-serverConnCh 1866 verb := make([]byte, 3) 1867 if _, err := io.ReadFull(sc, verb); err != nil { 1868 t.Errorf("Error reading HTTP verb from server: %v", err) 1869 } 1870 if string(verb) != "GET" { 1871 t.Errorf("server received %q; want GET", verb) 1872 } 1873 defer sc.Close() 1874 1875 tr.CancelRequest(req) 1876 1877 err := <-errc 1878 if err == nil { 1879 t.Fatalf("unexpected success from RoundTrip") 1880 } 1881 if err != ExportErrRequestCanceled { 1882 t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err) 1883 } 1884 } 1885 1886 // golang.org/issue/3672 -- Client can't close HTTP stream 1887 // Calling Close on a Response.Body used to just read until EOF. 1888 // Now it actually closes the TCP connection. 1889 func TestTransportCloseResponseBody(t *testing.T) { 1890 defer afterTest(t) 1891 writeErr := make(chan error, 1) 1892 msg := []byte("young\n") 1893 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 1894 for { 1895 _, err := w.Write(msg) 1896 if err != nil { 1897 writeErr <- err 1898 return 1899 } 1900 w.(Flusher).Flush() 1901 } 1902 })) 1903 defer ts.Close() 1904 1905 c := ts.Client() 1906 tr := c.Transport.(*Transport) 1907 1908 req, _ := NewRequest("GET", ts.URL, nil) 1909 defer tr.CancelRequest(req) 1910 1911 res, err := c.Do(req) 1912 if err != nil { 1913 t.Fatal(err) 1914 } 1915 1916 const repeats = 3 1917 buf := make([]byte, len(msg)*repeats) 1918 want := bytes.Repeat(msg, repeats) 1919 1920 _, err = io.ReadFull(res.Body, buf) 1921 if err != nil { 1922 t.Fatal(err) 1923 } 1924 if !bytes.Equal(buf, want) { 1925 t.Fatalf("read %q; want %q", buf, want) 1926 } 1927 didClose := make(chan error, 1) 1928 go func() { 1929 didClose <- res.Body.Close() 1930 }() 1931 select { 1932 case err := <-didClose: 1933 if err != nil { 1934 t.Errorf("Close = %v", err) 1935 } 1936 case <-time.After(10 * time.Second): 1937 t.Fatal("too long waiting for close") 1938 } 1939 select { 1940 case err := <-writeErr: 1941 if err == nil { 1942 t.Errorf("expected non-nil write error") 1943 } 1944 case <-time.After(10 * time.Second): 1945 t.Fatal("too long waiting for write error") 1946 } 1947 } 1948 1949 type fooProto struct{} 1950 1951 func (fooProto) RoundTrip(req *Request) (*Response, error) { 1952 res := &Response{ 1953 Status: "200 OK", 1954 StatusCode: 200, 1955 Header: make(Header), 1956 Body: ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())), 1957 } 1958 return res, nil 1959 } 1960 1961 func TestTransportAltProto(t *testing.T) { 1962 defer afterTest(t) 1963 tr := &Transport{} 1964 c := &Client{Transport: tr} 1965 tr.RegisterProtocol("foo", fooProto{}) 1966 res, err := c.Get("foo://bar.com/path") 1967 if err != nil { 1968 t.Fatal(err) 1969 } 1970 bodyb, err := ioutil.ReadAll(res.Body) 1971 if err != nil { 1972 t.Fatal(err) 1973 } 1974 body := string(bodyb) 1975 if e := "You wanted foo://bar.com/path"; body != e { 1976 t.Errorf("got response %q, want %q", body, e) 1977 } 1978 } 1979 1980 func TestTransportNoHost(t *testing.T) { 1981 defer afterTest(t) 1982 tr := &Transport{} 1983 _, err := tr.RoundTrip(&Request{ 1984 Header: make(Header), 1985 URL: &url.URL{ 1986 Scheme: "http", 1987 }, 1988 }) 1989 want := "http: no Host in request URL" 1990 if got := fmt.Sprint(err); got != want { 1991 t.Errorf("error = %v; want %q", err, want) 1992 } 1993 } 1994 1995 // Issue 13311 1996 func TestTransportEmptyMethod(t *testing.T) { 1997 req, _ := NewRequest("GET", "http://foo.com/", nil) 1998 req.Method = "" // docs say "For client requests an empty string means GET" 1999 got, err := httputil.DumpRequestOut(req, false) // DumpRequestOut uses Transport 2000 if err != nil { 2001 t.Fatal(err) 2002 } 2003 if !strings.Contains(string(got), "GET ") { 2004 t.Fatalf("expected substring 'GET '; got: %s", got) 2005 } 2006 } 2007 2008 func TestTransportSocketLateBinding(t *testing.T) { 2009 setParallel(t) 2010 defer afterTest(t) 2011 2012 mux := NewServeMux() 2013 fooGate := make(chan bool, 1) 2014 mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) { 2015 w.Header().Set("foo-ipport", r.RemoteAddr) 2016 w.(Flusher).Flush() 2017 <-fooGate 2018 }) 2019 mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) { 2020 w.Header().Set("bar-ipport", r.RemoteAddr) 2021 }) 2022 ts := httptest.NewServer(mux) 2023 defer ts.Close() 2024 2025 dialGate := make(chan bool, 1) 2026 c := ts.Client() 2027 c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) { 2028 if <-dialGate { 2029 return net.Dial(n, addr) 2030 } 2031 return nil, errors.New("manually closed") 2032 } 2033 2034 dialGate <- true // only allow one dial 2035 fooRes, err := c.Get(ts.URL + "/foo") 2036 if err != nil { 2037 t.Fatal(err) 2038 } 2039 fooAddr := fooRes.Header.Get("foo-ipport") 2040 if fooAddr == "" { 2041 t.Fatal("No addr on /foo request") 2042 } 2043 time.AfterFunc(200*time.Millisecond, func() { 2044 // let the foo response finish so we can use its 2045 // connection for /bar 2046 fooGate <- true 2047 io.Copy(ioutil.Discard, fooRes.Body) 2048 fooRes.Body.Close() 2049 }) 2050 2051 barRes, err := c.Get(ts.URL + "/bar") 2052 if err != nil { 2053 t.Fatal(err) 2054 } 2055 barAddr := barRes.Header.Get("bar-ipport") 2056 if barAddr != fooAddr { 2057 t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr) 2058 } 2059 barRes.Body.Close() 2060 dialGate <- false 2061 } 2062 2063 // Issue 2184 2064 func TestTransportReading100Continue(t *testing.T) { 2065 defer afterTest(t) 2066 2067 const numReqs = 5 2068 reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) } 2069 reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) } 2070 2071 send100Response := func(w *io.PipeWriter, r *io.PipeReader) { 2072 defer w.Close() 2073 defer r.Close() 2074 br := bufio.NewReader(r) 2075 n := 0 2076 for { 2077 n++ 2078 req, err := ReadRequest(br) 2079 if err == io.EOF { 2080 return 2081 } 2082 if err != nil { 2083 t.Error(err) 2084 return 2085 } 2086 slurp, err := ioutil.ReadAll(req.Body) 2087 if err != nil { 2088 t.Errorf("Server request body slurp: %v", err) 2089 return 2090 } 2091 id := req.Header.Get("Request-Id") 2092 resCode := req.Header.Get("X-Want-Response-Code") 2093 if resCode == "" { 2094 resCode = "100 Continue" 2095 if string(slurp) != reqBody(n) { 2096 t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n)) 2097 } 2098 } 2099 body := fmt.Sprintf("Response number %d", n) 2100 v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s 2101 Date: Thu, 28 Feb 2013 17:55:41 GMT 2102 2103 HTTP/1.1 200 OK 2104 Content-Type: text/html 2105 Echo-Request-Id: %s 2106 Content-Length: %d 2107 2108 %s`, resCode, id, len(body), body), "\n", "\r\n", -1)) 2109 w.Write(v) 2110 if id == reqID(numReqs) { 2111 return 2112 } 2113 } 2114 2115 } 2116 2117 tr := &Transport{ 2118 Dial: func(n, addr string) (net.Conn, error) { 2119 sr, sw := io.Pipe() // server read/write 2120 cr, cw := io.Pipe() // client read/write 2121 conn := &rwTestConn{ 2122 Reader: cr, 2123 Writer: sw, 2124 closeFunc: func() error { 2125 sw.Close() 2126 cw.Close() 2127 return nil 2128 }, 2129 } 2130 go send100Response(cw, sr) 2131 return conn, nil 2132 }, 2133 DisableKeepAlives: false, 2134 } 2135 defer tr.CloseIdleConnections() 2136 c := &Client{Transport: tr} 2137 2138 testResponse := func(req *Request, name string, wantCode int) { 2139 res, err := c.Do(req) 2140 if err != nil { 2141 t.Fatalf("%s: Do: %v", name, err) 2142 } 2143 if res.StatusCode != wantCode { 2144 t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode) 2145 } 2146 if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack { 2147 t.Errorf("%s: response id %q != request id %q", name, idBack, id) 2148 } 2149 _, err = ioutil.ReadAll(res.Body) 2150 if err != nil { 2151 t.Fatalf("%s: Slurp error: %v", name, err) 2152 } 2153 } 2154 2155 // Few 100 responses, making sure we're not off-by-one. 2156 for i := 1; i <= numReqs; i++ { 2157 req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i))) 2158 req.Header.Set("Request-Id", reqID(i)) 2159 testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200) 2160 } 2161 2162 // And some other informational 1xx but non-100 responses, to test 2163 // we return them but don't re-use the connection. 2164 for i := 1; i <= numReqs; i++ { 2165 req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i))) 2166 req.Header.Set("X-Want-Response-Code", "123 Sesame Street") 2167 testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123) 2168 } 2169 } 2170 2171 type proxyFromEnvTest struct { 2172 req string // URL to fetch; blank means "http://example.com" 2173 2174 env string // HTTP_PROXY 2175 httpsenv string // HTTPS_PROXY 2176 noenv string // NO_PROXY 2177 reqmeth string // REQUEST_METHOD 2178 2179 want string 2180 wanterr error 2181 } 2182 2183 func (t proxyFromEnvTest) String() string { 2184 var buf bytes.Buffer 2185 space := func() { 2186 if buf.Len() > 0 { 2187 buf.WriteByte(' ') 2188 } 2189 } 2190 if t.env != "" { 2191 fmt.Fprintf(&buf, "http_proxy=%q", t.env) 2192 } 2193 if t.httpsenv != "" { 2194 space() 2195 fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv) 2196 } 2197 if t.noenv != "" { 2198 space() 2199 fmt.Fprintf(&buf, "no_proxy=%q", t.noenv) 2200 } 2201 if t.reqmeth != "" { 2202 space() 2203 fmt.Fprintf(&buf, "request_method=%q", t.reqmeth) 2204 } 2205 req := "http://example.com" 2206 if t.req != "" { 2207 req = t.req 2208 } 2209 space() 2210 fmt.Fprintf(&buf, "req=%q", req) 2211 return strings.TrimSpace(buf.String()) 2212 } 2213 2214 var proxyFromEnvTests = []proxyFromEnvTest{ 2215 {env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"}, 2216 {env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"}, 2217 {env: "cache.corp.example.com", want: "http://cache.corp.example.com"}, 2218 {env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"}, 2219 {env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"}, 2220 {env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"}, 2221 {env: "socks5://127.0.0.1", want: "socks5://127.0.0.1"}, 2222 2223 // Don't use secure for http 2224 {req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"}, 2225 // Use secure for https. 2226 {req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"}, 2227 {req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"}, 2228 2229 // Issue 16405: don't use HTTP_PROXY in a CGI environment, 2230 // where HTTP_PROXY can be attacker-controlled. 2231 {env: "http://10.1.2.3:8080", reqmeth: "POST", 2232 want: "<nil>", 2233 wanterr: errors.New("net/http: refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxy")}, 2234 2235 {want: "<nil>"}, 2236 2237 {noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"}, 2238 {noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"}, 2239 {noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"}, 2240 {noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"}, 2241 {noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"}, 2242 } 2243 2244 func TestProxyFromEnvironment(t *testing.T) { 2245 ResetProxyEnv() 2246 defer ResetProxyEnv() 2247 for _, tt := range proxyFromEnvTests { 2248 os.Setenv("HTTP_PROXY", tt.env) 2249 os.Setenv("HTTPS_PROXY", tt.httpsenv) 2250 os.Setenv("NO_PROXY", tt.noenv) 2251 os.Setenv("REQUEST_METHOD", tt.reqmeth) 2252 ResetCachedEnvironment() 2253 reqURL := tt.req 2254 if reqURL == "" { 2255 reqURL = "http://example.com" 2256 } 2257 req, _ := NewRequest("GET", reqURL, nil) 2258 url, err := ProxyFromEnvironment(req) 2259 if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e { 2260 t.Errorf("%v: got error = %q, want %q", tt, g, e) 2261 continue 2262 } 2263 if got := fmt.Sprintf("%s", url); got != tt.want { 2264 t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want) 2265 } 2266 } 2267 } 2268 2269 func TestIdleConnChannelLeak(t *testing.T) { 2270 // Not parallel: uses global test hooks. 2271 var mu sync.Mutex 2272 var n int 2273 2274 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2275 mu.Lock() 2276 n++ 2277 mu.Unlock() 2278 })) 2279 defer ts.Close() 2280 2281 const nReqs = 5 2282 didRead := make(chan bool, nReqs) 2283 SetReadLoopBeforeNextReadHook(func() { didRead <- true }) 2284 defer SetReadLoopBeforeNextReadHook(nil) 2285 2286 c := ts.Client() 2287 tr := c.Transport.(*Transport) 2288 tr.Dial = func(netw, addr string) (net.Conn, error) { 2289 return net.Dial(netw, ts.Listener.Addr().String()) 2290 } 2291 2292 // First, without keep-alives. 2293 for _, disableKeep := range []bool{true, false} { 2294 tr.DisableKeepAlives = disableKeep 2295 for i := 0; i < nReqs; i++ { 2296 _, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i)) 2297 if err != nil { 2298 t.Fatal(err) 2299 } 2300 // Note: no res.Body.Close is needed here, since the 2301 // response Content-Length is zero. Perhaps the test 2302 // should be more explicit and use a HEAD, but tests 2303 // elsewhere guarantee that zero byte responses generate 2304 // a "Content-Length: 0" instead of chunking. 2305 } 2306 2307 // At this point, each of the 5 Transport.readLoop goroutines 2308 // are scheduling noting that there are no response bodies (see 2309 // earlier comment), and are then calling putIdleConn, which 2310 // decrements this count. Usually that happens quickly, which is 2311 // why this test has seemed to work for ages. But it's still 2312 // racey: we have wait for them to finish first. See Issue 10427 2313 for i := 0; i < nReqs; i++ { 2314 <-didRead 2315 } 2316 2317 if got := tr.IdleConnChMapSizeForTesting(); got != 0 { 2318 t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got) 2319 } 2320 } 2321 } 2322 2323 // Verify the status quo: that the Client.Post function coerces its 2324 // body into a ReadCloser if it's a Closer, and that the Transport 2325 // then closes it. 2326 func TestTransportClosesRequestBody(t *testing.T) { 2327 defer afterTest(t) 2328 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2329 io.Copy(ioutil.Discard, r.Body) 2330 })) 2331 defer ts.Close() 2332 2333 c := ts.Client() 2334 2335 closes := 0 2336 2337 res, err := c.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")}) 2338 if err != nil { 2339 t.Fatal(err) 2340 } 2341 res.Body.Close() 2342 if closes != 1 { 2343 t.Errorf("closes = %d; want 1", closes) 2344 } 2345 } 2346 2347 func TestTransportTLSHandshakeTimeout(t *testing.T) { 2348 defer afterTest(t) 2349 if testing.Short() { 2350 t.Skip("skipping in short mode") 2351 } 2352 ln := newLocalListener(t) 2353 defer ln.Close() 2354 testdonec := make(chan struct{}) 2355 defer close(testdonec) 2356 2357 go func() { 2358 c, err := ln.Accept() 2359 if err != nil { 2360 t.Error(err) 2361 return 2362 } 2363 <-testdonec 2364 c.Close() 2365 }() 2366 2367 getdonec := make(chan struct{}) 2368 go func() { 2369 defer close(getdonec) 2370 tr := &Transport{ 2371 Dial: func(_, _ string) (net.Conn, error) { 2372 return net.Dial("tcp", ln.Addr().String()) 2373 }, 2374 TLSHandshakeTimeout: 250 * time.Millisecond, 2375 } 2376 cl := &Client{Transport: tr} 2377 _, err := cl.Get("https://dummy.tld/") 2378 if err == nil { 2379 t.Error("expected error") 2380 return 2381 } 2382 ue, ok := err.(*url.Error) 2383 if !ok { 2384 t.Errorf("expected url.Error; got %#v", err) 2385 return 2386 } 2387 ne, ok := ue.Err.(net.Error) 2388 if !ok { 2389 t.Errorf("expected net.Error; got %#v", err) 2390 return 2391 } 2392 if !ne.Timeout() { 2393 t.Errorf("expected timeout error; got %v", err) 2394 } 2395 if !strings.Contains(err.Error(), "handshake timeout") { 2396 t.Errorf("expected 'handshake timeout' in error; got %v", err) 2397 } 2398 }() 2399 select { 2400 case <-getdonec: 2401 case <-time.After(5 * time.Second): 2402 t.Error("test timeout; TLS handshake hung?") 2403 } 2404 } 2405 2406 // Trying to repro golang.org/issue/3514 2407 func TestTLSServerClosesConnection(t *testing.T) { 2408 defer afterTest(t) 2409 testenv.SkipFlaky(t, 7634) 2410 2411 closedc := make(chan bool, 1) 2412 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2413 if strings.Contains(r.URL.Path, "/keep-alive-then-die") { 2414 conn, _, _ := w.(Hijacker).Hijack() 2415 conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) 2416 conn.Close() 2417 closedc <- true 2418 return 2419 } 2420 fmt.Fprintf(w, "hello") 2421 })) 2422 defer ts.Close() 2423 2424 c := ts.Client() 2425 tr := c.Transport.(*Transport) 2426 2427 var nSuccess = 0 2428 var errs []error 2429 const trials = 20 2430 for i := 0; i < trials; i++ { 2431 tr.CloseIdleConnections() 2432 res, err := c.Get(ts.URL + "/keep-alive-then-die") 2433 if err != nil { 2434 t.Fatal(err) 2435 } 2436 <-closedc 2437 slurp, err := ioutil.ReadAll(res.Body) 2438 if err != nil { 2439 t.Fatal(err) 2440 } 2441 if string(slurp) != "foo" { 2442 t.Errorf("Got %q, want foo", slurp) 2443 } 2444 2445 // Now try again and see if we successfully 2446 // pick a new connection. 2447 res, err = c.Get(ts.URL + "/") 2448 if err != nil { 2449 errs = append(errs, err) 2450 continue 2451 } 2452 slurp, err = ioutil.ReadAll(res.Body) 2453 if err != nil { 2454 errs = append(errs, err) 2455 continue 2456 } 2457 nSuccess++ 2458 } 2459 if nSuccess > 0 { 2460 t.Logf("successes = %d of %d", nSuccess, trials) 2461 } else { 2462 t.Errorf("All runs failed:") 2463 } 2464 for _, err := range errs { 2465 t.Logf(" err: %v", err) 2466 } 2467 } 2468 2469 // byteFromChanReader is an io.Reader that reads a single byte at a 2470 // time from the channel. When the channel is closed, the reader 2471 // returns io.EOF. 2472 type byteFromChanReader chan byte 2473 2474 func (c byteFromChanReader) Read(p []byte) (n int, err error) { 2475 if len(p) == 0 { 2476 return 2477 } 2478 b, ok := <-c 2479 if !ok { 2480 return 0, io.EOF 2481 } 2482 p[0] = b 2483 return 1, nil 2484 } 2485 2486 // Verifies that the Transport doesn't reuse a connection in the case 2487 // where the server replies before the request has been fully 2488 // written. We still honor that reply (see TestIssue3595), but don't 2489 // send future requests on the connection because it's then in a 2490 // questionable state. 2491 // golang.org/issue/7569 2492 func TestTransportNoReuseAfterEarlyResponse(t *testing.T) { 2493 setParallel(t) 2494 defer afterTest(t) 2495 var sconn struct { 2496 sync.Mutex 2497 c net.Conn 2498 } 2499 var getOkay bool 2500 closeConn := func() { 2501 sconn.Lock() 2502 defer sconn.Unlock() 2503 if sconn.c != nil { 2504 sconn.c.Close() 2505 sconn.c = nil 2506 if !getOkay { 2507 t.Logf("Closed server connection") 2508 } 2509 } 2510 } 2511 defer closeConn() 2512 2513 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2514 if r.Method == "GET" { 2515 io.WriteString(w, "bar") 2516 return 2517 } 2518 conn, _, _ := w.(Hijacker).Hijack() 2519 sconn.Lock() 2520 sconn.c = conn 2521 sconn.Unlock() 2522 conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive 2523 go io.Copy(ioutil.Discard, conn) 2524 })) 2525 defer ts.Close() 2526 c := ts.Client() 2527 2528 const bodySize = 256 << 10 2529 finalBit := make(byteFromChanReader, 1) 2530 req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit)) 2531 req.ContentLength = bodySize 2532 res, err := c.Do(req) 2533 if err := wantBody(res, err, "foo"); err != nil { 2534 t.Errorf("POST response: %v", err) 2535 } 2536 donec := make(chan bool) 2537 go func() { 2538 defer close(donec) 2539 res, err = c.Get(ts.URL) 2540 if err := wantBody(res, err, "bar"); err != nil { 2541 t.Errorf("GET response: %v", err) 2542 return 2543 } 2544 getOkay = true // suppress test noise 2545 }() 2546 time.AfterFunc(5*time.Second, closeConn) 2547 select { 2548 case <-donec: 2549 finalBit <- 'x' // unblock the writeloop of the first Post 2550 close(finalBit) 2551 case <-time.After(7 * time.Second): 2552 t.Fatal("timeout waiting for GET request to finish") 2553 } 2554 } 2555 2556 // Tests that we don't leak Transport persistConn.readLoop goroutines 2557 // when a server hangs up immediately after saying it would keep-alive. 2558 func TestTransportIssue10457(t *testing.T) { 2559 defer afterTest(t) // used to fail in goroutine leak check 2560 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2561 // Send a response with no body, keep-alive 2562 // (implicit), and then lie and immediately close the 2563 // connection. This forces the Transport's readLoop to 2564 // immediately Peek an io.EOF and get to the point 2565 // that used to hang. 2566 conn, _, _ := w.(Hijacker).Hijack() 2567 conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive 2568 conn.Close() 2569 })) 2570 defer ts.Close() 2571 c := ts.Client() 2572 2573 res, err := c.Get(ts.URL) 2574 if err != nil { 2575 t.Fatalf("Get: %v", err) 2576 } 2577 defer res.Body.Close() 2578 2579 // Just a sanity check that we at least get the response. The real 2580 // test here is that the "defer afterTest" above doesn't find any 2581 // leaked goroutines. 2582 if got, want := res.Header.Get("Foo"), "Bar"; got != want { 2583 t.Errorf("Foo header = %q; want %q", got, want) 2584 } 2585 } 2586 2587 type errorReader struct { 2588 err error 2589 } 2590 2591 func (e errorReader) Read(p []byte) (int, error) { return 0, e.err } 2592 2593 type closerFunc func() error 2594 2595 func (f closerFunc) Close() error { return f() } 2596 2597 type writerFuncConn struct { 2598 net.Conn 2599 write func(p []byte) (n int, err error) 2600 } 2601 2602 func (c writerFuncConn) Write(p []byte) (n int, err error) { return c.write(p) } 2603 2604 // Issue 4677. If we try to reuse a connection that the server is in the 2605 // process of closing, we may end up successfully writing out our request (or a 2606 // portion of our request) only to find a connection error when we try to read 2607 // from (or finish writing to) the socket. 2608 // 2609 // NOTE: we resend a request only if the request is idempotent, we reused a 2610 // keep-alive connection, and we haven't yet received any header data. This 2611 // automatically prevents an infinite resend loop because we'll run out of the 2612 // cached keep-alive connections eventually. 2613 func TestRetryIdempotentRequestsOnError(t *testing.T) { 2614 defer afterTest(t) 2615 2616 var ( 2617 mu sync.Mutex 2618 logbuf bytes.Buffer 2619 ) 2620 logf := func(format string, args ...interface{}) { 2621 mu.Lock() 2622 defer mu.Unlock() 2623 fmt.Fprintf(&logbuf, format, args...) 2624 logbuf.WriteByte('\n') 2625 } 2626 2627 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2628 logf("Handler") 2629 w.Header().Set("X-Status", "ok") 2630 })) 2631 defer ts.Close() 2632 2633 var writeNumAtomic int32 2634 c := ts.Client() 2635 c.Transport.(*Transport).Dial = func(network, addr string) (net.Conn, error) { 2636 logf("Dial") 2637 c, err := net.Dial(network, ts.Listener.Addr().String()) 2638 if err != nil { 2639 logf("Dial error: %v", err) 2640 return nil, err 2641 } 2642 return &writerFuncConn{ 2643 Conn: c, 2644 write: func(p []byte) (n int, err error) { 2645 if atomic.AddInt32(&writeNumAtomic, 1) == 2 { 2646 logf("intentional write failure") 2647 return 0, errors.New("second write fails") 2648 } 2649 logf("Write(%q)", p) 2650 return c.Write(p) 2651 }, 2652 }, nil 2653 } 2654 2655 SetRoundTripRetried(func() { 2656 logf("Retried.") 2657 }) 2658 defer SetRoundTripRetried(nil) 2659 2660 for i := 0; i < 3; i++ { 2661 res, err := c.Get("http://fake.golang/") 2662 if err != nil { 2663 t.Fatalf("i=%d: Get = %v", i, err) 2664 } 2665 res.Body.Close() 2666 } 2667 2668 mu.Lock() 2669 got := logbuf.String() 2670 mu.Unlock() 2671 const want = `Dial 2672 Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n") 2673 Handler 2674 intentional write failure 2675 Retried. 2676 Dial 2677 Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n") 2678 Handler 2679 Write("GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n") 2680 Handler 2681 ` 2682 if got != want { 2683 t.Errorf("Log of events differs. Got:\n%s\nWant:\n%s", got, want) 2684 } 2685 } 2686 2687 // Issue 6981 2688 func TestTransportClosesBodyOnError(t *testing.T) { 2689 setParallel(t) 2690 defer afterTest(t) 2691 readBody := make(chan error, 1) 2692 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2693 _, err := ioutil.ReadAll(r.Body) 2694 readBody <- err 2695 })) 2696 defer ts.Close() 2697 c := ts.Client() 2698 fakeErr := errors.New("fake error") 2699 didClose := make(chan bool, 1) 2700 req, _ := NewRequest("POST", ts.URL, struct { 2701 io.Reader 2702 io.Closer 2703 }{ 2704 io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}), 2705 closerFunc(func() error { 2706 select { 2707 case didClose <- true: 2708 default: 2709 } 2710 return nil 2711 }), 2712 }) 2713 res, err := c.Do(req) 2714 if res != nil { 2715 defer res.Body.Close() 2716 } 2717 if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) { 2718 t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error()) 2719 } 2720 select { 2721 case err := <-readBody: 2722 if err == nil { 2723 t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'") 2724 } 2725 case <-time.After(5 * time.Second): 2726 t.Error("timeout waiting for server handler to complete") 2727 } 2728 select { 2729 case <-didClose: 2730 default: 2731 t.Errorf("didn't see Body.Close") 2732 } 2733 } 2734 2735 func TestTransportDialTLS(t *testing.T) { 2736 setParallel(t) 2737 defer afterTest(t) 2738 var mu sync.Mutex // guards following 2739 var gotReq, didDial bool 2740 2741 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2742 mu.Lock() 2743 gotReq = true 2744 mu.Unlock() 2745 })) 2746 defer ts.Close() 2747 c := ts.Client() 2748 c.Transport.(*Transport).DialTLS = func(netw, addr string) (net.Conn, error) { 2749 mu.Lock() 2750 didDial = true 2751 mu.Unlock() 2752 c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig) 2753 if err != nil { 2754 return nil, err 2755 } 2756 return c, c.Handshake() 2757 } 2758 2759 res, err := c.Get(ts.URL) 2760 if err != nil { 2761 t.Fatal(err) 2762 } 2763 res.Body.Close() 2764 mu.Lock() 2765 if !gotReq { 2766 t.Error("didn't get request") 2767 } 2768 if !didDial { 2769 t.Error("didn't use dial hook") 2770 } 2771 } 2772 2773 // Test for issue 8755 2774 // Ensure that if a proxy returns an error, it is exposed by RoundTrip 2775 func TestRoundTripReturnsProxyError(t *testing.T) { 2776 badProxy := func(*Request) (*url.URL, error) { 2777 return nil, errors.New("errorMessage") 2778 } 2779 2780 tr := &Transport{Proxy: badProxy} 2781 2782 req, _ := NewRequest("GET", "http://example.com", nil) 2783 2784 _, err := tr.RoundTrip(req) 2785 2786 if err == nil { 2787 t.Error("Expected proxy error to be returned by RoundTrip") 2788 } 2789 } 2790 2791 // tests that putting an idle conn after a call to CloseIdleConns does return it 2792 func TestTransportCloseIdleConnsThenReturn(t *testing.T) { 2793 tr := &Transport{} 2794 wantIdle := func(when string, n int) bool { 2795 got := tr.IdleConnCountForTesting("|http|example.com") // key used by PutIdleTestConn 2796 if got == n { 2797 return true 2798 } 2799 t.Errorf("%s: idle conns = %d; want %d", when, got, n) 2800 return false 2801 } 2802 wantIdle("start", 0) 2803 if !tr.PutIdleTestConn() { 2804 t.Fatal("put failed") 2805 } 2806 if !tr.PutIdleTestConn() { 2807 t.Fatal("second put failed") 2808 } 2809 wantIdle("after put", 2) 2810 tr.CloseIdleConnections() 2811 if !tr.IsIdleForTesting() { 2812 t.Error("should be idle after CloseIdleConnections") 2813 } 2814 wantIdle("after close idle", 0) 2815 if tr.PutIdleTestConn() { 2816 t.Fatal("put didn't fail") 2817 } 2818 wantIdle("after second put", 0) 2819 2820 tr.RequestIdleConnChForTesting() // should toggle the transport out of idle mode 2821 if tr.IsIdleForTesting() { 2822 t.Error("shouldn't be idle after RequestIdleConnChForTesting") 2823 } 2824 if !tr.PutIdleTestConn() { 2825 t.Fatal("after re-activation") 2826 } 2827 wantIdle("after final put", 1) 2828 } 2829 2830 // This tests that an client requesting a content range won't also 2831 // implicitly ask for gzip support. If they want that, they need to do it 2832 // on their own. 2833 // golang.org/issue/8923 2834 func TestTransportRangeAndGzip(t *testing.T) { 2835 defer afterTest(t) 2836 reqc := make(chan *Request, 1) 2837 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2838 reqc <- r 2839 })) 2840 defer ts.Close() 2841 c := ts.Client() 2842 2843 req, _ := NewRequest("GET", ts.URL, nil) 2844 req.Header.Set("Range", "bytes=7-11") 2845 res, err := c.Do(req) 2846 if err != nil { 2847 t.Fatal(err) 2848 } 2849 2850 select { 2851 case r := <-reqc: 2852 if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { 2853 t.Error("Transport advertised gzip support in the Accept header") 2854 } 2855 if r.Header.Get("Range") == "" { 2856 t.Error("no Range in request") 2857 } 2858 case <-time.After(10 * time.Second): 2859 t.Fatal("timeout") 2860 } 2861 res.Body.Close() 2862 } 2863 2864 // Test for issue 10474 2865 func TestTransportResponseCancelRace(t *testing.T) { 2866 defer afterTest(t) 2867 2868 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 2869 // important that this response has a body. 2870 var b [1024]byte 2871 w.Write(b[:]) 2872 })) 2873 defer ts.Close() 2874 tr := ts.Client().Transport.(*Transport) 2875 2876 req, err := NewRequest("GET", ts.URL, nil) 2877 if err != nil { 2878 t.Fatal(err) 2879 } 2880 res, err := tr.RoundTrip(req) 2881 if err != nil { 2882 t.Fatal(err) 2883 } 2884 // If we do an early close, Transport just throws the connection away and 2885 // doesn't reuse it. In order to trigger the bug, it has to reuse the connection 2886 // so read the body 2887 if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { 2888 t.Fatal(err) 2889 } 2890 2891 req2, err := NewRequest("GET", ts.URL, nil) 2892 if err != nil { 2893 t.Fatal(err) 2894 } 2895 tr.CancelRequest(req) 2896 res, err = tr.RoundTrip(req2) 2897 if err != nil { 2898 t.Fatal(err) 2899 } 2900 res.Body.Close() 2901 } 2902 2903 func TestTransportDialCancelRace(t *testing.T) { 2904 defer afterTest(t) 2905 2906 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 2907 defer ts.Close() 2908 tr := ts.Client().Transport.(*Transport) 2909 2910 req, err := NewRequest("GET", ts.URL, nil) 2911 if err != nil { 2912 t.Fatal(err) 2913 } 2914 SetEnterRoundTripHook(func() { 2915 tr.CancelRequest(req) 2916 }) 2917 defer SetEnterRoundTripHook(nil) 2918 res, err := tr.RoundTrip(req) 2919 if err != ExportErrRequestCanceled { 2920 t.Errorf("expected canceled request error; got %v", err) 2921 if err == nil { 2922 res.Body.Close() 2923 } 2924 } 2925 } 2926 2927 // logWritesConn is a net.Conn that logs each Write call to writes 2928 // and then proxies to w. 2929 // It proxies Read calls to a reader it receives from rch. 2930 type logWritesConn struct { 2931 net.Conn // nil. crash on use. 2932 2933 w io.Writer 2934 2935 rch <-chan io.Reader 2936 r io.Reader // nil until received by rch 2937 2938 mu sync.Mutex 2939 writes []string 2940 } 2941 2942 func (c *logWritesConn) Write(p []byte) (n int, err error) { 2943 c.mu.Lock() 2944 defer c.mu.Unlock() 2945 c.writes = append(c.writes, string(p)) 2946 return c.w.Write(p) 2947 } 2948 2949 func (c *logWritesConn) Read(p []byte) (n int, err error) { 2950 if c.r == nil { 2951 c.r = <-c.rch 2952 } 2953 return c.r.Read(p) 2954 } 2955 2956 func (c *logWritesConn) Close() error { return nil } 2957 2958 // Issue 6574 2959 func TestTransportFlushesBodyChunks(t *testing.T) { 2960 defer afterTest(t) 2961 resBody := make(chan io.Reader, 1) 2962 connr, connw := io.Pipe() // connection pipe pair 2963 lw := &logWritesConn{ 2964 rch: resBody, 2965 w: connw, 2966 } 2967 tr := &Transport{ 2968 Dial: func(network, addr string) (net.Conn, error) { 2969 return lw, nil 2970 }, 2971 } 2972 bodyr, bodyw := io.Pipe() // body pipe pair 2973 go func() { 2974 defer bodyw.Close() 2975 for i := 0; i < 3; i++ { 2976 fmt.Fprintf(bodyw, "num%d\n", i) 2977 } 2978 }() 2979 resc := make(chan *Response) 2980 go func() { 2981 req, _ := NewRequest("POST", "http://localhost:8080", bodyr) 2982 req.Header.Set("User-Agent", "x") // known value for test 2983 res, err := tr.RoundTrip(req) 2984 if err != nil { 2985 t.Errorf("RoundTrip: %v", err) 2986 close(resc) 2987 return 2988 } 2989 resc <- res 2990 2991 }() 2992 // Fully consume the request before checking the Write log vs. want. 2993 req, err := ReadRequest(bufio.NewReader(connr)) 2994 if err != nil { 2995 t.Fatal(err) 2996 } 2997 io.Copy(ioutil.Discard, req.Body) 2998 2999 // Unblock the transport's roundTrip goroutine. 3000 resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n") 3001 res, ok := <-resc 3002 if !ok { 3003 return 3004 } 3005 defer res.Body.Close() 3006 3007 want := []string{ 3008 "POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n" + 3009 "5\r\nnum0\n\r\n", 3010 "5\r\nnum1\n\r\n", 3011 "5\r\nnum2\n\r\n", 3012 "0\r\n\r\n", 3013 } 3014 if !reflect.DeepEqual(lw.writes, want) { 3015 t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want) 3016 } 3017 } 3018 3019 // Issue 11745. 3020 func TestTransportPrefersResponseOverWriteError(t *testing.T) { 3021 if testing.Short() { 3022 t.Skip("skipping in short mode") 3023 } 3024 defer afterTest(t) 3025 const contentLengthLimit = 1024 * 1024 // 1MB 3026 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3027 if r.ContentLength >= contentLengthLimit { 3028 w.WriteHeader(StatusBadRequest) 3029 r.Body.Close() 3030 return 3031 } 3032 w.WriteHeader(StatusOK) 3033 })) 3034 defer ts.Close() 3035 c := ts.Client() 3036 3037 fail := 0 3038 count := 100 3039 bigBody := strings.Repeat("a", contentLengthLimit*2) 3040 for i := 0; i < count; i++ { 3041 req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody)) 3042 if err != nil { 3043 t.Fatal(err) 3044 } 3045 resp, err := c.Do(req) 3046 if err != nil { 3047 fail++ 3048 t.Logf("%d = %#v", i, err) 3049 if ue, ok := err.(*url.Error); ok { 3050 t.Logf("urlErr = %#v", ue.Err) 3051 if ne, ok := ue.Err.(*net.OpError); ok { 3052 t.Logf("netOpError = %#v", ne.Err) 3053 } 3054 } 3055 } else { 3056 resp.Body.Close() 3057 if resp.StatusCode != 400 { 3058 t.Errorf("Expected status code 400, got %v", resp.Status) 3059 } 3060 } 3061 } 3062 if fail > 0 { 3063 t.Errorf("Failed %v out of %v\n", fail, count) 3064 } 3065 } 3066 3067 func TestTransportAutomaticHTTP2(t *testing.T) { 3068 testTransportAutoHTTP(t, &Transport{}, true) 3069 } 3070 3071 // golang.org/issue/14391: also check DefaultTransport 3072 func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) { 3073 testTransportAutoHTTP(t, DefaultTransport.(*Transport), true) 3074 } 3075 3076 func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) { 3077 testTransportAutoHTTP(t, &Transport{ 3078 TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper), 3079 }, false) 3080 } 3081 3082 func TestTransportAutomaticHTTP2_TLSConfig(t *testing.T) { 3083 testTransportAutoHTTP(t, &Transport{ 3084 TLSClientConfig: new(tls.Config), 3085 }, false) 3086 } 3087 3088 func TestTransportAutomaticHTTP2_ExpectContinueTimeout(t *testing.T) { 3089 testTransportAutoHTTP(t, &Transport{ 3090 ExpectContinueTimeout: 1 * time.Second, 3091 }, true) 3092 } 3093 3094 func TestTransportAutomaticHTTP2_Dial(t *testing.T) { 3095 var d net.Dialer 3096 testTransportAutoHTTP(t, &Transport{ 3097 Dial: d.Dial, 3098 }, false) 3099 } 3100 3101 func TestTransportAutomaticHTTP2_DialTLS(t *testing.T) { 3102 testTransportAutoHTTP(t, &Transport{ 3103 DialTLS: func(network, addr string) (net.Conn, error) { 3104 panic("unused") 3105 }, 3106 }, false) 3107 } 3108 3109 func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) { 3110 _, err := tr.RoundTrip(new(Request)) 3111 if err == nil { 3112 t.Error("expected error from RoundTrip") 3113 } 3114 if reg := tr.TLSNextProto["h2"] != nil; reg != wantH2 { 3115 t.Errorf("HTTP/2 registered = %v; want %v", reg, wantH2) 3116 } 3117 } 3118 3119 // Issue 13633: there was a race where we returned bodyless responses 3120 // to callers before recycling the persistent connection, which meant 3121 // a client doing two subsequent requests could end up on different 3122 // connections. It's somewhat harmless but enough tests assume it's 3123 // not true in order to test other things that it's worth fixing. 3124 // Plus it's nice to be consistent and not have timing-dependent 3125 // behavior. 3126 func TestTransportReuseConnEmptyResponseBody(t *testing.T) { 3127 defer afterTest(t) 3128 cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) { 3129 w.Header().Set("X-Addr", r.RemoteAddr) 3130 // Empty response body. 3131 })) 3132 defer cst.close() 3133 n := 100 3134 if testing.Short() { 3135 n = 10 3136 } 3137 var firstAddr string 3138 for i := 0; i < n; i++ { 3139 res, err := cst.c.Get(cst.ts.URL) 3140 if err != nil { 3141 log.Fatal(err) 3142 } 3143 addr := res.Header.Get("X-Addr") 3144 if i == 0 { 3145 firstAddr = addr 3146 } else if addr != firstAddr { 3147 t.Fatalf("On request %d, addr %q != original addr %q", i+1, addr, firstAddr) 3148 } 3149 res.Body.Close() 3150 } 3151 } 3152 3153 // Issue 13839 3154 func TestNoCrashReturningTransportAltConn(t *testing.T) { 3155 cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey) 3156 if err != nil { 3157 t.Fatal(err) 3158 } 3159 ln := newLocalListener(t) 3160 defer ln.Close() 3161 3162 handledPendingDial := make(chan bool, 1) 3163 SetPendingDialHooks(nil, func() { handledPendingDial <- true }) 3164 defer SetPendingDialHooks(nil, nil) 3165 3166 testDone := make(chan struct{}) 3167 defer close(testDone) 3168 go func() { 3169 tln := tls.NewListener(ln, &tls.Config{ 3170 NextProtos: []string{"foo"}, 3171 Certificates: []tls.Certificate{cert}, 3172 }) 3173 sc, err := tln.Accept() 3174 if err != nil { 3175 t.Error(err) 3176 return 3177 } 3178 if err := sc.(*tls.Conn).Handshake(); err != nil { 3179 t.Error(err) 3180 return 3181 } 3182 <-testDone 3183 sc.Close() 3184 }() 3185 3186 addr := ln.Addr().String() 3187 3188 req, _ := NewRequest("GET", "https://fake.tld/", nil) 3189 cancel := make(chan struct{}) 3190 req.Cancel = cancel 3191 3192 doReturned := make(chan bool, 1) 3193 madeRoundTripper := make(chan bool, 1) 3194 3195 tr := &Transport{ 3196 DisableKeepAlives: true, 3197 TLSNextProto: map[string]func(string, *tls.Conn) RoundTripper{ 3198 "foo": func(authority string, c *tls.Conn) RoundTripper { 3199 madeRoundTripper <- true 3200 return funcRoundTripper(func() { 3201 t.Error("foo RoundTripper should not be called") 3202 }) 3203 }, 3204 }, 3205 Dial: func(_, _ string) (net.Conn, error) { 3206 panic("shouldn't be called") 3207 }, 3208 DialTLS: func(_, _ string) (net.Conn, error) { 3209 tc, err := tls.Dial("tcp", addr, &tls.Config{ 3210 InsecureSkipVerify: true, 3211 NextProtos: []string{"foo"}, 3212 }) 3213 if err != nil { 3214 return nil, err 3215 } 3216 if err := tc.Handshake(); err != nil { 3217 return nil, err 3218 } 3219 close(cancel) 3220 <-doReturned 3221 return tc, nil 3222 }, 3223 } 3224 c := &Client{Transport: tr} 3225 3226 _, err = c.Do(req) 3227 if ue, ok := err.(*url.Error); !ok || ue.Err != ExportErrRequestCanceledConn { 3228 t.Fatalf("Do error = %v; want url.Error with errRequestCanceledConn", err) 3229 } 3230 3231 doReturned <- true 3232 <-madeRoundTripper 3233 <-handledPendingDial 3234 } 3235 3236 func TestTransportReuseConnection_Gzip_Chunked(t *testing.T) { 3237 testTransportReuseConnection_Gzip(t, true) 3238 } 3239 3240 func TestTransportReuseConnection_Gzip_ContentLength(t *testing.T) { 3241 testTransportReuseConnection_Gzip(t, false) 3242 } 3243 3244 // Make sure we re-use underlying TCP connection for gzipped responses too. 3245 func testTransportReuseConnection_Gzip(t *testing.T, chunked bool) { 3246 setParallel(t) 3247 defer afterTest(t) 3248 addr := make(chan string, 2) 3249 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3250 addr <- r.RemoteAddr 3251 w.Header().Set("Content-Encoding", "gzip") 3252 if chunked { 3253 w.(Flusher).Flush() 3254 } 3255 w.Write(rgz) // arbitrary gzip response 3256 })) 3257 defer ts.Close() 3258 c := ts.Client() 3259 3260 for i := 0; i < 2; i++ { 3261 res, err := c.Get(ts.URL) 3262 if err != nil { 3263 t.Fatal(err) 3264 } 3265 buf := make([]byte, len(rgz)) 3266 if n, err := io.ReadFull(res.Body, buf); err != nil { 3267 t.Errorf("%d. ReadFull = %v, %v", i, n, err) 3268 } 3269 // Note: no res.Body.Close call. It should work without it, 3270 // since the flate.Reader's internal buffering will hit EOF 3271 // and that should be sufficient. 3272 } 3273 a1, a2 := <-addr, <-addr 3274 if a1 != a2 { 3275 t.Fatalf("didn't reuse connection") 3276 } 3277 } 3278 3279 func TestTransportResponseHeaderLength(t *testing.T) { 3280 setParallel(t) 3281 defer afterTest(t) 3282 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3283 if r.URL.Path == "/long" { 3284 w.Header().Set("Long", strings.Repeat("a", 1<<20)) 3285 } 3286 })) 3287 defer ts.Close() 3288 c := ts.Client() 3289 c.Transport.(*Transport).MaxResponseHeaderBytes = 512 << 10 3290 3291 if res, err := c.Get(ts.URL); err != nil { 3292 t.Fatal(err) 3293 } else { 3294 res.Body.Close() 3295 } 3296 3297 res, err := c.Get(ts.URL + "/long") 3298 if err == nil { 3299 defer res.Body.Close() 3300 var n int64 3301 for k, vv := range res.Header { 3302 for _, v := range vv { 3303 n += int64(len(k)) + int64(len(v)) 3304 } 3305 } 3306 t.Fatalf("Unexpected success. Got %v and %d bytes of response headers", res.Status, n) 3307 } 3308 if want := "server response headers exceeded 524288 bytes"; !strings.Contains(err.Error(), want) { 3309 t.Errorf("got error: %v; want %q", err, want) 3310 } 3311 } 3312 3313 func TestTransportEventTrace(t *testing.T) { testTransportEventTrace(t, h1Mode, false) } 3314 func TestTransportEventTrace_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, false) } 3315 3316 // test a non-nil httptrace.ClientTrace but with all hooks set to zero. 3317 func TestTransportEventTrace_NoHooks(t *testing.T) { testTransportEventTrace(t, h1Mode, true) } 3318 func TestTransportEventTrace_NoHooks_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, true) } 3319 3320 func testTransportEventTrace(t *testing.T, h2 bool, noHooks bool) { 3321 defer afterTest(t) 3322 const resBody = "some body" 3323 gotWroteReqEvent := make(chan struct{}) 3324 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 3325 if _, err := ioutil.ReadAll(r.Body); err != nil { 3326 t.Error(err) 3327 } 3328 if !noHooks { 3329 select { 3330 case <-gotWroteReqEvent: 3331 case <-time.After(5 * time.Second): 3332 t.Error("timeout waiting for WroteRequest event") 3333 } 3334 } 3335 io.WriteString(w, resBody) 3336 })) 3337 defer cst.close() 3338 3339 cst.tr.ExpectContinueTimeout = 1 * time.Second 3340 3341 var mu sync.Mutex // guards buf 3342 var buf bytes.Buffer 3343 logf := func(format string, args ...interface{}) { 3344 mu.Lock() 3345 defer mu.Unlock() 3346 fmt.Fprintf(&buf, format, args...) 3347 buf.WriteByte('\n') 3348 } 3349 3350 addrStr := cst.ts.Listener.Addr().String() 3351 ip, port, err := net.SplitHostPort(addrStr) 3352 if err != nil { 3353 t.Fatal(err) 3354 } 3355 3356 // Install a fake DNS server. 3357 ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) { 3358 if host != "dns-is-faked.golang" { 3359 t.Errorf("unexpected DNS host lookup for %q", host) 3360 return nil, nil 3361 } 3362 return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil 3363 }) 3364 3365 req, _ := NewRequest("POST", cst.scheme()+"://dns-is-faked.golang:"+port, strings.NewReader("some body")) 3366 trace := &httptrace.ClientTrace{ 3367 GetConn: func(hostPort string) { logf("Getting conn for %v ...", hostPort) }, 3368 GotConn: func(ci httptrace.GotConnInfo) { logf("got conn: %+v", ci) }, 3369 GotFirstResponseByte: func() { logf("first response byte") }, 3370 PutIdleConn: func(err error) { logf("PutIdleConn = %v", err) }, 3371 DNSStart: func(e httptrace.DNSStartInfo) { logf("DNS start: %+v", e) }, 3372 DNSDone: func(e httptrace.DNSDoneInfo) { logf("DNS done: %+v", e) }, 3373 ConnectStart: func(network, addr string) { logf("ConnectStart: Connecting to %s %s ...", network, addr) }, 3374 ConnectDone: func(network, addr string, err error) { 3375 if err != nil { 3376 t.Errorf("ConnectDone: %v", err) 3377 } 3378 logf("ConnectDone: connected to %s %s = %v", network, addr, err) 3379 }, 3380 Wait100Continue: func() { logf("Wait100Continue") }, 3381 Got100Continue: func() { logf("Got100Continue") }, 3382 WroteRequest: func(e httptrace.WroteRequestInfo) { 3383 logf("WroteRequest: %+v", e) 3384 close(gotWroteReqEvent) 3385 }, 3386 } 3387 if h2 { 3388 trace.TLSHandshakeStart = func() { logf("tls handshake start") } 3389 trace.TLSHandshakeDone = func(s tls.ConnectionState, err error) { 3390 logf("tls handshake done. ConnectionState = %v \n err = %v", s, err) 3391 } 3392 } 3393 if noHooks { 3394 // zero out all func pointers, trying to get some path to crash 3395 *trace = httptrace.ClientTrace{} 3396 } 3397 req = req.WithContext(httptrace.WithClientTrace(ctx, trace)) 3398 3399 req.Header.Set("Expect", "100-continue") 3400 res, err := cst.c.Do(req) 3401 if err != nil { 3402 t.Fatal(err) 3403 } 3404 logf("got roundtrip.response") 3405 slurp, err := ioutil.ReadAll(res.Body) 3406 if err != nil { 3407 t.Fatal(err) 3408 } 3409 logf("consumed body") 3410 if string(slurp) != resBody || res.StatusCode != 200 { 3411 t.Fatalf("Got %q, %v; want %q, 200 OK", slurp, res.Status, resBody) 3412 } 3413 res.Body.Close() 3414 3415 if noHooks { 3416 // Done at this point. Just testing a full HTTP 3417 // requests can happen with a trace pointing to a zero 3418 // ClientTrace, full of nil func pointers. 3419 return 3420 } 3421 3422 mu.Lock() 3423 got := buf.String() 3424 mu.Unlock() 3425 3426 wantOnce := func(sub string) { 3427 if strings.Count(got, sub) != 1 { 3428 t.Errorf("expected substring %q exactly once in output.", sub) 3429 } 3430 } 3431 wantOnceOrMore := func(sub string) { 3432 if strings.Count(got, sub) == 0 { 3433 t.Errorf("expected substring %q at least once in output.", sub) 3434 } 3435 } 3436 wantOnce("Getting conn for dns-is-faked.golang:" + port) 3437 wantOnce("DNS start: {Host:dns-is-faked.golang}") 3438 wantOnce("DNS done: {Addrs:[{IP:" + ip + " Zone:}] Err:<nil> Coalesced:false}") 3439 wantOnce("got conn: {") 3440 wantOnceOrMore("Connecting to tcp " + addrStr) 3441 wantOnceOrMore("connected to tcp " + addrStr + " = <nil>") 3442 wantOnce("Reused:false WasIdle:false IdleTime:0s") 3443 wantOnce("first response byte") 3444 if h2 { 3445 wantOnce("tls handshake start") 3446 wantOnce("tls handshake done") 3447 } else { 3448 wantOnce("PutIdleConn = <nil>") 3449 } 3450 wantOnce("Wait100Continue") 3451 wantOnce("Got100Continue") 3452 wantOnce("WroteRequest: {Err:<nil>}") 3453 if strings.Contains(got, " to udp ") { 3454 t.Errorf("should not see UDP (DNS) connections") 3455 } 3456 if t.Failed() { 3457 t.Errorf("Output:\n%s", got) 3458 } 3459 } 3460 3461 var ( 3462 isDNSHijackedOnce sync.Once 3463 isDNSHijacked bool 3464 ) 3465 3466 func skipIfDNSHijacked(t *testing.T) { 3467 // Skip this test if the user is using a shady/ISP 3468 // DNS server hijacking queries. 3469 // See issues 16732, 16716. 3470 isDNSHijackedOnce.Do(func() { 3471 addrs, _ := net.LookupHost("dns-should-not-resolve.golang") 3472 isDNSHijacked = len(addrs) != 0 3473 }) 3474 if isDNSHijacked { 3475 t.Skip("skipping; test requires non-hijacking DNS server") 3476 } 3477 } 3478 3479 func TestTransportEventTraceRealDNS(t *testing.T) { 3480 skipIfDNSHijacked(t) 3481 defer afterTest(t) 3482 tr := &Transport{} 3483 defer tr.CloseIdleConnections() 3484 c := &Client{Transport: tr} 3485 3486 var mu sync.Mutex // guards buf 3487 var buf bytes.Buffer 3488 logf := func(format string, args ...interface{}) { 3489 mu.Lock() 3490 defer mu.Unlock() 3491 fmt.Fprintf(&buf, format, args...) 3492 buf.WriteByte('\n') 3493 } 3494 3495 req, _ := NewRequest("GET", "http://dns-should-not-resolve.golang:80", nil) 3496 trace := &httptrace.ClientTrace{ 3497 DNSStart: func(e httptrace.DNSStartInfo) { logf("DNSStart: %+v", e) }, 3498 DNSDone: func(e httptrace.DNSDoneInfo) { logf("DNSDone: %+v", e) }, 3499 ConnectStart: func(network, addr string) { logf("ConnectStart: %s %s", network, addr) }, 3500 ConnectDone: func(network, addr string, err error) { logf("ConnectDone: %s %s %v", network, addr, err) }, 3501 } 3502 req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace)) 3503 3504 resp, err := c.Do(req) 3505 if err == nil { 3506 resp.Body.Close() 3507 t.Fatal("expected error during DNS lookup") 3508 } 3509 3510 mu.Lock() 3511 got := buf.String() 3512 mu.Unlock() 3513 3514 wantSub := func(sub string) { 3515 if !strings.Contains(got, sub) { 3516 t.Errorf("expected substring %q in output.", sub) 3517 } 3518 } 3519 wantSub("DNSStart: {Host:dns-should-not-resolve.golang}") 3520 wantSub("DNSDone: {Addrs:[] Err:") 3521 if strings.Contains(got, "ConnectStart") || strings.Contains(got, "ConnectDone") { 3522 t.Errorf("should not see Connect events") 3523 } 3524 if t.Failed() { 3525 t.Errorf("Output:\n%s", got) 3526 } 3527 } 3528 3529 // Issue 14353: port can only contain digits. 3530 func TestTransportRejectsAlphaPort(t *testing.T) { 3531 res, err := Get("http://dummy.tld:123foo/bar") 3532 if err == nil { 3533 res.Body.Close() 3534 t.Fatal("unexpected success") 3535 } 3536 ue, ok := err.(*url.Error) 3537 if !ok { 3538 t.Fatalf("got %#v; want *url.Error", err) 3539 } 3540 got := ue.Err.Error() 3541 want := `invalid URL port "123foo"` 3542 if got != want { 3543 t.Errorf("got error %q; want %q", got, want) 3544 } 3545 } 3546 3547 // Test the httptrace.TLSHandshake{Start,Done} hooks with a https http1 3548 // connections. The http2 test is done in TestTransportEventTrace_h2 3549 func TestTLSHandshakeTrace(t *testing.T) { 3550 defer afterTest(t) 3551 ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) 3552 defer ts.Close() 3553 3554 var mu sync.Mutex 3555 var start, done bool 3556 trace := &httptrace.ClientTrace{ 3557 TLSHandshakeStart: func() { 3558 mu.Lock() 3559 defer mu.Unlock() 3560 start = true 3561 }, 3562 TLSHandshakeDone: func(s tls.ConnectionState, err error) { 3563 mu.Lock() 3564 defer mu.Unlock() 3565 done = true 3566 if err != nil { 3567 t.Fatal("Expected error to be nil but was:", err) 3568 } 3569 }, 3570 } 3571 3572 c := ts.Client() 3573 req, err := NewRequest("GET", ts.URL, nil) 3574 if err != nil { 3575 t.Fatal("Unable to construct test request:", err) 3576 } 3577 req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) 3578 3579 r, err := c.Do(req) 3580 if err != nil { 3581 t.Fatal("Unexpected error making request:", err) 3582 } 3583 r.Body.Close() 3584 mu.Lock() 3585 defer mu.Unlock() 3586 if !start { 3587 t.Fatal("Expected TLSHandshakeStart to be called, but wasn't") 3588 } 3589 if !done { 3590 t.Fatal("Expected TLSHandshakeDone to be called, but wasnt't") 3591 } 3592 } 3593 3594 func TestTransportMaxIdleConns(t *testing.T) { 3595 defer afterTest(t) 3596 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3597 // No body for convenience. 3598 })) 3599 defer ts.Close() 3600 c := ts.Client() 3601 tr := c.Transport.(*Transport) 3602 tr.MaxIdleConns = 4 3603 3604 ip, port, err := net.SplitHostPort(ts.Listener.Addr().String()) 3605 if err != nil { 3606 t.Fatal(err) 3607 } 3608 ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) { 3609 return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil 3610 }) 3611 3612 hitHost := func(n int) { 3613 req, _ := NewRequest("GET", fmt.Sprintf("http://host-%d.dns-is-faked.golang:"+port, n), nil) 3614 req = req.WithContext(ctx) 3615 res, err := c.Do(req) 3616 if err != nil { 3617 t.Fatal(err) 3618 } 3619 res.Body.Close() 3620 } 3621 for i := 0; i < 4; i++ { 3622 hitHost(i) 3623 } 3624 want := []string{ 3625 "|http|host-0.dns-is-faked.golang:" + port, 3626 "|http|host-1.dns-is-faked.golang:" + port, 3627 "|http|host-2.dns-is-faked.golang:" + port, 3628 "|http|host-3.dns-is-faked.golang:" + port, 3629 } 3630 if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) { 3631 t.Fatalf("idle conn keys mismatch.\n got: %q\nwant: %q\n", got, want) 3632 } 3633 3634 // Now hitting the 5th host should kick out the first host: 3635 hitHost(4) 3636 want = []string{ 3637 "|http|host-1.dns-is-faked.golang:" + port, 3638 "|http|host-2.dns-is-faked.golang:" + port, 3639 "|http|host-3.dns-is-faked.golang:" + port, 3640 "|http|host-4.dns-is-faked.golang:" + port, 3641 } 3642 if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) { 3643 t.Fatalf("idle conn keys mismatch after 5th host.\n got: %q\nwant: %q\n", got, want) 3644 } 3645 } 3646 3647 func TestTransportIdleConnTimeout_h1(t *testing.T) { testTransportIdleConnTimeout(t, h1Mode) } 3648 func TestTransportIdleConnTimeout_h2(t *testing.T) { testTransportIdleConnTimeout(t, h2Mode) } 3649 func testTransportIdleConnTimeout(t *testing.T, h2 bool) { 3650 if testing.Short() { 3651 t.Skip("skipping in short mode") 3652 } 3653 defer afterTest(t) 3654 3655 const timeout = 1 * time.Second 3656 3657 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 3658 // No body for convenience. 3659 })) 3660 defer cst.close() 3661 tr := cst.tr 3662 tr.IdleConnTimeout = timeout 3663 defer tr.CloseIdleConnections() 3664 c := &Client{Transport: tr} 3665 3666 idleConns := func() []string { 3667 if h2 { 3668 return tr.IdleConnStrsForTesting_h2() 3669 } else { 3670 return tr.IdleConnStrsForTesting() 3671 } 3672 } 3673 3674 var conn string 3675 doReq := func(n int) { 3676 req, _ := NewRequest("GET", cst.ts.URL, nil) 3677 req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{ 3678 PutIdleConn: func(err error) { 3679 if err != nil { 3680 t.Errorf("failed to keep idle conn: %v", err) 3681 } 3682 }, 3683 })) 3684 res, err := c.Do(req) 3685 if err != nil { 3686 t.Fatal(err) 3687 } 3688 res.Body.Close() 3689 conns := idleConns() 3690 if len(conns) != 1 { 3691 t.Fatalf("req %v: unexpected number of idle conns: %q", n, conns) 3692 } 3693 if conn == "" { 3694 conn = conns[0] 3695 } 3696 if conn != conns[0] { 3697 t.Fatalf("req %v: cached connection changed; expected the same one throughout the test", n) 3698 } 3699 } 3700 for i := 0; i < 3; i++ { 3701 doReq(i) 3702 time.Sleep(timeout / 2) 3703 } 3704 time.Sleep(timeout * 3 / 2) 3705 if got := idleConns(); len(got) != 0 { 3706 t.Errorf("idle conns = %q; want none", got) 3707 } 3708 } 3709 3710 // Issue 16208: Go 1.7 crashed after Transport.IdleConnTimeout if an 3711 // HTTP/2 connection was established but but its caller no longer 3712 // wanted it. (Assuming the connection cache was enabled, which it is 3713 // by default) 3714 // 3715 // This test reproduced the crash by setting the IdleConnTimeout low 3716 // (to make the test reasonable) and then making a request which is 3717 // canceled by the DialTLS hook, which then also waits to return the 3718 // real connection until after the RoundTrip saw the error. Then we 3719 // know the successful tls.Dial from DialTLS will need to go into the 3720 // idle pool. Then we give it a of time to explode. 3721 func TestIdleConnH2Crash(t *testing.T) { 3722 setParallel(t) 3723 cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) { 3724 // nothing 3725 })) 3726 defer cst.close() 3727 3728 ctx, cancel := context.WithCancel(context.Background()) 3729 defer cancel() 3730 3731 sawDoErr := make(chan bool, 1) 3732 testDone := make(chan struct{}) 3733 defer close(testDone) 3734 3735 cst.tr.IdleConnTimeout = 5 * time.Millisecond 3736 cst.tr.DialTLS = func(network, addr string) (net.Conn, error) { 3737 c, err := tls.Dial(network, addr, &tls.Config{ 3738 InsecureSkipVerify: true, 3739 NextProtos: []string{"h2"}, 3740 }) 3741 if err != nil { 3742 t.Error(err) 3743 return nil, err 3744 } 3745 if cs := c.ConnectionState(); cs.NegotiatedProtocol != "h2" { 3746 t.Errorf("protocol = %q; want %q", cs.NegotiatedProtocol, "h2") 3747 c.Close() 3748 return nil, errors.New("bogus") 3749 } 3750 3751 cancel() 3752 3753 failTimer := time.NewTimer(5 * time.Second) 3754 defer failTimer.Stop() 3755 select { 3756 case <-sawDoErr: 3757 case <-testDone: 3758 case <-failTimer.C: 3759 t.Error("timeout in DialTLS, waiting too long for cst.c.Do to fail") 3760 } 3761 return c, nil 3762 } 3763 3764 req, _ := NewRequest("GET", cst.ts.URL, nil) 3765 req = req.WithContext(ctx) 3766 res, err := cst.c.Do(req) 3767 if err == nil { 3768 res.Body.Close() 3769 t.Fatal("unexpected success") 3770 } 3771 sawDoErr <- true 3772 3773 // Wait for the explosion. 3774 time.Sleep(cst.tr.IdleConnTimeout * 10) 3775 } 3776 3777 type funcConn struct { 3778 net.Conn 3779 read func([]byte) (int, error) 3780 write func([]byte) (int, error) 3781 } 3782 3783 func (c funcConn) Read(p []byte) (int, error) { return c.read(p) } 3784 func (c funcConn) Write(p []byte) (int, error) { return c.write(p) } 3785 func (c funcConn) Close() error { return nil } 3786 3787 // Issue 16465: Transport.RoundTrip should return the raw net.Conn.Read error from Peek 3788 // back to the caller. 3789 func TestTransportReturnsPeekError(t *testing.T) { 3790 errValue := errors.New("specific error value") 3791 3792 wrote := make(chan struct{}) 3793 var wroteOnce sync.Once 3794 3795 tr := &Transport{ 3796 Dial: func(network, addr string) (net.Conn, error) { 3797 c := funcConn{ 3798 read: func([]byte) (int, error) { 3799 <-wrote 3800 return 0, errValue 3801 }, 3802 write: func(p []byte) (int, error) { 3803 wroteOnce.Do(func() { close(wrote) }) 3804 return len(p), nil 3805 }, 3806 } 3807 return c, nil 3808 }, 3809 } 3810 _, err := tr.RoundTrip(httptest.NewRequest("GET", "http://fake.tld/", nil)) 3811 if err != errValue { 3812 t.Errorf("error = %#v; want %v", err, errValue) 3813 } 3814 } 3815 3816 // Issue 13835: international domain names should work 3817 func TestTransportIDNA_h1(t *testing.T) { testTransportIDNA(t, h1Mode) } 3818 func TestTransportIDNA_h2(t *testing.T) { testTransportIDNA(t, h2Mode) } 3819 func testTransportIDNA(t *testing.T, h2 bool) { 3820 defer afterTest(t) 3821 3822 const uniDomain = "гофер.го" 3823 const punyDomain = "xn--c1ae0ajs.xn--c1aw" 3824 3825 var port string 3826 cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { 3827 want := punyDomain + ":" + port 3828 if r.Host != want { 3829 t.Errorf("Host header = %q; want %q", r.Host, want) 3830 } 3831 if h2 { 3832 if r.TLS == nil { 3833 t.Errorf("r.TLS == nil") 3834 } else if r.TLS.ServerName != punyDomain { 3835 t.Errorf("TLS.ServerName = %q; want %q", r.TLS.ServerName, punyDomain) 3836 } 3837 } 3838 w.Header().Set("Hit-Handler", "1") 3839 })) 3840 defer cst.close() 3841 3842 ip, port, err := net.SplitHostPort(cst.ts.Listener.Addr().String()) 3843 if err != nil { 3844 t.Fatal(err) 3845 } 3846 3847 // Install a fake DNS server. 3848 ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) { 3849 if host != punyDomain { 3850 t.Errorf("got DNS host lookup for %q; want %q", host, punyDomain) 3851 return nil, nil 3852 } 3853 return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil 3854 }) 3855 3856 req, _ := NewRequest("GET", cst.scheme()+"://"+uniDomain+":"+port, nil) 3857 trace := &httptrace.ClientTrace{ 3858 GetConn: func(hostPort string) { 3859 want := net.JoinHostPort(punyDomain, port) 3860 if hostPort != want { 3861 t.Errorf("getting conn for %q; want %q", hostPort, want) 3862 } 3863 }, 3864 DNSStart: func(e httptrace.DNSStartInfo) { 3865 if e.Host != punyDomain { 3866 t.Errorf("DNSStart Host = %q; want %q", e.Host, punyDomain) 3867 } 3868 }, 3869 } 3870 req = req.WithContext(httptrace.WithClientTrace(ctx, trace)) 3871 3872 res, err := cst.tr.RoundTrip(req) 3873 if err != nil { 3874 t.Fatal(err) 3875 } 3876 defer res.Body.Close() 3877 if res.Header.Get("Hit-Handler") != "1" { 3878 out, err := httputil.DumpResponse(res, true) 3879 if err != nil { 3880 t.Fatal(err) 3881 } 3882 t.Errorf("Response body wasn't from Handler. Got:\n%s\n", out) 3883 } 3884 } 3885 3886 // Issue 13290: send User-Agent in proxy CONNECT 3887 func TestTransportProxyConnectHeader(t *testing.T) { 3888 defer afterTest(t) 3889 reqc := make(chan *Request, 1) 3890 ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { 3891 if r.Method != "CONNECT" { 3892 t.Errorf("method = %q; want CONNECT", r.Method) 3893 } 3894 reqc <- r 3895 c, _, err := w.(Hijacker).Hijack() 3896 if err != nil { 3897 t.Errorf("Hijack: %v", err) 3898 return 3899 } 3900 c.Close() 3901 })) 3902 defer ts.Close() 3903 3904 c := ts.Client() 3905 c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) { 3906 return url.Parse(ts.URL) 3907 } 3908 c.Transport.(*Transport).ProxyConnectHeader = Header{ 3909 "User-Agent": {"foo"}, 3910 "Other": {"bar"}, 3911 } 3912 3913 res, err := c.Get("https://dummy.tld/") // https to force a CONNECT 3914 if err == nil { 3915 res.Body.Close() 3916 t.Errorf("unexpected success") 3917 } 3918 select { 3919 case <-time.After(3 * time.Second): 3920 t.Fatal("timeout") 3921 case r := <-reqc: 3922 if got, want := r.Header.Get("User-Agent"), "foo"; got != want { 3923 t.Errorf("CONNECT request User-Agent = %q; want %q", got, want) 3924 } 3925 if got, want := r.Header.Get("Other"), "bar"; got != want { 3926 t.Errorf("CONNECT request Other = %q; want %q", got, want) 3927 } 3928 } 3929 } 3930 3931 var errFakeRoundTrip = errors.New("fake roundtrip") 3932 3933 type funcRoundTripper func() 3934 3935 func (fn funcRoundTripper) RoundTrip(*Request) (*Response, error) { 3936 fn() 3937 return nil, errFakeRoundTrip 3938 } 3939 3940 func wantBody(res *Response, err error, want string) error { 3941 if err != nil { 3942 return err 3943 } 3944 slurp, err := ioutil.ReadAll(res.Body) 3945 if err != nil { 3946 return fmt.Errorf("error reading body: %v", err) 3947 } 3948 if string(slurp) != want { 3949 return fmt.Errorf("body = %q; want %q", slurp, want) 3950 } 3951 if err := res.Body.Close(); err != nil { 3952 return fmt.Errorf("body Close = %v", err) 3953 } 3954 return nil 3955 } 3956 3957 func newLocalListener(t *testing.T) net.Listener { 3958 ln, err := net.Listen("tcp", "127.0.0.1:0") 3959 if err != nil { 3960 ln, err = net.Listen("tcp6", "[::1]:0") 3961 } 3962 if err != nil { 3963 t.Fatal(err) 3964 } 3965 return ln 3966 } 3967 3968 type countCloseReader struct { 3969 n *int 3970 io.Reader 3971 } 3972 3973 func (cr countCloseReader) Close() error { 3974 (*cr.n)++ 3975 return nil 3976 } 3977 3978 // rgz is a gzip quine that uncompresses to itself. 3979 var rgz = []byte{ 3980 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 3981 0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 3982 0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0, 3983 0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 3984 0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 3985 0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60, 3986 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2, 3987 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00, 3988 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 3989 0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16, 3990 0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05, 3991 0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff, 3992 0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00, 3993 0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 3994 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 3995 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 3996 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 3997 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 3998 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 3999 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 4000 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 4001 0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff, 4002 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00, 4003 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 4004 0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 4005 0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 4006 0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 4007 0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06, 4008 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00, 4009 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00, 4010 0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00, 4011 0x00, 0x00, 4012 }