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