github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/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_RPXY
  2064  
  2065  	want    string
  2066  	wanterr error
  2067  }
  2068  
  2069  func (t proxyFromEnvTest) String() string {
  2070  	var buf bytes.Buffer
  2071  	space := func() {
  2072  		if buf.Len() > 0 {
  2073  			buf.WriteByte(' ')
  2074  		}
  2075  	}
  2076  	if t.env != "" {
  2077  		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
  2078  	}
  2079  	if t.httpsenv != "" {
  2080  		space()
  2081  		fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv)
  2082  	}
  2083  	if t.noenv != "" {
  2084  		space()
  2085  		fmt.Fprintf(&buf, "no_proxy=%q", t.noenv)
  2086  	}
  2087  	req := "http://example.com"
  2088  	if t.req != "" {
  2089  		req = t.req
  2090  	}
  2091  	space()
  2092  	fmt.Fprintf(&buf, "req=%q", req)
  2093  	return strings.TrimSpace(buf.String())
  2094  }
  2095  
  2096  var proxyFromEnvTests = []proxyFromEnvTest{
  2097  	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2098  	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
  2099  	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
  2100  	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
  2101  	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2102  	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
  2103  
  2104  	// Don't use secure for http
  2105  	{req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"},
  2106  	// Use secure for https.
  2107  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"},
  2108  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"},
  2109  
  2110  	{want: "<nil>"},
  2111  
  2112  	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  2113  	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  2114  	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2115  	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
  2116  	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2117  }
  2118  
  2119  func TestProxyFromEnvironment(t *testing.T) {
  2120  	ResetProxyEnv()
  2121  	for _, tt := range proxyFromEnvTests {
  2122  		os.Setenv("HTTP_PROXY", tt.env)
  2123  		os.Setenv("HTTPS_PROXY", tt.httpsenv)
  2124  		os.Setenv("NO_PROXY", tt.noenv)
  2125  		ResetCachedEnvironment()
  2126  		reqURL := tt.req
  2127  		if reqURL == "" {
  2128  			reqURL = "http://example.com"
  2129  		}
  2130  		req, _ := NewRequest("GET", reqURL, nil)
  2131  		url, err := ProxyFromEnvironment(req)
  2132  		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
  2133  			t.Errorf("%v: got error = %q, want %q", tt, g, e)
  2134  			continue
  2135  		}
  2136  		if got := fmt.Sprintf("%s", url); got != tt.want {
  2137  			t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
  2138  		}
  2139  	}
  2140  }
  2141  
  2142  func TestIdleConnChannelLeak(t *testing.T) {
  2143  	var mu sync.Mutex
  2144  	var n int
  2145  
  2146  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2147  		mu.Lock()
  2148  		n++
  2149  		mu.Unlock()
  2150  	}))
  2151  	defer ts.Close()
  2152  
  2153  	const nReqs = 5
  2154  	didRead := make(chan bool, nReqs)
  2155  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
  2156  	defer SetReadLoopBeforeNextReadHook(nil)
  2157  
  2158  	tr := &Transport{
  2159  		Dial: func(netw, addr string) (net.Conn, error) {
  2160  			return net.Dial(netw, ts.Listener.Addr().String())
  2161  		},
  2162  	}
  2163  	defer tr.CloseIdleConnections()
  2164  
  2165  	c := &Client{Transport: tr}
  2166  
  2167  	// First, without keep-alives.
  2168  	for _, disableKeep := range []bool{true, false} {
  2169  		tr.DisableKeepAlives = disableKeep
  2170  		for i := 0; i < nReqs; i++ {
  2171  			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
  2172  			if err != nil {
  2173  				t.Fatal(err)
  2174  			}
  2175  			// Note: no res.Body.Close is needed here, since the
  2176  			// response Content-Length is zero. Perhaps the test
  2177  			// should be more explicit and use a HEAD, but tests
  2178  			// elsewhere guarantee that zero byte responses generate
  2179  			// a "Content-Length: 0" instead of chunking.
  2180  		}
  2181  
  2182  		// At this point, each of the 5 Transport.readLoop goroutines
  2183  		// are scheduling noting that there are no response bodies (see
  2184  		// earlier comment), and are then calling putIdleConn, which
  2185  		// decrements this count. Usually that happens quickly, which is
  2186  		// why this test has seemed to work for ages. But it's still
  2187  		// racey: we have wait for them to finish first. See Issue 10427
  2188  		for i := 0; i < nReqs; i++ {
  2189  			<-didRead
  2190  		}
  2191  
  2192  		if got := tr.IdleConnChMapSizeForTesting(); got != 0 {
  2193  			t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
  2194  		}
  2195  	}
  2196  }
  2197  
  2198  // Verify the status quo: that the Client.Post function coerces its
  2199  // body into a ReadCloser if it's a Closer, and that the Transport
  2200  // then closes it.
  2201  func TestTransportClosesRequestBody(t *testing.T) {
  2202  	defer afterTest(t)
  2203  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2204  		io.Copy(ioutil.Discard, r.Body)
  2205  	}))
  2206  	defer ts.Close()
  2207  
  2208  	tr := &Transport{}
  2209  	defer tr.CloseIdleConnections()
  2210  	cl := &Client{Transport: tr}
  2211  
  2212  	closes := 0
  2213  
  2214  	res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
  2215  	if err != nil {
  2216  		t.Fatal(err)
  2217  	}
  2218  	res.Body.Close()
  2219  	if closes != 1 {
  2220  		t.Errorf("closes = %d; want 1", closes)
  2221  	}
  2222  }
  2223  
  2224  func TestTransportTLSHandshakeTimeout(t *testing.T) {
  2225  	defer afterTest(t)
  2226  	if testing.Short() {
  2227  		t.Skip("skipping in short mode")
  2228  	}
  2229  	ln := newLocalListener(t)
  2230  	defer ln.Close()
  2231  	testdonec := make(chan struct{})
  2232  	defer close(testdonec)
  2233  
  2234  	go func() {
  2235  		c, err := ln.Accept()
  2236  		if err != nil {
  2237  			t.Error(err)
  2238  			return
  2239  		}
  2240  		<-testdonec
  2241  		c.Close()
  2242  	}()
  2243  
  2244  	getdonec := make(chan struct{})
  2245  	go func() {
  2246  		defer close(getdonec)
  2247  		tr := &Transport{
  2248  			Dial: func(_, _ string) (net.Conn, error) {
  2249  				return net.Dial("tcp", ln.Addr().String())
  2250  			},
  2251  			TLSHandshakeTimeout: 250 * time.Millisecond,
  2252  		}
  2253  		cl := &Client{Transport: tr}
  2254  		_, err := cl.Get("https://dummy.tld/")
  2255  		if err == nil {
  2256  			t.Error("expected error")
  2257  			return
  2258  		}
  2259  		ue, ok := err.(*url.Error)
  2260  		if !ok {
  2261  			t.Errorf("expected url.Error; got %#v", err)
  2262  			return
  2263  		}
  2264  		ne, ok := ue.Err.(net.Error)
  2265  		if !ok {
  2266  			t.Errorf("expected net.Error; got %#v", err)
  2267  			return
  2268  		}
  2269  		if !ne.Timeout() {
  2270  			t.Errorf("expected timeout error; got %v", err)
  2271  		}
  2272  		if !strings.Contains(err.Error(), "handshake timeout") {
  2273  			t.Errorf("expected 'handshake timeout' in error; got %v", err)
  2274  		}
  2275  	}()
  2276  	select {
  2277  	case <-getdonec:
  2278  	case <-time.After(5 * time.Second):
  2279  		t.Error("test timeout; TLS handshake hung?")
  2280  	}
  2281  }
  2282  
  2283  // Trying to repro golang.org/issue/3514
  2284  func TestTLSServerClosesConnection(t *testing.T) {
  2285  	defer afterTest(t)
  2286  	testenv.SkipFlaky(t, 7634)
  2287  
  2288  	closedc := make(chan bool, 1)
  2289  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2290  		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
  2291  			conn, _, _ := w.(Hijacker).Hijack()
  2292  			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
  2293  			conn.Close()
  2294  			closedc <- true
  2295  			return
  2296  		}
  2297  		fmt.Fprintf(w, "hello")
  2298  	}))
  2299  	defer ts.Close()
  2300  	tr := &Transport{
  2301  		TLSClientConfig: &tls.Config{
  2302  			InsecureSkipVerify: true,
  2303  		},
  2304  	}
  2305  	defer tr.CloseIdleConnections()
  2306  	client := &Client{Transport: tr}
  2307  
  2308  	var nSuccess = 0
  2309  	var errs []error
  2310  	const trials = 20
  2311  	for i := 0; i < trials; i++ {
  2312  		tr.CloseIdleConnections()
  2313  		res, err := client.Get(ts.URL + "/keep-alive-then-die")
  2314  		if err != nil {
  2315  			t.Fatal(err)
  2316  		}
  2317  		<-closedc
  2318  		slurp, err := ioutil.ReadAll(res.Body)
  2319  		if err != nil {
  2320  			t.Fatal(err)
  2321  		}
  2322  		if string(slurp) != "foo" {
  2323  			t.Errorf("Got %q, want foo", slurp)
  2324  		}
  2325  
  2326  		// Now try again and see if we successfully
  2327  		// pick a new connection.
  2328  		res, err = client.Get(ts.URL + "/")
  2329  		if err != nil {
  2330  			errs = append(errs, err)
  2331  			continue
  2332  		}
  2333  		slurp, err = ioutil.ReadAll(res.Body)
  2334  		if err != nil {
  2335  			errs = append(errs, err)
  2336  			continue
  2337  		}
  2338  		nSuccess++
  2339  	}
  2340  	if nSuccess > 0 {
  2341  		t.Logf("successes = %d of %d", nSuccess, trials)
  2342  	} else {
  2343  		t.Errorf("All runs failed:")
  2344  	}
  2345  	for _, err := range errs {
  2346  		t.Logf("  err: %v", err)
  2347  	}
  2348  }
  2349  
  2350  // byteFromChanReader is an io.Reader that reads a single byte at a
  2351  // time from the channel. When the channel is closed, the reader
  2352  // returns io.EOF.
  2353  type byteFromChanReader chan byte
  2354  
  2355  func (c byteFromChanReader) Read(p []byte) (n int, err error) {
  2356  	if len(p) == 0 {
  2357  		return
  2358  	}
  2359  	b, ok := <-c
  2360  	if !ok {
  2361  		return 0, io.EOF
  2362  	}
  2363  	p[0] = b
  2364  	return 1, nil
  2365  }
  2366  
  2367  // Verifies that the Transport doesn't reuse a connection in the case
  2368  // where the server replies before the request has been fully
  2369  // written. We still honor that reply (see TestIssue3595), but don't
  2370  // send future requests on the connection because it's then in a
  2371  // questionable state.
  2372  // golang.org/issue/7569
  2373  func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
  2374  	defer afterTest(t)
  2375  	var sconn struct {
  2376  		sync.Mutex
  2377  		c net.Conn
  2378  	}
  2379  	var getOkay bool
  2380  	closeConn := func() {
  2381  		sconn.Lock()
  2382  		defer sconn.Unlock()
  2383  		if sconn.c != nil {
  2384  			sconn.c.Close()
  2385  			sconn.c = nil
  2386  			if !getOkay {
  2387  				t.Logf("Closed server connection")
  2388  			}
  2389  		}
  2390  	}
  2391  	defer closeConn()
  2392  
  2393  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2394  		if r.Method == "GET" {
  2395  			io.WriteString(w, "bar")
  2396  			return
  2397  		}
  2398  		conn, _, _ := w.(Hijacker).Hijack()
  2399  		sconn.Lock()
  2400  		sconn.c = conn
  2401  		sconn.Unlock()
  2402  		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
  2403  		go io.Copy(ioutil.Discard, conn)
  2404  	}))
  2405  	defer ts.Close()
  2406  	tr := &Transport{}
  2407  	defer tr.CloseIdleConnections()
  2408  	client := &Client{Transport: tr}
  2409  
  2410  	const bodySize = 256 << 10
  2411  	finalBit := make(byteFromChanReader, 1)
  2412  	req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
  2413  	req.ContentLength = bodySize
  2414  	res, err := client.Do(req)
  2415  	if err := wantBody(res, err, "foo"); err != nil {
  2416  		t.Errorf("POST response: %v", err)
  2417  	}
  2418  	donec := make(chan bool)
  2419  	go func() {
  2420  		defer close(donec)
  2421  		res, err = client.Get(ts.URL)
  2422  		if err := wantBody(res, err, "bar"); err != nil {
  2423  			t.Errorf("GET response: %v", err)
  2424  			return
  2425  		}
  2426  		getOkay = true // suppress test noise
  2427  	}()
  2428  	time.AfterFunc(5*time.Second, closeConn)
  2429  	select {
  2430  	case <-donec:
  2431  		finalBit <- 'x' // unblock the writeloop of the first Post
  2432  		close(finalBit)
  2433  	case <-time.After(7 * time.Second):
  2434  		t.Fatal("timeout waiting for GET request to finish")
  2435  	}
  2436  }
  2437  
  2438  // Tests that we don't leak Transport persistConn.readLoop goroutines
  2439  // when a server hangs up immediately after saying it would keep-alive.
  2440  func TestTransportIssue10457(t *testing.T) {
  2441  	defer afterTest(t) // used to fail in goroutine leak check
  2442  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2443  		// Send a response with no body, keep-alive
  2444  		// (implicit), and then lie and immediately close the
  2445  		// connection. This forces the Transport's readLoop to
  2446  		// immediately Peek an io.EOF and get to the point
  2447  		// that used to hang.
  2448  		conn, _, _ := w.(Hijacker).Hijack()
  2449  		conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
  2450  		conn.Close()
  2451  	}))
  2452  	defer ts.Close()
  2453  	tr := &Transport{}
  2454  	defer tr.CloseIdleConnections()
  2455  	cl := &Client{Transport: tr}
  2456  	res, err := cl.Get(ts.URL)
  2457  	if err != nil {
  2458  		t.Fatalf("Get: %v", err)
  2459  	}
  2460  	defer res.Body.Close()
  2461  
  2462  	// Just a sanity check that we at least get the response. The real
  2463  	// test here is that the "defer afterTest" above doesn't find any
  2464  	// leaked goroutines.
  2465  	if got, want := res.Header.Get("Foo"), "Bar"; got != want {
  2466  		t.Errorf("Foo header = %q; want %q", got, want)
  2467  	}
  2468  }
  2469  
  2470  type errorReader struct {
  2471  	err error
  2472  }
  2473  
  2474  func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
  2475  
  2476  type plan9SleepReader struct{}
  2477  
  2478  func (plan9SleepReader) Read(p []byte) (int, error) {
  2479  	if runtime.GOOS == "plan9" {
  2480  		// After the fix to unblock TCP Reads in
  2481  		// https://golang.org/cl/15941, this sleep is required
  2482  		// on plan9 to make sure TCP Writes before an
  2483  		// immediate TCP close go out on the wire. On Plan 9,
  2484  		// it seems that a hangup of a TCP connection with
  2485  		// queued data doesn't send the queued data first.
  2486  		// https://golang.org/issue/9554
  2487  		time.Sleep(50 * time.Millisecond)
  2488  	}
  2489  	return 0, io.EOF
  2490  }
  2491  
  2492  type closerFunc func() error
  2493  
  2494  func (f closerFunc) Close() error { return f() }
  2495  
  2496  // Issue 4677. If we try to reuse a connection that the server is in the
  2497  // process of closing, we may end up successfully writing out our request (or a
  2498  // portion of our request) only to find a connection error when we try to read
  2499  // from (or finish writing to) the socket.
  2500  //
  2501  // NOTE: we resend a request only if the request is idempotent, we reused a
  2502  // keep-alive connection, and we haven't yet received any header data. This
  2503  // automatically prevents an infinite resend loop because we'll run out of the
  2504  // cached keep-alive connections eventually.
  2505  func TestRetryIdempotentRequestsOnError(t *testing.T) {
  2506  	defer afterTest(t)
  2507  
  2508  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2509  	}))
  2510  	defer ts.Close()
  2511  
  2512  	tr := &Transport{}
  2513  	c := &Client{Transport: tr}
  2514  
  2515  	const N = 2
  2516  	retryc := make(chan struct{}, N)
  2517  	SetRoundTripRetried(func() {
  2518  		retryc <- struct{}{}
  2519  	})
  2520  	defer SetRoundTripRetried(nil)
  2521  
  2522  	for n := 0; n < 100; n++ {
  2523  		// open 2 conns
  2524  		errc := make(chan error, N)
  2525  		for i := 0; i < N; i++ {
  2526  			// start goroutines, send on errc
  2527  			go func() {
  2528  				res, err := c.Get(ts.URL)
  2529  				if err == nil {
  2530  					res.Body.Close()
  2531  				}
  2532  				errc <- err
  2533  			}()
  2534  		}
  2535  		for i := 0; i < N; i++ {
  2536  			if err := <-errc; err != nil {
  2537  				t.Fatal(err)
  2538  			}
  2539  		}
  2540  
  2541  		ts.CloseClientConnections()
  2542  		for i := 0; i < N; i++ {
  2543  			go func() {
  2544  				res, err := c.Get(ts.URL)
  2545  				if err == nil {
  2546  					res.Body.Close()
  2547  				}
  2548  				errc <- err
  2549  			}()
  2550  		}
  2551  
  2552  		for i := 0; i < N; i++ {
  2553  			if err := <-errc; err != nil {
  2554  				t.Fatal(err)
  2555  			}
  2556  		}
  2557  		for i := 0; i < N; i++ {
  2558  			select {
  2559  			case <-retryc:
  2560  				// we triggered a retry, test was successful
  2561  				t.Logf("finished after %d runs\n", n)
  2562  				return
  2563  			default:
  2564  			}
  2565  		}
  2566  	}
  2567  	t.Fatal("did not trigger any retries")
  2568  }
  2569  
  2570  // Issue 6981
  2571  func TestTransportClosesBodyOnError(t *testing.T) {
  2572  	setParallel(t)
  2573  	defer afterTest(t)
  2574  	readBody := make(chan error, 1)
  2575  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2576  		_, err := ioutil.ReadAll(r.Body)
  2577  		readBody <- err
  2578  	}))
  2579  	defer ts.Close()
  2580  	fakeErr := errors.New("fake error")
  2581  	didClose := make(chan bool, 1)
  2582  	req, _ := NewRequest("POST", ts.URL, struct {
  2583  		io.Reader
  2584  		io.Closer
  2585  	}{
  2586  		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), plan9SleepReader{}, errorReader{fakeErr}),
  2587  		closerFunc(func() error {
  2588  			select {
  2589  			case didClose <- true:
  2590  			default:
  2591  			}
  2592  			return nil
  2593  		}),
  2594  	})
  2595  	res, err := DefaultClient.Do(req)
  2596  	if res != nil {
  2597  		defer res.Body.Close()
  2598  	}
  2599  	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
  2600  		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
  2601  	}
  2602  	select {
  2603  	case err := <-readBody:
  2604  		if err == nil {
  2605  			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
  2606  		}
  2607  	case <-time.After(5 * time.Second):
  2608  		t.Error("timeout waiting for server handler to complete")
  2609  	}
  2610  	select {
  2611  	case <-didClose:
  2612  	default:
  2613  		t.Errorf("didn't see Body.Close")
  2614  	}
  2615  }
  2616  
  2617  func TestTransportDialTLS(t *testing.T) {
  2618  	var mu sync.Mutex // guards following
  2619  	var gotReq, didDial bool
  2620  
  2621  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2622  		mu.Lock()
  2623  		gotReq = true
  2624  		mu.Unlock()
  2625  	}))
  2626  	defer ts.Close()
  2627  	tr := &Transport{
  2628  		DialTLS: func(netw, addr string) (net.Conn, error) {
  2629  			mu.Lock()
  2630  			didDial = true
  2631  			mu.Unlock()
  2632  			c, err := tls.Dial(netw, addr, &tls.Config{
  2633  				InsecureSkipVerify: true,
  2634  			})
  2635  			if err != nil {
  2636  				return nil, err
  2637  			}
  2638  			return c, c.Handshake()
  2639  		},
  2640  	}
  2641  	defer tr.CloseIdleConnections()
  2642  	client := &Client{Transport: tr}
  2643  	res, err := client.Get(ts.URL)
  2644  	if err != nil {
  2645  		t.Fatal(err)
  2646  	}
  2647  	res.Body.Close()
  2648  	mu.Lock()
  2649  	if !gotReq {
  2650  		t.Error("didn't get request")
  2651  	}
  2652  	if !didDial {
  2653  		t.Error("didn't use dial hook")
  2654  	}
  2655  }
  2656  
  2657  // Test for issue 8755
  2658  // Ensure that if a proxy returns an error, it is exposed by RoundTrip
  2659  func TestRoundTripReturnsProxyError(t *testing.T) {
  2660  	badProxy := func(*Request) (*url.URL, error) {
  2661  		return nil, errors.New("errorMessage")
  2662  	}
  2663  
  2664  	tr := &Transport{Proxy: badProxy}
  2665  
  2666  	req, _ := NewRequest("GET", "http://example.com", nil)
  2667  
  2668  	_, err := tr.RoundTrip(req)
  2669  
  2670  	if err == nil {
  2671  		t.Error("Expected proxy error to be returned by RoundTrip")
  2672  	}
  2673  }
  2674  
  2675  // tests that putting an idle conn after a call to CloseIdleConns does return it
  2676  func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
  2677  	tr := &Transport{}
  2678  	wantIdle := func(when string, n int) bool {
  2679  		got := tr.IdleConnCountForTesting("|http|example.com") // key used by PutIdleTestConn
  2680  		if got == n {
  2681  			return true
  2682  		}
  2683  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  2684  		return false
  2685  	}
  2686  	wantIdle("start", 0)
  2687  	if !tr.PutIdleTestConn() {
  2688  		t.Fatal("put failed")
  2689  	}
  2690  	if !tr.PutIdleTestConn() {
  2691  		t.Fatal("second put failed")
  2692  	}
  2693  	wantIdle("after put", 2)
  2694  	tr.CloseIdleConnections()
  2695  	if !tr.IsIdleForTesting() {
  2696  		t.Error("should be idle after CloseIdleConnections")
  2697  	}
  2698  	wantIdle("after close idle", 0)
  2699  	if tr.PutIdleTestConn() {
  2700  		t.Fatal("put didn't fail")
  2701  	}
  2702  	wantIdle("after second put", 0)
  2703  
  2704  	tr.RequestIdleConnChForTesting() // should toggle the transport out of idle mode
  2705  	if tr.IsIdleForTesting() {
  2706  		t.Error("shouldn't be idle after RequestIdleConnChForTesting")
  2707  	}
  2708  	if !tr.PutIdleTestConn() {
  2709  		t.Fatal("after re-activation")
  2710  	}
  2711  	wantIdle("after final put", 1)
  2712  }
  2713  
  2714  // This tests that an client requesting a content range won't also
  2715  // implicitly ask for gzip support. If they want that, they need to do it
  2716  // on their own.
  2717  // golang.org/issue/8923
  2718  func TestTransportRangeAndGzip(t *testing.T) {
  2719  	defer afterTest(t)
  2720  	reqc := make(chan *Request, 1)
  2721  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2722  		reqc <- r
  2723  	}))
  2724  	defer ts.Close()
  2725  
  2726  	req, _ := NewRequest("GET", ts.URL, nil)
  2727  	req.Header.Set("Range", "bytes=7-11")
  2728  	res, err := DefaultClient.Do(req)
  2729  	if err != nil {
  2730  		t.Fatal(err)
  2731  	}
  2732  
  2733  	select {
  2734  	case r := <-reqc:
  2735  		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  2736  			t.Error("Transport advertised gzip support in the Accept header")
  2737  		}
  2738  		if r.Header.Get("Range") == "" {
  2739  			t.Error("no Range in request")
  2740  		}
  2741  	case <-time.After(10 * time.Second):
  2742  		t.Fatal("timeout")
  2743  	}
  2744  	res.Body.Close()
  2745  }
  2746  
  2747  // Test for issue 10474
  2748  func TestTransportResponseCancelRace(t *testing.T) {
  2749  	defer afterTest(t)
  2750  
  2751  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2752  		// important that this response has a body.
  2753  		var b [1024]byte
  2754  		w.Write(b[:])
  2755  	}))
  2756  	defer ts.Close()
  2757  
  2758  	tr := &Transport{}
  2759  	defer tr.CloseIdleConnections()
  2760  
  2761  	req, err := NewRequest("GET", ts.URL, nil)
  2762  	if err != nil {
  2763  		t.Fatal(err)
  2764  	}
  2765  	res, err := tr.RoundTrip(req)
  2766  	if err != nil {
  2767  		t.Fatal(err)
  2768  	}
  2769  	// If we do an early close, Transport just throws the connection away and
  2770  	// doesn't reuse it. In order to trigger the bug, it has to reuse the connection
  2771  	// so read the body
  2772  	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
  2773  		t.Fatal(err)
  2774  	}
  2775  
  2776  	req2, err := NewRequest("GET", ts.URL, nil)
  2777  	if err != nil {
  2778  		t.Fatal(err)
  2779  	}
  2780  	tr.CancelRequest(req)
  2781  	res, err = tr.RoundTrip(req2)
  2782  	if err != nil {
  2783  		t.Fatal(err)
  2784  	}
  2785  	res.Body.Close()
  2786  }
  2787  
  2788  func TestTransportDialCancelRace(t *testing.T) {
  2789  	defer afterTest(t)
  2790  
  2791  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  2792  	defer ts.Close()
  2793  
  2794  	tr := &Transport{}
  2795  	defer tr.CloseIdleConnections()
  2796  
  2797  	req, err := NewRequest("GET", ts.URL, nil)
  2798  	if err != nil {
  2799  		t.Fatal(err)
  2800  	}
  2801  	SetEnterRoundTripHook(func() {
  2802  		tr.CancelRequest(req)
  2803  	})
  2804  	defer SetEnterRoundTripHook(nil)
  2805  	res, err := tr.RoundTrip(req)
  2806  	if err != ExportErrRequestCanceled {
  2807  		t.Errorf("expected canceled request error; got %v", err)
  2808  		if err == nil {
  2809  			res.Body.Close()
  2810  		}
  2811  	}
  2812  }
  2813  
  2814  // logWritesConn is a net.Conn that logs each Write call to writes
  2815  // and then proxies to w.
  2816  // It proxies Read calls to a reader it receives from rch.
  2817  type logWritesConn struct {
  2818  	net.Conn // nil. crash on use.
  2819  
  2820  	w io.Writer
  2821  
  2822  	rch <-chan io.Reader
  2823  	r   io.Reader // nil until received by rch
  2824  
  2825  	mu     sync.Mutex
  2826  	writes []string
  2827  }
  2828  
  2829  func (c *logWritesConn) Write(p []byte) (n int, err error) {
  2830  	c.mu.Lock()
  2831  	defer c.mu.Unlock()
  2832  	c.writes = append(c.writes, string(p))
  2833  	return c.w.Write(p)
  2834  }
  2835  
  2836  func (c *logWritesConn) Read(p []byte) (n int, err error) {
  2837  	if c.r == nil {
  2838  		c.r = <-c.rch
  2839  	}
  2840  	return c.r.Read(p)
  2841  }
  2842  
  2843  func (c *logWritesConn) Close() error { return nil }
  2844  
  2845  // Issue 6574
  2846  func TestTransportFlushesBodyChunks(t *testing.T) {
  2847  	defer afterTest(t)
  2848  	resBody := make(chan io.Reader, 1)
  2849  	connr, connw := io.Pipe() // connection pipe pair
  2850  	lw := &logWritesConn{
  2851  		rch: resBody,
  2852  		w:   connw,
  2853  	}
  2854  	tr := &Transport{
  2855  		Dial: func(network, addr string) (net.Conn, error) {
  2856  			return lw, nil
  2857  		},
  2858  	}
  2859  	bodyr, bodyw := io.Pipe() // body pipe pair
  2860  	go func() {
  2861  		defer bodyw.Close()
  2862  		for i := 0; i < 3; i++ {
  2863  			fmt.Fprintf(bodyw, "num%d\n", i)
  2864  		}
  2865  	}()
  2866  	resc := make(chan *Response)
  2867  	go func() {
  2868  		req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
  2869  		req.Header.Set("User-Agent", "x") // known value for test
  2870  		res, err := tr.RoundTrip(req)
  2871  		if err != nil {
  2872  			t.Errorf("RoundTrip: %v", err)
  2873  			close(resc)
  2874  			return
  2875  		}
  2876  		resc <- res
  2877  
  2878  	}()
  2879  	// Fully consume the request before checking the Write log vs. want.
  2880  	req, err := ReadRequest(bufio.NewReader(connr))
  2881  	if err != nil {
  2882  		t.Fatal(err)
  2883  	}
  2884  	io.Copy(ioutil.Discard, req.Body)
  2885  
  2886  	// Unblock the transport's roundTrip goroutine.
  2887  	resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
  2888  	res, ok := <-resc
  2889  	if !ok {
  2890  		return
  2891  	}
  2892  	defer res.Body.Close()
  2893  
  2894  	want := []string{
  2895  		// Because Request.ContentLength = 0, the body is sniffed for 1 byte to determine whether there's content.
  2896  		// That explains the initial "num0" being split into "n" and "um0".
  2897  		// The first byte is included with the request headers Write. Perhaps in the future
  2898  		// we will want to flush the headers out early if the first byte of the request body is
  2899  		// taking a long time to arrive. But not yet.
  2900  		"POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n" +
  2901  			"1\r\nn\r\n",
  2902  		"4\r\num0\n\r\n",
  2903  		"5\r\nnum1\n\r\n",
  2904  		"5\r\nnum2\n\r\n",
  2905  		"0\r\n\r\n",
  2906  	}
  2907  	if !reflect.DeepEqual(lw.writes, want) {
  2908  		t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
  2909  	}
  2910  }
  2911  
  2912  // Issue 11745.
  2913  func TestTransportPrefersResponseOverWriteError(t *testing.T) {
  2914  	if testing.Short() {
  2915  		t.Skip("skipping in short mode")
  2916  	}
  2917  	defer afterTest(t)
  2918  	const contentLengthLimit = 1024 * 1024 // 1MB
  2919  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2920  		if r.ContentLength >= contentLengthLimit {
  2921  			w.WriteHeader(StatusBadRequest)
  2922  			r.Body.Close()
  2923  			return
  2924  		}
  2925  		w.WriteHeader(StatusOK)
  2926  	}))
  2927  	defer ts.Close()
  2928  
  2929  	fail := 0
  2930  	count := 100
  2931  	bigBody := strings.Repeat("a", contentLengthLimit*2)
  2932  	for i := 0; i < count; i++ {
  2933  		req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
  2934  		if err != nil {
  2935  			t.Fatal(err)
  2936  		}
  2937  		tr := new(Transport)
  2938  		defer tr.CloseIdleConnections()
  2939  		client := &Client{Transport: tr}
  2940  		resp, err := client.Do(req)
  2941  		if err != nil {
  2942  			fail++
  2943  			t.Logf("%d = %#v", i, err)
  2944  			if ue, ok := err.(*url.Error); ok {
  2945  				t.Logf("urlErr = %#v", ue.Err)
  2946  				if ne, ok := ue.Err.(*net.OpError); ok {
  2947  					t.Logf("netOpError = %#v", ne.Err)
  2948  				}
  2949  			}
  2950  		} else {
  2951  			resp.Body.Close()
  2952  			if resp.StatusCode != 400 {
  2953  				t.Errorf("Expected status code 400, got %v", resp.Status)
  2954  			}
  2955  		}
  2956  	}
  2957  	if fail > 0 {
  2958  		t.Errorf("Failed %v out of %v\n", fail, count)
  2959  	}
  2960  }
  2961  
  2962  func TestTransportAutomaticHTTP2(t *testing.T) {
  2963  	testTransportAutoHTTP(t, &Transport{}, true)
  2964  }
  2965  
  2966  // golang.org/issue/14391: also check DefaultTransport
  2967  func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
  2968  	testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
  2969  }
  2970  
  2971  func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
  2972  	testTransportAutoHTTP(t, &Transport{
  2973  		TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
  2974  	}, false)
  2975  }
  2976  
  2977  func TestTransportAutomaticHTTP2_TLSConfig(t *testing.T) {
  2978  	testTransportAutoHTTP(t, &Transport{
  2979  		TLSClientConfig: new(tls.Config),
  2980  	}, false)
  2981  }
  2982  
  2983  func TestTransportAutomaticHTTP2_ExpectContinueTimeout(t *testing.T) {
  2984  	testTransportAutoHTTP(t, &Transport{
  2985  		ExpectContinueTimeout: 1 * time.Second,
  2986  	}, true)
  2987  }
  2988  
  2989  func TestTransportAutomaticHTTP2_Dial(t *testing.T) {
  2990  	var d net.Dialer
  2991  	testTransportAutoHTTP(t, &Transport{
  2992  		Dial: d.Dial,
  2993  	}, false)
  2994  }
  2995  
  2996  func TestTransportAutomaticHTTP2_DialTLS(t *testing.T) {
  2997  	testTransportAutoHTTP(t, &Transport{
  2998  		DialTLS: func(network, addr string) (net.Conn, error) {
  2999  			panic("unused")
  3000  		},
  3001  	}, false)
  3002  }
  3003  
  3004  func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) {
  3005  	_, err := tr.RoundTrip(new(Request))
  3006  	if err == nil {
  3007  		t.Error("expected error from RoundTrip")
  3008  	}
  3009  	if reg := tr.TLSNextProto["h2"] != nil; reg != wantH2 {
  3010  		t.Errorf("HTTP/2 registered = %v; want %v", reg, wantH2)
  3011  	}
  3012  }
  3013  
  3014  // Issue 13633: there was a race where we returned bodyless responses
  3015  // to callers before recycling the persistent connection, which meant
  3016  // a client doing two subsequent requests could end up on different
  3017  // connections. It's somewhat harmless but enough tests assume it's
  3018  // not true in order to test other things that it's worth fixing.
  3019  // Plus it's nice to be consistent and not have timing-dependent
  3020  // behavior.
  3021  func TestTransportReuseConnEmptyResponseBody(t *testing.T) {
  3022  	defer afterTest(t)
  3023  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  3024  		w.Header().Set("X-Addr", r.RemoteAddr)
  3025  		// Empty response body.
  3026  	}))
  3027  	defer cst.close()
  3028  	n := 100
  3029  	if testing.Short() {
  3030  		n = 10
  3031  	}
  3032  	var firstAddr string
  3033  	for i := 0; i < n; i++ {
  3034  		res, err := cst.c.Get(cst.ts.URL)
  3035  		if err != nil {
  3036  			log.Fatal(err)
  3037  		}
  3038  		addr := res.Header.Get("X-Addr")
  3039  		if i == 0 {
  3040  			firstAddr = addr
  3041  		} else if addr != firstAddr {
  3042  			t.Fatalf("On request %d, addr %q != original addr %q", i+1, addr, firstAddr)
  3043  		}
  3044  		res.Body.Close()
  3045  	}
  3046  }
  3047  
  3048  // Issue 13839
  3049  func TestNoCrashReturningTransportAltConn(t *testing.T) {
  3050  	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
  3051  	if err != nil {
  3052  		t.Fatal(err)
  3053  	}
  3054  	ln := newLocalListener(t)
  3055  	defer ln.Close()
  3056  
  3057  	handledPendingDial := make(chan bool, 1)
  3058  	SetPendingDialHooks(nil, func() { handledPendingDial <- true })
  3059  	defer SetPendingDialHooks(nil, nil)
  3060  
  3061  	testDone := make(chan struct{})
  3062  	defer close(testDone)
  3063  	go func() {
  3064  		tln := tls.NewListener(ln, &tls.Config{
  3065  			NextProtos:   []string{"foo"},
  3066  			Certificates: []tls.Certificate{cert},
  3067  		})
  3068  		sc, err := tln.Accept()
  3069  		if err != nil {
  3070  			t.Error(err)
  3071  			return
  3072  		}
  3073  		if err := sc.(*tls.Conn).Handshake(); err != nil {
  3074  			t.Error(err)
  3075  			return
  3076  		}
  3077  		<-testDone
  3078  		sc.Close()
  3079  	}()
  3080  
  3081  	addr := ln.Addr().String()
  3082  
  3083  	req, _ := NewRequest("GET", "https://fake.tld/", nil)
  3084  	cancel := make(chan struct{})
  3085  	req.Cancel = cancel
  3086  
  3087  	doReturned := make(chan bool, 1)
  3088  	madeRoundTripper := make(chan bool, 1)
  3089  
  3090  	tr := &Transport{
  3091  		DisableKeepAlives: true,
  3092  		TLSNextProto: map[string]func(string, *tls.Conn) RoundTripper{
  3093  			"foo": func(authority string, c *tls.Conn) RoundTripper {
  3094  				madeRoundTripper <- true
  3095  				return funcRoundTripper(func() {
  3096  					t.Error("foo RoundTripper should not be called")
  3097  				})
  3098  			},
  3099  		},
  3100  		Dial: func(_, _ string) (net.Conn, error) {
  3101  			panic("shouldn't be called")
  3102  		},
  3103  		DialTLS: func(_, _ string) (net.Conn, error) {
  3104  			tc, err := tls.Dial("tcp", addr, &tls.Config{
  3105  				InsecureSkipVerify: true,
  3106  				NextProtos:         []string{"foo"},
  3107  			})
  3108  			if err != nil {
  3109  				return nil, err
  3110  			}
  3111  			if err := tc.Handshake(); err != nil {
  3112  				return nil, err
  3113  			}
  3114  			close(cancel)
  3115  			<-doReturned
  3116  			return tc, nil
  3117  		},
  3118  	}
  3119  	c := &Client{Transport: tr}
  3120  
  3121  	_, err = c.Do(req)
  3122  	if ue, ok := err.(*url.Error); !ok || ue.Err != ExportErrRequestCanceledConn {
  3123  		t.Fatalf("Do error = %v; want url.Error with errRequestCanceledConn", err)
  3124  	}
  3125  
  3126  	doReturned <- true
  3127  	<-madeRoundTripper
  3128  	<-handledPendingDial
  3129  }
  3130  
  3131  func TestTransportReuseConnection_Gzip_Chunked(t *testing.T) {
  3132  	testTransportReuseConnection_Gzip(t, true)
  3133  }
  3134  
  3135  func TestTransportReuseConnection_Gzip_ContentLength(t *testing.T) {
  3136  	testTransportReuseConnection_Gzip(t, false)
  3137  }
  3138  
  3139  // Make sure we re-use underlying TCP connection for gzipped responses too.
  3140  func testTransportReuseConnection_Gzip(t *testing.T, chunked bool) {
  3141  	defer afterTest(t)
  3142  	addr := make(chan string, 2)
  3143  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3144  		addr <- r.RemoteAddr
  3145  		w.Header().Set("Content-Encoding", "gzip")
  3146  		if chunked {
  3147  			w.(Flusher).Flush()
  3148  		}
  3149  		w.Write(rgz) // arbitrary gzip response
  3150  	}))
  3151  	defer ts.Close()
  3152  
  3153  	tr := &Transport{}
  3154  	defer tr.CloseIdleConnections()
  3155  	c := &Client{Transport: tr}
  3156  	for i := 0; i < 2; i++ {
  3157  		res, err := c.Get(ts.URL)
  3158  		if err != nil {
  3159  			t.Fatal(err)
  3160  		}
  3161  		buf := make([]byte, len(rgz))
  3162  		if n, err := io.ReadFull(res.Body, buf); err != nil {
  3163  			t.Errorf("%d. ReadFull = %v, %v", i, n, err)
  3164  		}
  3165  		// Note: no res.Body.Close call. It should work without it,
  3166  		// since the flate.Reader's internal buffering will hit EOF
  3167  		// and that should be sufficient.
  3168  	}
  3169  	a1, a2 := <-addr, <-addr
  3170  	if a1 != a2 {
  3171  		t.Fatalf("didn't reuse connection")
  3172  	}
  3173  }
  3174  
  3175  func TestTransportResponseHeaderLength(t *testing.T) {
  3176  	defer afterTest(t)
  3177  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3178  		if r.URL.Path == "/long" {
  3179  			w.Header().Set("Long", strings.Repeat("a", 1<<20))
  3180  		}
  3181  	}))
  3182  	defer ts.Close()
  3183  
  3184  	tr := &Transport{
  3185  		MaxResponseHeaderBytes: 512 << 10,
  3186  	}
  3187  	defer tr.CloseIdleConnections()
  3188  	c := &Client{Transport: tr}
  3189  	if res, err := c.Get(ts.URL); err != nil {
  3190  		t.Fatal(err)
  3191  	} else {
  3192  		res.Body.Close()
  3193  	}
  3194  
  3195  	res, err := c.Get(ts.URL + "/long")
  3196  	if err == nil {
  3197  		defer res.Body.Close()
  3198  		var n int64
  3199  		for k, vv := range res.Header {
  3200  			for _, v := range vv {
  3201  				n += int64(len(k)) + int64(len(v))
  3202  			}
  3203  		}
  3204  		t.Fatalf("Unexpected success. Got %v and %d bytes of response headers", res.Status, n)
  3205  	}
  3206  	if want := "server response headers exceeded 524288 bytes"; !strings.Contains(err.Error(), want) {
  3207  		t.Errorf("got error: %v; want %q", err, want)
  3208  	}
  3209  }
  3210  
  3211  func TestTransportEventTrace(t *testing.T)    { testTransportEventTrace(t, h1Mode, false) }
  3212  func TestTransportEventTrace_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, false) }
  3213  
  3214  // test a non-nil httptrace.ClientTrace but with all hooks set to zero.
  3215  func TestTransportEventTrace_NoHooks(t *testing.T)    { testTransportEventTrace(t, h1Mode, true) }
  3216  func TestTransportEventTrace_NoHooks_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, true) }
  3217  
  3218  func testTransportEventTrace(t *testing.T, h2 bool, noHooks bool) {
  3219  	defer afterTest(t)
  3220  	const resBody = "some body"
  3221  	gotWroteReqEvent := make(chan struct{})
  3222  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  3223  		if _, err := ioutil.ReadAll(r.Body); err != nil {
  3224  			t.Error(err)
  3225  		}
  3226  		if !noHooks {
  3227  			select {
  3228  			case <-gotWroteReqEvent:
  3229  			case <-time.After(5 * time.Second):
  3230  				t.Error("timeout waiting for WroteRequest event")
  3231  			}
  3232  		}
  3233  		io.WriteString(w, resBody)
  3234  	}))
  3235  	defer cst.close()
  3236  
  3237  	cst.tr.ExpectContinueTimeout = 1 * time.Second
  3238  
  3239  	var mu sync.Mutex
  3240  	var buf bytes.Buffer
  3241  	logf := func(format string, args ...interface{}) {
  3242  		mu.Lock()
  3243  		defer mu.Unlock()
  3244  		fmt.Fprintf(&buf, format, args...)
  3245  		buf.WriteByte('\n')
  3246  	}
  3247  
  3248  	addrStr := cst.ts.Listener.Addr().String()
  3249  	ip, port, err := net.SplitHostPort(addrStr)
  3250  	if err != nil {
  3251  		t.Fatal(err)
  3252  	}
  3253  
  3254  	// Install a fake DNS server.
  3255  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) {
  3256  		if host != "dns-is-faked.golang" {
  3257  			t.Errorf("unexpected DNS host lookup for %q", host)
  3258  			return nil, nil
  3259  		}
  3260  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  3261  	})
  3262  
  3263  	req, _ := NewRequest("POST", cst.scheme()+"://dns-is-faked.golang:"+port, strings.NewReader("some body"))
  3264  	trace := &httptrace.ClientTrace{
  3265  		GetConn:              func(hostPort string) { logf("Getting conn for %v ...", hostPort) },
  3266  		GotConn:              func(ci httptrace.GotConnInfo) { logf("got conn: %+v", ci) },
  3267  		GotFirstResponseByte: func() { logf("first response byte") },
  3268  		PutIdleConn:          func(err error) { logf("PutIdleConn = %v", err) },
  3269  		DNSStart:             func(e httptrace.DNSStartInfo) { logf("DNS start: %+v", e) },
  3270  		DNSDone:              func(e httptrace.DNSDoneInfo) { logf("DNS done: %+v", e) },
  3271  		ConnectStart:         func(network, addr string) { logf("ConnectStart: Connecting to %s %s ...", network, addr) },
  3272  		ConnectDone: func(network, addr string, err error) {
  3273  			if err != nil {
  3274  				t.Errorf("ConnectDone: %v", err)
  3275  			}
  3276  			logf("ConnectDone: connected to %s %s = %v", network, addr, err)
  3277  		},
  3278  		Wait100Continue: func() { logf("Wait100Continue") },
  3279  		Got100Continue:  func() { logf("Got100Continue") },
  3280  		WroteRequest: func(e httptrace.WroteRequestInfo) {
  3281  			close(gotWroteReqEvent)
  3282  			logf("WroteRequest: %+v", e)
  3283  		},
  3284  	}
  3285  	if noHooks {
  3286  		// zero out all func pointers, trying to get some path to crash
  3287  		*trace = httptrace.ClientTrace{}
  3288  	}
  3289  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  3290  
  3291  	req.Header.Set("Expect", "100-continue")
  3292  	res, err := cst.c.Do(req)
  3293  	if err != nil {
  3294  		t.Fatal(err)
  3295  	}
  3296  	logf("got roundtrip.response")
  3297  	slurp, err := ioutil.ReadAll(res.Body)
  3298  	if err != nil {
  3299  		t.Fatal(err)
  3300  	}
  3301  	logf("consumed body")
  3302  	if string(slurp) != resBody || res.StatusCode != 200 {
  3303  		t.Fatalf("Got %q, %v; want %q, 200 OK", slurp, res.Status, resBody)
  3304  	}
  3305  	res.Body.Close()
  3306  
  3307  	if noHooks {
  3308  		// Done at this point. Just testing a full HTTP
  3309  		// requests can happen with a trace pointing to a zero
  3310  		// ClientTrace, full of nil func pointers.
  3311  		return
  3312  	}
  3313  
  3314  	got := buf.String()
  3315  	wantOnce := func(sub string) {
  3316  		if strings.Count(got, sub) != 1 {
  3317  			t.Errorf("expected substring %q exactly once in output.", sub)
  3318  		}
  3319  	}
  3320  	wantOnceOrMore := func(sub string) {
  3321  		if strings.Count(got, sub) == 0 {
  3322  			t.Errorf("expected substring %q at least once in output.", sub)
  3323  		}
  3324  	}
  3325  	wantOnce("Getting conn for dns-is-faked.golang:" + port)
  3326  	wantOnce("DNS start: {Host:dns-is-faked.golang}")
  3327  	wantOnce("DNS done: {Addrs:[{IP:" + ip + " Zone:}] Err:<nil> Coalesced:false}")
  3328  	wantOnce("got conn: {")
  3329  	wantOnceOrMore("Connecting to tcp " + addrStr)
  3330  	wantOnceOrMore("connected to tcp " + addrStr + " = <nil>")
  3331  	wantOnce("Reused:false WasIdle:false IdleTime:0s")
  3332  	wantOnce("first response byte")
  3333  	if !h2 {
  3334  		wantOnce("PutIdleConn = <nil>")
  3335  	}
  3336  	wantOnce("Wait100Continue")
  3337  	wantOnce("Got100Continue")
  3338  	wantOnce("WroteRequest: {Err:<nil>}")
  3339  	if strings.Contains(got, " to udp ") {
  3340  		t.Errorf("should not see UDP (DNS) connections")
  3341  	}
  3342  	if t.Failed() {
  3343  		t.Errorf("Output:\n%s", got)
  3344  	}
  3345  }
  3346  
  3347  func TestTransportEventTraceRealDNS(t *testing.T) {
  3348  	defer afterTest(t)
  3349  	tr := &Transport{}
  3350  	defer tr.CloseIdleConnections()
  3351  	c := &Client{Transport: tr}
  3352  
  3353  	var mu sync.Mutex
  3354  	var buf bytes.Buffer
  3355  	logf := func(format string, args ...interface{}) {
  3356  		mu.Lock()
  3357  		defer mu.Unlock()
  3358  		fmt.Fprintf(&buf, format, args...)
  3359  		buf.WriteByte('\n')
  3360  	}
  3361  
  3362  	req, _ := NewRequest("GET", "http://dns-should-not-resolve.golang:80", nil)
  3363  	trace := &httptrace.ClientTrace{
  3364  		DNSStart:     func(e httptrace.DNSStartInfo) { logf("DNSStart: %+v", e) },
  3365  		DNSDone:      func(e httptrace.DNSDoneInfo) { logf("DNSDone: %+v", e) },
  3366  		ConnectStart: func(network, addr string) { logf("ConnectStart: %s %s", network, addr) },
  3367  		ConnectDone:  func(network, addr string, err error) { logf("ConnectDone: %s %s %v", network, addr, err) },
  3368  	}
  3369  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  3370  
  3371  	resp, err := c.Do(req)
  3372  	if err == nil {
  3373  		resp.Body.Close()
  3374  		t.Fatal("expected error during DNS lookup")
  3375  	}
  3376  
  3377  	got := buf.String()
  3378  	wantSub := func(sub string) {
  3379  		if !strings.Contains(got, sub) {
  3380  			t.Errorf("expected substring %q in output.", sub)
  3381  		}
  3382  	}
  3383  	wantSub("DNSStart: {Host:dns-should-not-resolve.golang}")
  3384  	wantSub("DNSDone: {Addrs:[] Err:")
  3385  	if strings.Contains(got, "ConnectStart") || strings.Contains(got, "ConnectDone") {
  3386  		t.Errorf("should not see Connect events")
  3387  	}
  3388  	if t.Failed() {
  3389  		t.Errorf("Output:\n%s", got)
  3390  	}
  3391  }
  3392  
  3393  func TestTransportMaxIdleConns(t *testing.T) {
  3394  	defer afterTest(t)
  3395  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3396  		// No body for convenience.
  3397  	}))
  3398  	defer ts.Close()
  3399  	tr := &Transport{
  3400  		MaxIdleConns: 4,
  3401  	}
  3402  	defer tr.CloseIdleConnections()
  3403  
  3404  	ip, port, err := net.SplitHostPort(ts.Listener.Addr().String())
  3405  	if err != nil {
  3406  		t.Fatal(err)
  3407  	}
  3408  	c := &Client{Transport: tr}
  3409  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) {
  3410  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  3411  	})
  3412  
  3413  	hitHost := func(n int) {
  3414  		req, _ := NewRequest("GET", fmt.Sprintf("http://host-%d.dns-is-faked.golang:"+port, n), nil)
  3415  		req = req.WithContext(ctx)
  3416  		res, err := c.Do(req)
  3417  		if err != nil {
  3418  			t.Fatal(err)
  3419  		}
  3420  		res.Body.Close()
  3421  	}
  3422  	for i := 0; i < 4; i++ {
  3423  		hitHost(i)
  3424  	}
  3425  	want := []string{
  3426  		"|http|host-0.dns-is-faked.golang:" + port,
  3427  		"|http|host-1.dns-is-faked.golang:" + port,
  3428  		"|http|host-2.dns-is-faked.golang:" + port,
  3429  		"|http|host-3.dns-is-faked.golang:" + port,
  3430  	}
  3431  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  3432  		t.Fatalf("idle conn keys mismatch.\n got: %q\nwant: %q\n", got, want)
  3433  	}
  3434  
  3435  	// Now hitting the 5th host should kick out the first host:
  3436  	hitHost(4)
  3437  	want = []string{
  3438  		"|http|host-1.dns-is-faked.golang:" + port,
  3439  		"|http|host-2.dns-is-faked.golang:" + port,
  3440  		"|http|host-3.dns-is-faked.golang:" + port,
  3441  		"|http|host-4.dns-is-faked.golang:" + port,
  3442  	}
  3443  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  3444  		t.Fatalf("idle conn keys mismatch after 5th host.\n got: %q\nwant: %q\n", got, want)
  3445  	}
  3446  }
  3447  
  3448  func TestTransportIdleConnTimeout(t *testing.T) {
  3449  	if testing.Short() {
  3450  		t.Skip("skipping in short mode")
  3451  	}
  3452  	defer afterTest(t)
  3453  
  3454  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3455  		// No body for convenience.
  3456  	}))
  3457  	defer ts.Close()
  3458  
  3459  	const timeout = 1 * time.Second
  3460  	tr := &Transport{
  3461  		IdleConnTimeout: timeout,
  3462  	}
  3463  	defer tr.CloseIdleConnections()
  3464  	c := &Client{Transport: tr}
  3465  
  3466  	var conn string
  3467  	doReq := func(n int) {
  3468  		req, _ := NewRequest("GET", ts.URL, nil)
  3469  		req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  3470  			PutIdleConn: func(err error) {
  3471  				if err != nil {
  3472  					t.Errorf("failed to keep idle conn: %v", err)
  3473  				}
  3474  			},
  3475  		}))
  3476  		res, err := c.Do(req)
  3477  		if err != nil {
  3478  			t.Fatal(err)
  3479  		}
  3480  		res.Body.Close()
  3481  		conns := tr.IdleConnStrsForTesting()
  3482  		if len(conns) != 1 {
  3483  			t.Fatalf("req %v: unexpected number of idle conns: %q", n, conns)
  3484  		}
  3485  		if conn == "" {
  3486  			conn = conns[0]
  3487  		}
  3488  		if conn != conns[0] {
  3489  			t.Fatalf("req %v: cached connection changed; expected the same one throughout the test", n)
  3490  		}
  3491  	}
  3492  	for i := 0; i < 3; i++ {
  3493  		doReq(i)
  3494  		time.Sleep(timeout / 2)
  3495  	}
  3496  	time.Sleep(timeout * 3 / 2)
  3497  	if got := tr.IdleConnStrsForTesting(); len(got) != 0 {
  3498  		t.Errorf("idle conns = %q; want none", got)
  3499  	}
  3500  }
  3501  
  3502  var errFakeRoundTrip = errors.New("fake roundtrip")
  3503  
  3504  type funcRoundTripper func()
  3505  
  3506  func (fn funcRoundTripper) RoundTrip(*Request) (*Response, error) {
  3507  	fn()
  3508  	return nil, errFakeRoundTrip
  3509  }
  3510  
  3511  func wantBody(res *Response, err error, want string) error {
  3512  	if err != nil {
  3513  		return err
  3514  	}
  3515  	slurp, err := ioutil.ReadAll(res.Body)
  3516  	if err != nil {
  3517  		return fmt.Errorf("error reading body: %v", err)
  3518  	}
  3519  	if string(slurp) != want {
  3520  		return fmt.Errorf("body = %q; want %q", slurp, want)
  3521  	}
  3522  	if err := res.Body.Close(); err != nil {
  3523  		return fmt.Errorf("body Close = %v", err)
  3524  	}
  3525  	return nil
  3526  }
  3527  
  3528  func newLocalListener(t *testing.T) net.Listener {
  3529  	ln, err := net.Listen("tcp", "127.0.0.1:0")
  3530  	if err != nil {
  3531  		ln, err = net.Listen("tcp6", "[::1]:0")
  3532  	}
  3533  	if err != nil {
  3534  		t.Fatal(err)
  3535  	}
  3536  	return ln
  3537  }
  3538  
  3539  type countCloseReader struct {
  3540  	n *int
  3541  	io.Reader
  3542  }
  3543  
  3544  func (cr countCloseReader) Close() error {
  3545  	(*cr.n)++
  3546  	return nil
  3547  }
  3548  
  3549  // rgz is a gzip quine that uncompresses to itself.
  3550  var rgz = []byte{
  3551  	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  3552  	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  3553  	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  3554  	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  3555  	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  3556  	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  3557  	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  3558  	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  3559  	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  3560  	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  3561  	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  3562  	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  3563  	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  3564  	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  3565  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  3566  	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  3567  	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  3568  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  3569  	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  3570  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  3571  	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  3572  	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  3573  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  3574  	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  3575  	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  3576  	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  3577  	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  3578  	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  3579  	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  3580  	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  3581  	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  3582  	0x00, 0x00,
  3583  }