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