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