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