github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/net/http/transport_test.go (about)

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