github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/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  func TestTransportProxy(t *testing.T) {
   794  	defer afterTest(t)
   795  	ch := make(chan string, 1)
   796  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   797  		ch <- "real server"
   798  	}))
   799  	defer ts.Close()
   800  	proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   801  		ch <- "proxy for " + r.URL.String()
   802  	}))
   803  	defer proxy.Close()
   804  
   805  	pu, err := url.Parse(proxy.URL)
   806  	if err != nil {
   807  		t.Fatal(err)
   808  	}
   809  	c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
   810  	c.Head(ts.URL)
   811  	got := <-ch
   812  	want := "proxy for " + ts.URL + "/"
   813  	if got != want {
   814  		t.Errorf("want %q, got %q", want, got)
   815  	}
   816  }
   817  
   818  // TestTransportGzipRecursive sends a gzip quine and checks that the
   819  // client gets the same value back. This is more cute than anything,
   820  // but checks that we don't recurse forever, and checks that
   821  // Content-Encoding is removed.
   822  func TestTransportGzipRecursive(t *testing.T) {
   823  	defer afterTest(t)
   824  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   825  		w.Header().Set("Content-Encoding", "gzip")
   826  		w.Write(rgz)
   827  	}))
   828  	defer ts.Close()
   829  
   830  	c := &Client{Transport: &Transport{}}
   831  	res, err := c.Get(ts.URL)
   832  	if err != nil {
   833  		t.Fatal(err)
   834  	}
   835  	body, err := ioutil.ReadAll(res.Body)
   836  	if err != nil {
   837  		t.Fatal(err)
   838  	}
   839  	if !bytes.Equal(body, rgz) {
   840  		t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
   841  			body, rgz)
   842  	}
   843  	if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
   844  		t.Fatalf("Content-Encoding = %q; want %q", g, e)
   845  	}
   846  }
   847  
   848  // golang.org/issue/7750: request fails when server replies with
   849  // a short gzip body
   850  func TestTransportGzipShort(t *testing.T) {
   851  	defer afterTest(t)
   852  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   853  		w.Header().Set("Content-Encoding", "gzip")
   854  		w.Write([]byte{0x1f, 0x8b})
   855  	}))
   856  	defer ts.Close()
   857  
   858  	tr := &Transport{}
   859  	defer tr.CloseIdleConnections()
   860  	c := &Client{Transport: tr}
   861  	res, err := c.Get(ts.URL)
   862  	if err != nil {
   863  		t.Fatal(err)
   864  	}
   865  	defer res.Body.Close()
   866  	_, err = ioutil.ReadAll(res.Body)
   867  	if err == nil {
   868  		t.Fatal("Expect an error from reading a body.")
   869  	}
   870  	if err != io.ErrUnexpectedEOF {
   871  		t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err)
   872  	}
   873  }
   874  
   875  // tests that persistent goroutine connections shut down when no longer desired.
   876  func TestTransportPersistConnLeak(t *testing.T) {
   877  	if runtime.GOOS == "plan9" {
   878  		t.Skip("skipping test; see https://golang.org/issue/7237")
   879  	}
   880  	defer afterTest(t)
   881  	gotReqCh := make(chan bool)
   882  	unblockCh := make(chan bool)
   883  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   884  		gotReqCh <- true
   885  		<-unblockCh
   886  		w.Header().Set("Content-Length", "0")
   887  		w.WriteHeader(204)
   888  	}))
   889  	defer ts.Close()
   890  
   891  	tr := &Transport{}
   892  	c := &Client{Transport: tr}
   893  
   894  	n0 := runtime.NumGoroutine()
   895  
   896  	const numReq = 25
   897  	didReqCh := make(chan bool)
   898  	for i := 0; i < numReq; i++ {
   899  		go func() {
   900  			res, err := c.Get(ts.URL)
   901  			didReqCh <- true
   902  			if err != nil {
   903  				t.Errorf("client fetch error: %v", err)
   904  				return
   905  			}
   906  			res.Body.Close()
   907  		}()
   908  	}
   909  
   910  	// Wait for all goroutines to be stuck in the Handler.
   911  	for i := 0; i < numReq; i++ {
   912  		<-gotReqCh
   913  	}
   914  
   915  	nhigh := runtime.NumGoroutine()
   916  
   917  	// Tell all handlers to unblock and reply.
   918  	for i := 0; i < numReq; i++ {
   919  		unblockCh <- true
   920  	}
   921  
   922  	// Wait for all HTTP clients to be done.
   923  	for i := 0; i < numReq; i++ {
   924  		<-didReqCh
   925  	}
   926  
   927  	tr.CloseIdleConnections()
   928  	time.Sleep(100 * time.Millisecond)
   929  	runtime.GC()
   930  	runtime.GC() // even more.
   931  	nfinal := runtime.NumGoroutine()
   932  
   933  	growth := nfinal - n0
   934  
   935  	// We expect 0 or 1 extra goroutine, empirically.  Allow up to 5.
   936  	// Previously we were leaking one per numReq.
   937  	if int(growth) > 5 {
   938  		t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
   939  		t.Error("too many new goroutines")
   940  	}
   941  }
   942  
   943  // golang.org/issue/4531: Transport leaks goroutines when
   944  // request.ContentLength is explicitly short
   945  func TestTransportPersistConnLeakShortBody(t *testing.T) {
   946  	if runtime.GOOS == "plan9" {
   947  		t.Skip("skipping test; see https://golang.org/issue/7237")
   948  	}
   949  	defer afterTest(t)
   950  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   951  	}))
   952  	defer ts.Close()
   953  
   954  	tr := &Transport{}
   955  	c := &Client{Transport: tr}
   956  
   957  	n0 := runtime.NumGoroutine()
   958  	body := []byte("Hello")
   959  	for i := 0; i < 20; i++ {
   960  		req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
   961  		if err != nil {
   962  			t.Fatal(err)
   963  		}
   964  		req.ContentLength = int64(len(body) - 2) // explicitly short
   965  		_, err = c.Do(req)
   966  		if err == nil {
   967  			t.Fatal("Expect an error from writing too long of a body.")
   968  		}
   969  	}
   970  	nhigh := runtime.NumGoroutine()
   971  	tr.CloseIdleConnections()
   972  	time.Sleep(400 * time.Millisecond)
   973  	runtime.GC()
   974  	nfinal := runtime.NumGoroutine()
   975  
   976  	growth := nfinal - n0
   977  
   978  	// We expect 0 or 1 extra goroutine, empirically.  Allow up to 5.
   979  	// Previously we were leaking one per numReq.
   980  	t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
   981  	if int(growth) > 5 {
   982  		t.Error("too many new goroutines")
   983  	}
   984  }
   985  
   986  // This used to crash; https://golang.org/issue/3266
   987  func TestTransportIdleConnCrash(t *testing.T) {
   988  	defer afterTest(t)
   989  	tr := &Transport{}
   990  	c := &Client{Transport: tr}
   991  
   992  	unblockCh := make(chan bool, 1)
   993  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   994  		<-unblockCh
   995  		tr.CloseIdleConnections()
   996  	}))
   997  	defer ts.Close()
   998  
   999  	didreq := make(chan bool)
  1000  	go func() {
  1001  		res, err := c.Get(ts.URL)
  1002  		if err != nil {
  1003  			t.Error(err)
  1004  		} else {
  1005  			res.Body.Close() // returns idle conn
  1006  		}
  1007  		didreq <- true
  1008  	}()
  1009  	unblockCh <- true
  1010  	<-didreq
  1011  }
  1012  
  1013  // Test that the transport doesn't close the TCP connection early,
  1014  // before the response body has been read.  This was a regression
  1015  // which sadly lacked a triggering test.  The large response body made
  1016  // the old race easier to trigger.
  1017  func TestIssue3644(t *testing.T) {
  1018  	defer afterTest(t)
  1019  	const numFoos = 5000
  1020  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1021  		w.Header().Set("Connection", "close")
  1022  		for i := 0; i < numFoos; i++ {
  1023  			w.Write([]byte("foo "))
  1024  		}
  1025  	}))
  1026  	defer ts.Close()
  1027  	tr := &Transport{}
  1028  	c := &Client{Transport: tr}
  1029  	res, err := c.Get(ts.URL)
  1030  	if err != nil {
  1031  		t.Fatal(err)
  1032  	}
  1033  	defer res.Body.Close()
  1034  	bs, err := ioutil.ReadAll(res.Body)
  1035  	if err != nil {
  1036  		t.Fatal(err)
  1037  	}
  1038  	if len(bs) != numFoos*len("foo ") {
  1039  		t.Errorf("unexpected response length")
  1040  	}
  1041  }
  1042  
  1043  // Test that a client receives a server's reply, even if the server doesn't read
  1044  // the entire request body.
  1045  func TestIssue3595(t *testing.T) {
  1046  	defer afterTest(t)
  1047  	const deniedMsg = "sorry, denied."
  1048  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1049  		Error(w, deniedMsg, StatusUnauthorized)
  1050  	}))
  1051  	defer ts.Close()
  1052  	tr := &Transport{}
  1053  	c := &Client{Transport: tr}
  1054  	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
  1055  	if err != nil {
  1056  		t.Errorf("Post: %v", err)
  1057  		return
  1058  	}
  1059  	got, err := ioutil.ReadAll(res.Body)
  1060  	if err != nil {
  1061  		t.Fatalf("Body ReadAll: %v", err)
  1062  	}
  1063  	if !strings.Contains(string(got), deniedMsg) {
  1064  		t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
  1065  	}
  1066  }
  1067  
  1068  // From https://golang.org/issue/4454 ,
  1069  // "client fails to handle requests with no body and chunked encoding"
  1070  func TestChunkedNoContent(t *testing.T) {
  1071  	defer afterTest(t)
  1072  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1073  		w.WriteHeader(StatusNoContent)
  1074  	}))
  1075  	defer ts.Close()
  1076  
  1077  	for _, closeBody := range []bool{true, false} {
  1078  		c := &Client{Transport: &Transport{}}
  1079  		const n = 4
  1080  		for i := 1; i <= n; i++ {
  1081  			res, err := c.Get(ts.URL)
  1082  			if err != nil {
  1083  				t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
  1084  			} else {
  1085  				if closeBody {
  1086  					res.Body.Close()
  1087  				}
  1088  			}
  1089  		}
  1090  	}
  1091  }
  1092  
  1093  func TestTransportConcurrency(t *testing.T) {
  1094  	defer afterTest(t)
  1095  	maxProcs, numReqs := 16, 500
  1096  	if testing.Short() {
  1097  		maxProcs, numReqs = 4, 50
  1098  	}
  1099  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
  1100  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1101  		fmt.Fprintf(w, "%v", r.FormValue("echo"))
  1102  	}))
  1103  	defer ts.Close()
  1104  
  1105  	var wg sync.WaitGroup
  1106  	wg.Add(numReqs)
  1107  
  1108  	// Due to the Transport's "socket late binding" (see
  1109  	// idleConnCh in transport.go), the numReqs HTTP requests
  1110  	// below can finish with a dial still outstanding.  To keep
  1111  	// the leak checker happy, keep track of pending dials and
  1112  	// wait for them to finish (and be closed or returned to the
  1113  	// idle pool) before we close idle connections.
  1114  	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  1115  	defer SetPendingDialHooks(nil, nil)
  1116  
  1117  	tr := &Transport{}
  1118  	defer tr.CloseIdleConnections()
  1119  
  1120  	c := &Client{Transport: tr}
  1121  	reqs := make(chan string)
  1122  	defer close(reqs)
  1123  
  1124  	for i := 0; i < maxProcs*2; i++ {
  1125  		go func() {
  1126  			for req := range reqs {
  1127  				res, err := c.Get(ts.URL + "/?echo=" + req)
  1128  				if err != nil {
  1129  					t.Errorf("error on req %s: %v", req, err)
  1130  					wg.Done()
  1131  					continue
  1132  				}
  1133  				all, err := ioutil.ReadAll(res.Body)
  1134  				if err != nil {
  1135  					t.Errorf("read error on req %s: %v", req, err)
  1136  					wg.Done()
  1137  					continue
  1138  				}
  1139  				if string(all) != req {
  1140  					t.Errorf("body of req %s = %q; want %q", req, all, req)
  1141  				}
  1142  				res.Body.Close()
  1143  				wg.Done()
  1144  			}
  1145  		}()
  1146  	}
  1147  	for i := 0; i < numReqs; i++ {
  1148  		reqs <- fmt.Sprintf("request-%d", i)
  1149  	}
  1150  	wg.Wait()
  1151  }
  1152  
  1153  func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
  1154  	if runtime.GOOS == "plan9" {
  1155  		t.Skip("skipping test; see https://golang.org/issue/7237")
  1156  	}
  1157  	defer afterTest(t)
  1158  	const debug = false
  1159  	mux := NewServeMux()
  1160  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1161  		io.Copy(w, neverEnding('a'))
  1162  	})
  1163  	ts := httptest.NewServer(mux)
  1164  	timeout := 100 * time.Millisecond
  1165  
  1166  	client := &Client{
  1167  		Transport: &Transport{
  1168  			Dial: func(n, addr string) (net.Conn, error) {
  1169  				conn, err := net.Dial(n, addr)
  1170  				if err != nil {
  1171  					return nil, err
  1172  				}
  1173  				conn.SetDeadline(time.Now().Add(timeout))
  1174  				if debug {
  1175  					conn = NewLoggingConn("client", conn)
  1176  				}
  1177  				return conn, nil
  1178  			},
  1179  			DisableKeepAlives: true,
  1180  		},
  1181  	}
  1182  
  1183  	getFailed := false
  1184  	nRuns := 5
  1185  	if testing.Short() {
  1186  		nRuns = 1
  1187  	}
  1188  	for i := 0; i < nRuns; i++ {
  1189  		if debug {
  1190  			println("run", i+1, "of", nRuns)
  1191  		}
  1192  		sres, err := client.Get(ts.URL + "/get")
  1193  		if err != nil {
  1194  			if !getFailed {
  1195  				// Make the timeout longer, once.
  1196  				getFailed = true
  1197  				t.Logf("increasing timeout")
  1198  				i--
  1199  				timeout *= 10
  1200  				continue
  1201  			}
  1202  			t.Errorf("Error issuing GET: %v", err)
  1203  			break
  1204  		}
  1205  		_, err = io.Copy(ioutil.Discard, sres.Body)
  1206  		if err == nil {
  1207  			t.Errorf("Unexpected successful copy")
  1208  			break
  1209  		}
  1210  	}
  1211  	if debug {
  1212  		println("tests complete; waiting for handlers to finish")
  1213  	}
  1214  	ts.Close()
  1215  }
  1216  
  1217  func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
  1218  	if runtime.GOOS == "plan9" {
  1219  		t.Skip("skipping test; see https://golang.org/issue/7237")
  1220  	}
  1221  	defer afterTest(t)
  1222  	const debug = false
  1223  	mux := NewServeMux()
  1224  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1225  		io.Copy(w, neverEnding('a'))
  1226  	})
  1227  	mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
  1228  		defer r.Body.Close()
  1229  		io.Copy(ioutil.Discard, r.Body)
  1230  	})
  1231  	ts := httptest.NewServer(mux)
  1232  	timeout := 100 * time.Millisecond
  1233  
  1234  	client := &Client{
  1235  		Transport: &Transport{
  1236  			Dial: func(n, addr string) (net.Conn, error) {
  1237  				conn, err := net.Dial(n, addr)
  1238  				if err != nil {
  1239  					return nil, err
  1240  				}
  1241  				conn.SetDeadline(time.Now().Add(timeout))
  1242  				if debug {
  1243  					conn = NewLoggingConn("client", conn)
  1244  				}
  1245  				return conn, nil
  1246  			},
  1247  			DisableKeepAlives: true,
  1248  		},
  1249  	}
  1250  
  1251  	getFailed := false
  1252  	nRuns := 5
  1253  	if testing.Short() {
  1254  		nRuns = 1
  1255  	}
  1256  	for i := 0; i < nRuns; i++ {
  1257  		if debug {
  1258  			println("run", i+1, "of", nRuns)
  1259  		}
  1260  		sres, err := client.Get(ts.URL + "/get")
  1261  		if err != nil {
  1262  			if !getFailed {
  1263  				// Make the timeout longer, once.
  1264  				getFailed = true
  1265  				t.Logf("increasing timeout")
  1266  				i--
  1267  				timeout *= 10
  1268  				continue
  1269  			}
  1270  			t.Errorf("Error issuing GET: %v", err)
  1271  			break
  1272  		}
  1273  		req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
  1274  		_, err = client.Do(req)
  1275  		if err == nil {
  1276  			sres.Body.Close()
  1277  			t.Errorf("Unexpected successful PUT")
  1278  			break
  1279  		}
  1280  		sres.Body.Close()
  1281  	}
  1282  	if debug {
  1283  		println("tests complete; waiting for handlers to finish")
  1284  	}
  1285  	ts.Close()
  1286  }
  1287  
  1288  func TestTransportResponseHeaderTimeout(t *testing.T) {
  1289  	defer afterTest(t)
  1290  	if testing.Short() {
  1291  		t.Skip("skipping timeout test in -short mode")
  1292  	}
  1293  	inHandler := make(chan bool, 1)
  1294  	mux := NewServeMux()
  1295  	mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {
  1296  		inHandler <- true
  1297  	})
  1298  	mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
  1299  		inHandler <- true
  1300  		time.Sleep(2 * time.Second)
  1301  	})
  1302  	ts := httptest.NewServer(mux)
  1303  	defer ts.Close()
  1304  
  1305  	tr := &Transport{
  1306  		ResponseHeaderTimeout: 500 * time.Millisecond,
  1307  	}
  1308  	defer tr.CloseIdleConnections()
  1309  	c := &Client{Transport: tr}
  1310  
  1311  	tests := []struct {
  1312  		path    string
  1313  		want    int
  1314  		wantErr string
  1315  	}{
  1316  		{path: "/fast", want: 200},
  1317  		{path: "/slow", wantErr: "timeout awaiting response headers"},
  1318  		{path: "/fast", want: 200},
  1319  	}
  1320  	for i, tt := range tests {
  1321  		res, err := c.Get(ts.URL + tt.path)
  1322  		select {
  1323  		case <-inHandler:
  1324  		case <-time.After(5 * time.Second):
  1325  			t.Errorf("never entered handler for test index %d, %s", i, tt.path)
  1326  			continue
  1327  		}
  1328  		if err != nil {
  1329  			uerr, ok := err.(*url.Error)
  1330  			if !ok {
  1331  				t.Errorf("error is not an url.Error; got: %#v", err)
  1332  				continue
  1333  			}
  1334  			nerr, ok := uerr.Err.(net.Error)
  1335  			if !ok {
  1336  				t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
  1337  				continue
  1338  			}
  1339  			if !nerr.Timeout() {
  1340  				t.Errorf("want timeout error; got: %q", nerr)
  1341  				continue
  1342  			}
  1343  			if strings.Contains(err.Error(), tt.wantErr) {
  1344  				continue
  1345  			}
  1346  			t.Errorf("%d. unexpected error: %v", i, err)
  1347  			continue
  1348  		}
  1349  		if tt.wantErr != "" {
  1350  			t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
  1351  			continue
  1352  		}
  1353  		if res.StatusCode != tt.want {
  1354  			t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
  1355  		}
  1356  	}
  1357  }
  1358  
  1359  func TestTransportCancelRequest(t *testing.T) {
  1360  	defer afterTest(t)
  1361  	if testing.Short() {
  1362  		t.Skip("skipping test in -short mode")
  1363  	}
  1364  	unblockc := make(chan bool)
  1365  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1366  		fmt.Fprintf(w, "Hello")
  1367  		w.(Flusher).Flush() // send headers and some body
  1368  		<-unblockc
  1369  	}))
  1370  	defer ts.Close()
  1371  	defer close(unblockc)
  1372  
  1373  	tr := &Transport{}
  1374  	defer tr.CloseIdleConnections()
  1375  	c := &Client{Transport: tr}
  1376  
  1377  	req, _ := NewRequest("GET", ts.URL, nil)
  1378  	res, err := c.Do(req)
  1379  	if err != nil {
  1380  		t.Fatal(err)
  1381  	}
  1382  	go func() {
  1383  		time.Sleep(1 * time.Second)
  1384  		tr.CancelRequest(req)
  1385  	}()
  1386  	t0 := time.Now()
  1387  	body, err := ioutil.ReadAll(res.Body)
  1388  	d := time.Since(t0)
  1389  
  1390  	if err != ExportErrRequestCanceled {
  1391  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  1392  	}
  1393  	if string(body) != "Hello" {
  1394  		t.Errorf("Body = %q; want Hello", body)
  1395  	}
  1396  	if d < 500*time.Millisecond {
  1397  		t.Errorf("expected ~1 second delay; got %v", d)
  1398  	}
  1399  	// Verify no outstanding requests after readLoop/writeLoop
  1400  	// goroutines shut down.
  1401  	for tries := 5; tries > 0; tries-- {
  1402  		n := tr.NumPendingRequestsForTesting()
  1403  		if n == 0 {
  1404  			break
  1405  		}
  1406  		time.Sleep(100 * time.Millisecond)
  1407  		if tries == 1 {
  1408  			t.Errorf("pending requests = %d; want 0", n)
  1409  		}
  1410  	}
  1411  }
  1412  
  1413  func TestTransportCancelRequestInDial(t *testing.T) {
  1414  	defer afterTest(t)
  1415  	if testing.Short() {
  1416  		t.Skip("skipping test in -short mode")
  1417  	}
  1418  	var logbuf bytes.Buffer
  1419  	eventLog := log.New(&logbuf, "", 0)
  1420  
  1421  	unblockDial := make(chan bool)
  1422  	defer close(unblockDial)
  1423  
  1424  	inDial := make(chan bool)
  1425  	tr := &Transport{
  1426  		Dial: func(network, addr string) (net.Conn, error) {
  1427  			eventLog.Println("dial: blocking")
  1428  			inDial <- true
  1429  			<-unblockDial
  1430  			return nil, errors.New("nope")
  1431  		},
  1432  	}
  1433  	cl := &Client{Transport: tr}
  1434  	gotres := make(chan bool)
  1435  	req, _ := NewRequest("GET", "http://something.no-network.tld/", nil)
  1436  	go func() {
  1437  		_, err := cl.Do(req)
  1438  		eventLog.Printf("Get = %v", err)
  1439  		gotres <- true
  1440  	}()
  1441  
  1442  	select {
  1443  	case <-inDial:
  1444  	case <-time.After(5 * time.Second):
  1445  		t.Fatal("timeout; never saw blocking dial")
  1446  	}
  1447  
  1448  	eventLog.Printf("canceling")
  1449  	tr.CancelRequest(req)
  1450  	tr.CancelRequest(req) // used to panic on second call
  1451  
  1452  	select {
  1453  	case <-gotres:
  1454  	case <-time.After(5 * time.Second):
  1455  		panic("hang. events are: " + logbuf.String())
  1456  	}
  1457  
  1458  	got := logbuf.String()
  1459  	want := `dial: blocking
  1460  canceling
  1461  Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection
  1462  `
  1463  	if got != want {
  1464  		t.Errorf("Got events:\n%s\nWant:\n%s", got, want)
  1465  	}
  1466  }
  1467  
  1468  func TestCancelRequestWithChannel(t *testing.T) {
  1469  	defer afterTest(t)
  1470  	if testing.Short() {
  1471  		t.Skip("skipping test in -short mode")
  1472  	}
  1473  	unblockc := make(chan bool)
  1474  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1475  		fmt.Fprintf(w, "Hello")
  1476  		w.(Flusher).Flush() // send headers and some body
  1477  		<-unblockc
  1478  	}))
  1479  	defer ts.Close()
  1480  	defer close(unblockc)
  1481  
  1482  	tr := &Transport{}
  1483  	defer tr.CloseIdleConnections()
  1484  	c := &Client{Transport: tr}
  1485  
  1486  	req, _ := NewRequest("GET", ts.URL, nil)
  1487  	ch := make(chan struct{})
  1488  	req.Cancel = ch
  1489  
  1490  	res, err := c.Do(req)
  1491  	if err != nil {
  1492  		t.Fatal(err)
  1493  	}
  1494  	go func() {
  1495  		time.Sleep(1 * time.Second)
  1496  		close(ch)
  1497  	}()
  1498  	t0 := time.Now()
  1499  	body, err := ioutil.ReadAll(res.Body)
  1500  	d := time.Since(t0)
  1501  
  1502  	if err != ExportErrRequestCanceled {
  1503  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  1504  	}
  1505  	if string(body) != "Hello" {
  1506  		t.Errorf("Body = %q; want Hello", body)
  1507  	}
  1508  	if d < 500*time.Millisecond {
  1509  		t.Errorf("expected ~1 second delay; got %v", d)
  1510  	}
  1511  	// Verify no outstanding requests after readLoop/writeLoop
  1512  	// goroutines shut down.
  1513  	for tries := 5; tries > 0; tries-- {
  1514  		n := tr.NumPendingRequestsForTesting()
  1515  		if n == 0 {
  1516  			break
  1517  		}
  1518  		time.Sleep(100 * time.Millisecond)
  1519  		if tries == 1 {
  1520  			t.Errorf("pending requests = %d; want 0", n)
  1521  		}
  1522  	}
  1523  }
  1524  
  1525  func TestCancelRequestWithChannelBeforeDo(t *testing.T) {
  1526  	defer afterTest(t)
  1527  	unblockc := make(chan bool)
  1528  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1529  		<-unblockc
  1530  	}))
  1531  	defer ts.Close()
  1532  	defer close(unblockc)
  1533  
  1534  	// Don't interfere with the next test on plan9.
  1535  	// Cf. https://golang.org/issues/11476
  1536  	if runtime.GOOS == "plan9" {
  1537  		defer time.Sleep(500 * time.Millisecond)
  1538  	}
  1539  
  1540  	tr := &Transport{}
  1541  	defer tr.CloseIdleConnections()
  1542  	c := &Client{Transport: tr}
  1543  
  1544  	req, _ := NewRequest("GET", ts.URL, nil)
  1545  	ch := make(chan struct{})
  1546  	req.Cancel = ch
  1547  	close(ch)
  1548  
  1549  	_, err := c.Do(req)
  1550  	if err == nil || !strings.Contains(err.Error(), "canceled") {
  1551  		t.Errorf("Do error = %v; want cancelation", err)
  1552  	}
  1553  }
  1554  
  1555  // Issue 11020. The returned error message should be errRequestCanceled
  1556  func TestTransportCancelBeforeResponseHeaders(t *testing.T) {
  1557  	t.Skip("Skipping flaky test; see Issue 11894")
  1558  	defer afterTest(t)
  1559  
  1560  	serverConnCh := make(chan net.Conn, 1)
  1561  	tr := &Transport{
  1562  		Dial: func(network, addr string) (net.Conn, error) {
  1563  			cc, sc := net.Pipe()
  1564  			serverConnCh <- sc
  1565  			return cc, nil
  1566  		},
  1567  	}
  1568  	defer tr.CloseIdleConnections()
  1569  	errc := make(chan error, 1)
  1570  	req, _ := NewRequest("GET", "http://example.com/", nil)
  1571  	go func() {
  1572  		_, err := tr.RoundTrip(req)
  1573  		errc <- err
  1574  	}()
  1575  
  1576  	sc := <-serverConnCh
  1577  	verb := make([]byte, 3)
  1578  	if _, err := io.ReadFull(sc, verb); err != nil {
  1579  		t.Errorf("Error reading HTTP verb from server: %v", err)
  1580  	}
  1581  	if string(verb) != "GET" {
  1582  		t.Errorf("server received %q; want GET", verb)
  1583  	}
  1584  	defer sc.Close()
  1585  
  1586  	tr.CancelRequest(req)
  1587  
  1588  	err := <-errc
  1589  	if err == nil {
  1590  		t.Fatalf("unexpected success from RoundTrip")
  1591  	}
  1592  	if err != ExportErrRequestCanceled {
  1593  		t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err)
  1594  	}
  1595  }
  1596  
  1597  // golang.org/issue/3672 -- Client can't close HTTP stream
  1598  // Calling Close on a Response.Body used to just read until EOF.
  1599  // Now it actually closes the TCP connection.
  1600  func TestTransportCloseResponseBody(t *testing.T) {
  1601  	defer afterTest(t)
  1602  	writeErr := make(chan error, 1)
  1603  	msg := []byte("young\n")
  1604  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1605  		for {
  1606  			_, err := w.Write(msg)
  1607  			if err != nil {
  1608  				writeErr <- err
  1609  				return
  1610  			}
  1611  			w.(Flusher).Flush()
  1612  		}
  1613  	}))
  1614  	defer ts.Close()
  1615  
  1616  	tr := &Transport{}
  1617  	defer tr.CloseIdleConnections()
  1618  	c := &Client{Transport: tr}
  1619  
  1620  	req, _ := NewRequest("GET", ts.URL, nil)
  1621  	defer tr.CancelRequest(req)
  1622  
  1623  	res, err := c.Do(req)
  1624  	if err != nil {
  1625  		t.Fatal(err)
  1626  	}
  1627  
  1628  	const repeats = 3
  1629  	buf := make([]byte, len(msg)*repeats)
  1630  	want := bytes.Repeat(msg, repeats)
  1631  
  1632  	_, err = io.ReadFull(res.Body, buf)
  1633  	if err != nil {
  1634  		t.Fatal(err)
  1635  	}
  1636  	if !bytes.Equal(buf, want) {
  1637  		t.Fatalf("read %q; want %q", buf, want)
  1638  	}
  1639  	didClose := make(chan error, 1)
  1640  	go func() {
  1641  		didClose <- res.Body.Close()
  1642  	}()
  1643  	select {
  1644  	case err := <-didClose:
  1645  		if err != nil {
  1646  			t.Errorf("Close = %v", err)
  1647  		}
  1648  	case <-time.After(10 * time.Second):
  1649  		t.Fatal("too long waiting for close")
  1650  	}
  1651  	select {
  1652  	case err := <-writeErr:
  1653  		if err == nil {
  1654  			t.Errorf("expected non-nil write error")
  1655  		}
  1656  	case <-time.After(10 * time.Second):
  1657  		t.Fatal("too long waiting for write error")
  1658  	}
  1659  }
  1660  
  1661  type fooProto struct{}
  1662  
  1663  func (fooProto) RoundTrip(req *Request) (*Response, error) {
  1664  	res := &Response{
  1665  		Status:     "200 OK",
  1666  		StatusCode: 200,
  1667  		Header:     make(Header),
  1668  		Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
  1669  	}
  1670  	return res, nil
  1671  }
  1672  
  1673  func TestTransportAltProto(t *testing.T) {
  1674  	defer afterTest(t)
  1675  	tr := &Transport{}
  1676  	c := &Client{Transport: tr}
  1677  	tr.RegisterProtocol("foo", fooProto{})
  1678  	res, err := c.Get("foo://bar.com/path")
  1679  	if err != nil {
  1680  		t.Fatal(err)
  1681  	}
  1682  	bodyb, err := ioutil.ReadAll(res.Body)
  1683  	if err != nil {
  1684  		t.Fatal(err)
  1685  	}
  1686  	body := string(bodyb)
  1687  	if e := "You wanted foo://bar.com/path"; body != e {
  1688  		t.Errorf("got response %q, want %q", body, e)
  1689  	}
  1690  }
  1691  
  1692  func TestTransportNoHost(t *testing.T) {
  1693  	defer afterTest(t)
  1694  	tr := &Transport{}
  1695  	_, err := tr.RoundTrip(&Request{
  1696  		Header: make(Header),
  1697  		URL: &url.URL{
  1698  			Scheme: "http",
  1699  		},
  1700  	})
  1701  	want := "http: no Host in request URL"
  1702  	if got := fmt.Sprint(err); got != want {
  1703  		t.Errorf("error = %v; want %q", err, want)
  1704  	}
  1705  }
  1706  
  1707  func TestTransportSocketLateBinding(t *testing.T) {
  1708  	defer afterTest(t)
  1709  
  1710  	mux := NewServeMux()
  1711  	fooGate := make(chan bool, 1)
  1712  	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
  1713  		w.Header().Set("foo-ipport", r.RemoteAddr)
  1714  		w.(Flusher).Flush()
  1715  		<-fooGate
  1716  	})
  1717  	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
  1718  		w.Header().Set("bar-ipport", r.RemoteAddr)
  1719  	})
  1720  	ts := httptest.NewServer(mux)
  1721  	defer ts.Close()
  1722  
  1723  	dialGate := make(chan bool, 1)
  1724  	tr := &Transport{
  1725  		Dial: func(n, addr string) (net.Conn, error) {
  1726  			if <-dialGate {
  1727  				return net.Dial(n, addr)
  1728  			}
  1729  			return nil, errors.New("manually closed")
  1730  		},
  1731  		DisableKeepAlives: false,
  1732  	}
  1733  	defer tr.CloseIdleConnections()
  1734  	c := &Client{
  1735  		Transport: tr,
  1736  	}
  1737  
  1738  	dialGate <- true // only allow one dial
  1739  	fooRes, err := c.Get(ts.URL + "/foo")
  1740  	if err != nil {
  1741  		t.Fatal(err)
  1742  	}
  1743  	fooAddr := fooRes.Header.Get("foo-ipport")
  1744  	if fooAddr == "" {
  1745  		t.Fatal("No addr on /foo request")
  1746  	}
  1747  	time.AfterFunc(200*time.Millisecond, func() {
  1748  		// let the foo response finish so we can use its
  1749  		// connection for /bar
  1750  		fooGate <- true
  1751  		io.Copy(ioutil.Discard, fooRes.Body)
  1752  		fooRes.Body.Close()
  1753  	})
  1754  
  1755  	barRes, err := c.Get(ts.URL + "/bar")
  1756  	if err != nil {
  1757  		t.Fatal(err)
  1758  	}
  1759  	barAddr := barRes.Header.Get("bar-ipport")
  1760  	if barAddr != fooAddr {
  1761  		t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
  1762  	}
  1763  	barRes.Body.Close()
  1764  	dialGate <- false
  1765  }
  1766  
  1767  // Issue 2184
  1768  func TestTransportReading100Continue(t *testing.T) {
  1769  	defer afterTest(t)
  1770  
  1771  	const numReqs = 5
  1772  	reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
  1773  	reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
  1774  
  1775  	send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
  1776  		defer w.Close()
  1777  		defer r.Close()
  1778  		br := bufio.NewReader(r)
  1779  		n := 0
  1780  		for {
  1781  			n++
  1782  			req, err := ReadRequest(br)
  1783  			if err == io.EOF {
  1784  				return
  1785  			}
  1786  			if err != nil {
  1787  				t.Error(err)
  1788  				return
  1789  			}
  1790  			slurp, err := ioutil.ReadAll(req.Body)
  1791  			if err != nil {
  1792  				t.Errorf("Server request body slurp: %v", err)
  1793  				return
  1794  			}
  1795  			id := req.Header.Get("Request-Id")
  1796  			resCode := req.Header.Get("X-Want-Response-Code")
  1797  			if resCode == "" {
  1798  				resCode = "100 Continue"
  1799  				if string(slurp) != reqBody(n) {
  1800  					t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
  1801  				}
  1802  			}
  1803  			body := fmt.Sprintf("Response number %d", n)
  1804  			v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
  1805  Date: Thu, 28 Feb 2013 17:55:41 GMT
  1806  
  1807  HTTP/1.1 200 OK
  1808  Content-Type: text/html
  1809  Echo-Request-Id: %s
  1810  Content-Length: %d
  1811  
  1812  %s`, resCode, id, len(body), body), "\n", "\r\n", -1))
  1813  			w.Write(v)
  1814  			if id == reqID(numReqs) {
  1815  				return
  1816  			}
  1817  		}
  1818  
  1819  	}
  1820  
  1821  	tr := &Transport{
  1822  		Dial: func(n, addr string) (net.Conn, error) {
  1823  			sr, sw := io.Pipe() // server read/write
  1824  			cr, cw := io.Pipe() // client read/write
  1825  			conn := &rwTestConn{
  1826  				Reader: cr,
  1827  				Writer: sw,
  1828  				closeFunc: func() error {
  1829  					sw.Close()
  1830  					cw.Close()
  1831  					return nil
  1832  				},
  1833  			}
  1834  			go send100Response(cw, sr)
  1835  			return conn, nil
  1836  		},
  1837  		DisableKeepAlives: false,
  1838  	}
  1839  	defer tr.CloseIdleConnections()
  1840  	c := &Client{Transport: tr}
  1841  
  1842  	testResponse := func(req *Request, name string, wantCode int) {
  1843  		res, err := c.Do(req)
  1844  		if err != nil {
  1845  			t.Fatalf("%s: Do: %v", name, err)
  1846  		}
  1847  		if res.StatusCode != wantCode {
  1848  			t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
  1849  		}
  1850  		if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
  1851  			t.Errorf("%s: response id %q != request id %q", name, idBack, id)
  1852  		}
  1853  		_, err = ioutil.ReadAll(res.Body)
  1854  		if err != nil {
  1855  			t.Fatalf("%s: Slurp error: %v", name, err)
  1856  		}
  1857  	}
  1858  
  1859  	// Few 100 responses, making sure we're not off-by-one.
  1860  	for i := 1; i <= numReqs; i++ {
  1861  		req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
  1862  		req.Header.Set("Request-Id", reqID(i))
  1863  		testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
  1864  	}
  1865  
  1866  	// And some other informational 1xx but non-100 responses, to test
  1867  	// we return them but don't re-use the connection.
  1868  	for i := 1; i <= numReqs; i++ {
  1869  		req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i)))
  1870  		req.Header.Set("X-Want-Response-Code", "123 Sesame Street")
  1871  		testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123)
  1872  	}
  1873  }
  1874  
  1875  type proxyFromEnvTest struct {
  1876  	req string // URL to fetch; blank means "http://example.com"
  1877  
  1878  	env      string // HTTP_PROXY
  1879  	httpsenv string // HTTPS_PROXY
  1880  	noenv    string // NO_RPXY
  1881  
  1882  	want    string
  1883  	wanterr error
  1884  }
  1885  
  1886  func (t proxyFromEnvTest) String() string {
  1887  	var buf bytes.Buffer
  1888  	space := func() {
  1889  		if buf.Len() > 0 {
  1890  			buf.WriteByte(' ')
  1891  		}
  1892  	}
  1893  	if t.env != "" {
  1894  		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
  1895  	}
  1896  	if t.httpsenv != "" {
  1897  		space()
  1898  		fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv)
  1899  	}
  1900  	if t.noenv != "" {
  1901  		space()
  1902  		fmt.Fprintf(&buf, "no_proxy=%q", t.noenv)
  1903  	}
  1904  	req := "http://example.com"
  1905  	if t.req != "" {
  1906  		req = t.req
  1907  	}
  1908  	space()
  1909  	fmt.Fprintf(&buf, "req=%q", req)
  1910  	return strings.TrimSpace(buf.String())
  1911  }
  1912  
  1913  var proxyFromEnvTests = []proxyFromEnvTest{
  1914  	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  1915  	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
  1916  	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
  1917  	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
  1918  	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  1919  	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
  1920  
  1921  	// Don't use secure for http
  1922  	{req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"},
  1923  	// Use secure for https.
  1924  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"},
  1925  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"},
  1926  
  1927  	{want: "<nil>"},
  1928  
  1929  	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  1930  	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  1931  	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  1932  	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
  1933  	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  1934  }
  1935  
  1936  func TestProxyFromEnvironment(t *testing.T) {
  1937  	ResetProxyEnv()
  1938  	for _, tt := range proxyFromEnvTests {
  1939  		os.Setenv("HTTP_PROXY", tt.env)
  1940  		os.Setenv("HTTPS_PROXY", tt.httpsenv)
  1941  		os.Setenv("NO_PROXY", tt.noenv)
  1942  		ResetCachedEnvironment()
  1943  		reqURL := tt.req
  1944  		if reqURL == "" {
  1945  			reqURL = "http://example.com"
  1946  		}
  1947  		req, _ := NewRequest("GET", reqURL, nil)
  1948  		url, err := ProxyFromEnvironment(req)
  1949  		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
  1950  			t.Errorf("%v: got error = %q, want %q", tt, g, e)
  1951  			continue
  1952  		}
  1953  		if got := fmt.Sprintf("%s", url); got != tt.want {
  1954  			t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
  1955  		}
  1956  	}
  1957  }
  1958  
  1959  func TestIdleConnChannelLeak(t *testing.T) {
  1960  	var mu sync.Mutex
  1961  	var n int
  1962  
  1963  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1964  		mu.Lock()
  1965  		n++
  1966  		mu.Unlock()
  1967  	}))
  1968  	defer ts.Close()
  1969  
  1970  	const nReqs = 5
  1971  	didRead := make(chan bool, nReqs)
  1972  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
  1973  	defer SetReadLoopBeforeNextReadHook(nil)
  1974  
  1975  	tr := &Transport{
  1976  		Dial: func(netw, addr string) (net.Conn, error) {
  1977  			return net.Dial(netw, ts.Listener.Addr().String())
  1978  		},
  1979  	}
  1980  	defer tr.CloseIdleConnections()
  1981  
  1982  	c := &Client{Transport: tr}
  1983  
  1984  	// First, without keep-alives.
  1985  	for _, disableKeep := range []bool{true, false} {
  1986  		tr.DisableKeepAlives = disableKeep
  1987  		for i := 0; i < nReqs; i++ {
  1988  			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
  1989  			if err != nil {
  1990  				t.Fatal(err)
  1991  			}
  1992  			// Note: no res.Body.Close is needed here, since the
  1993  			// response Content-Length is zero. Perhaps the test
  1994  			// should be more explicit and use a HEAD, but tests
  1995  			// elsewhere guarantee that zero byte responses generate
  1996  			// a "Content-Length: 0" instead of chunking.
  1997  		}
  1998  
  1999  		// At this point, each of the 5 Transport.readLoop goroutines
  2000  		// are scheduling noting that there are no response bodies (see
  2001  		// earlier comment), and are then calling putIdleConn, which
  2002  		// decrements this count. Usually that happens quickly, which is
  2003  		// why this test has seemed to work for ages. But it's still
  2004  		// racey: we have wait for them to finish first. See Issue 10427
  2005  		for i := 0; i < nReqs; i++ {
  2006  			<-didRead
  2007  		}
  2008  
  2009  		if got := tr.IdleConnChMapSizeForTesting(); got != 0 {
  2010  			t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
  2011  		}
  2012  	}
  2013  }
  2014  
  2015  // Verify the status quo: that the Client.Post function coerces its
  2016  // body into a ReadCloser if it's a Closer, and that the Transport
  2017  // then closes it.
  2018  func TestTransportClosesRequestBody(t *testing.T) {
  2019  	defer afterTest(t)
  2020  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2021  		io.Copy(ioutil.Discard, r.Body)
  2022  	}))
  2023  	defer ts.Close()
  2024  
  2025  	tr := &Transport{}
  2026  	defer tr.CloseIdleConnections()
  2027  	cl := &Client{Transport: tr}
  2028  
  2029  	closes := 0
  2030  
  2031  	res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
  2032  	if err != nil {
  2033  		t.Fatal(err)
  2034  	}
  2035  	res.Body.Close()
  2036  	if closes != 1 {
  2037  		t.Errorf("closes = %d; want 1", closes)
  2038  	}
  2039  }
  2040  
  2041  func TestTransportTLSHandshakeTimeout(t *testing.T) {
  2042  	defer afterTest(t)
  2043  	if testing.Short() {
  2044  		t.Skip("skipping in short mode")
  2045  	}
  2046  	ln := newLocalListener(t)
  2047  	defer ln.Close()
  2048  	testdonec := make(chan struct{})
  2049  	defer close(testdonec)
  2050  
  2051  	go func() {
  2052  		c, err := ln.Accept()
  2053  		if err != nil {
  2054  			t.Error(err)
  2055  			return
  2056  		}
  2057  		<-testdonec
  2058  		c.Close()
  2059  	}()
  2060  
  2061  	getdonec := make(chan struct{})
  2062  	go func() {
  2063  		defer close(getdonec)
  2064  		tr := &Transport{
  2065  			Dial: func(_, _ string) (net.Conn, error) {
  2066  				return net.Dial("tcp", ln.Addr().String())
  2067  			},
  2068  			TLSHandshakeTimeout: 250 * time.Millisecond,
  2069  		}
  2070  		cl := &Client{Transport: tr}
  2071  		_, err := cl.Get("https://dummy.tld/")
  2072  		if err == nil {
  2073  			t.Error("expected error")
  2074  			return
  2075  		}
  2076  		ue, ok := err.(*url.Error)
  2077  		if !ok {
  2078  			t.Errorf("expected url.Error; got %#v", err)
  2079  			return
  2080  		}
  2081  		ne, ok := ue.Err.(net.Error)
  2082  		if !ok {
  2083  			t.Errorf("expected net.Error; got %#v", err)
  2084  			return
  2085  		}
  2086  		if !ne.Timeout() {
  2087  			t.Errorf("expected timeout error; got %v", err)
  2088  		}
  2089  		if !strings.Contains(err.Error(), "handshake timeout") {
  2090  			t.Errorf("expected 'handshake timeout' in error; got %v", err)
  2091  		}
  2092  	}()
  2093  	select {
  2094  	case <-getdonec:
  2095  	case <-time.After(5 * time.Second):
  2096  		t.Error("test timeout; TLS handshake hung?")
  2097  	}
  2098  }
  2099  
  2100  // Trying to repro golang.org/issue/3514
  2101  func TestTLSServerClosesConnection(t *testing.T) {
  2102  	defer afterTest(t)
  2103  	if runtime.GOOS == "windows" {
  2104  		t.Skip("skipping flaky test on Windows; golang.org/issue/7634")
  2105  	}
  2106  	closedc := make(chan bool, 1)
  2107  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2108  		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
  2109  			conn, _, _ := w.(Hijacker).Hijack()
  2110  			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
  2111  			conn.Close()
  2112  			closedc <- true
  2113  			return
  2114  		}
  2115  		fmt.Fprintf(w, "hello")
  2116  	}))
  2117  	defer ts.Close()
  2118  	tr := &Transport{
  2119  		TLSClientConfig: &tls.Config{
  2120  			InsecureSkipVerify: true,
  2121  		},
  2122  	}
  2123  	defer tr.CloseIdleConnections()
  2124  	client := &Client{Transport: tr}
  2125  
  2126  	var nSuccess = 0
  2127  	var errs []error
  2128  	const trials = 20
  2129  	for i := 0; i < trials; i++ {
  2130  		tr.CloseIdleConnections()
  2131  		res, err := client.Get(ts.URL + "/keep-alive-then-die")
  2132  		if err != nil {
  2133  			t.Fatal(err)
  2134  		}
  2135  		<-closedc
  2136  		slurp, err := ioutil.ReadAll(res.Body)
  2137  		if err != nil {
  2138  			t.Fatal(err)
  2139  		}
  2140  		if string(slurp) != "foo" {
  2141  			t.Errorf("Got %q, want foo", slurp)
  2142  		}
  2143  
  2144  		// Now try again and see if we successfully
  2145  		// pick a new connection.
  2146  		res, err = client.Get(ts.URL + "/")
  2147  		if err != nil {
  2148  			errs = append(errs, err)
  2149  			continue
  2150  		}
  2151  		slurp, err = ioutil.ReadAll(res.Body)
  2152  		if err != nil {
  2153  			errs = append(errs, err)
  2154  			continue
  2155  		}
  2156  		nSuccess++
  2157  	}
  2158  	if nSuccess > 0 {
  2159  		t.Logf("successes = %d of %d", nSuccess, trials)
  2160  	} else {
  2161  		t.Errorf("All runs failed:")
  2162  	}
  2163  	for _, err := range errs {
  2164  		t.Logf("  err: %v", err)
  2165  	}
  2166  }
  2167  
  2168  // byteFromChanReader is an io.Reader that reads a single byte at a
  2169  // time from the channel.  When the channel is closed, the reader
  2170  // returns io.EOF.
  2171  type byteFromChanReader chan byte
  2172  
  2173  func (c byteFromChanReader) Read(p []byte) (n int, err error) {
  2174  	if len(p) == 0 {
  2175  		return
  2176  	}
  2177  	b, ok := <-c
  2178  	if !ok {
  2179  		return 0, io.EOF
  2180  	}
  2181  	p[0] = b
  2182  	return 1, nil
  2183  }
  2184  
  2185  // Verifies that the Transport doesn't reuse a connection in the case
  2186  // where the server replies before the request has been fully
  2187  // written. We still honor that reply (see TestIssue3595), but don't
  2188  // send future requests on the connection because it's then in a
  2189  // questionable state.
  2190  // golang.org/issue/7569
  2191  func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
  2192  	defer afterTest(t)
  2193  	var sconn struct {
  2194  		sync.Mutex
  2195  		c net.Conn
  2196  	}
  2197  	var getOkay bool
  2198  	closeConn := func() {
  2199  		sconn.Lock()
  2200  		defer sconn.Unlock()
  2201  		if sconn.c != nil {
  2202  			sconn.c.Close()
  2203  			sconn.c = nil
  2204  			if !getOkay {
  2205  				t.Logf("Closed server connection")
  2206  			}
  2207  		}
  2208  	}
  2209  	defer closeConn()
  2210  
  2211  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2212  		if r.Method == "GET" {
  2213  			io.WriteString(w, "bar")
  2214  			return
  2215  		}
  2216  		conn, _, _ := w.(Hijacker).Hijack()
  2217  		sconn.Lock()
  2218  		sconn.c = conn
  2219  		sconn.Unlock()
  2220  		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
  2221  		go io.Copy(ioutil.Discard, conn)
  2222  	}))
  2223  	defer ts.Close()
  2224  	tr := &Transport{}
  2225  	defer tr.CloseIdleConnections()
  2226  	client := &Client{Transport: tr}
  2227  
  2228  	const bodySize = 256 << 10
  2229  	finalBit := make(byteFromChanReader, 1)
  2230  	req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
  2231  	req.ContentLength = bodySize
  2232  	res, err := client.Do(req)
  2233  	if err := wantBody(res, err, "foo"); err != nil {
  2234  		t.Errorf("POST response: %v", err)
  2235  	}
  2236  	donec := make(chan bool)
  2237  	go func() {
  2238  		defer close(donec)
  2239  		res, err = client.Get(ts.URL)
  2240  		if err := wantBody(res, err, "bar"); err != nil {
  2241  			t.Errorf("GET response: %v", err)
  2242  			return
  2243  		}
  2244  		getOkay = true // suppress test noise
  2245  	}()
  2246  	time.AfterFunc(5*time.Second, closeConn)
  2247  	select {
  2248  	case <-donec:
  2249  		finalBit <- 'x' // unblock the writeloop of the first Post
  2250  		close(finalBit)
  2251  	case <-time.After(7 * time.Second):
  2252  		t.Fatal("timeout waiting for GET request to finish")
  2253  	}
  2254  }
  2255  
  2256  // Tests that we don't leak Transport persistConn.readLoop goroutines
  2257  // when a server hangs up immediately after saying it would keep-alive.
  2258  func TestTransportIssue10457(t *testing.T) {
  2259  	defer afterTest(t) // used to fail in goroutine leak check
  2260  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2261  		// Send a response with no body, keep-alive
  2262  		// (implicit), and then lie and immediately close the
  2263  		// connection. This forces the Transport's readLoop to
  2264  		// immediately Peek an io.EOF and get to the point
  2265  		// that used to hang.
  2266  		conn, _, _ := w.(Hijacker).Hijack()
  2267  		conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
  2268  		conn.Close()
  2269  	}))
  2270  	defer ts.Close()
  2271  	tr := &Transport{}
  2272  	defer tr.CloseIdleConnections()
  2273  	cl := &Client{Transport: tr}
  2274  	res, err := cl.Get(ts.URL)
  2275  	if err != nil {
  2276  		t.Fatalf("Get: %v", err)
  2277  	}
  2278  	defer res.Body.Close()
  2279  
  2280  	// Just a sanity check that we at least get the response. The real
  2281  	// test here is that the "defer afterTest" above doesn't find any
  2282  	// leaked goroutines.
  2283  	if got, want := res.Header.Get("Foo"), "Bar"; got != want {
  2284  		t.Errorf("Foo header = %q; want %q", got, want)
  2285  	}
  2286  }
  2287  
  2288  type errorReader struct {
  2289  	err error
  2290  }
  2291  
  2292  func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
  2293  
  2294  type closerFunc func() error
  2295  
  2296  func (f closerFunc) Close() error { return f() }
  2297  
  2298  // Issue 6981
  2299  func TestTransportClosesBodyOnError(t *testing.T) {
  2300  	if runtime.GOOS == "plan9" {
  2301  		t.Skip("skipping test; see https://golang.org/issue/7782")
  2302  	}
  2303  	defer afterTest(t)
  2304  	readBody := make(chan error, 1)
  2305  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2306  		_, err := ioutil.ReadAll(r.Body)
  2307  		readBody <- err
  2308  	}))
  2309  	defer ts.Close()
  2310  	fakeErr := errors.New("fake error")
  2311  	didClose := make(chan bool, 1)
  2312  	req, _ := NewRequest("POST", ts.URL, struct {
  2313  		io.Reader
  2314  		io.Closer
  2315  	}{
  2316  		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}),
  2317  		closerFunc(func() error {
  2318  			select {
  2319  			case didClose <- true:
  2320  			default:
  2321  			}
  2322  			return nil
  2323  		}),
  2324  	})
  2325  	res, err := DefaultClient.Do(req)
  2326  	if res != nil {
  2327  		defer res.Body.Close()
  2328  	}
  2329  	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
  2330  		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
  2331  	}
  2332  	select {
  2333  	case err := <-readBody:
  2334  		if err == nil {
  2335  			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
  2336  		}
  2337  	case <-time.After(5 * time.Second):
  2338  		t.Error("timeout waiting for server handler to complete")
  2339  	}
  2340  	select {
  2341  	case <-didClose:
  2342  	default:
  2343  		t.Errorf("didn't see Body.Close")
  2344  	}
  2345  }
  2346  
  2347  func TestTransportDialTLS(t *testing.T) {
  2348  	var mu sync.Mutex // guards following
  2349  	var gotReq, didDial bool
  2350  
  2351  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2352  		mu.Lock()
  2353  		gotReq = true
  2354  		mu.Unlock()
  2355  	}))
  2356  	defer ts.Close()
  2357  	tr := &Transport{
  2358  		DialTLS: func(netw, addr string) (net.Conn, error) {
  2359  			mu.Lock()
  2360  			didDial = true
  2361  			mu.Unlock()
  2362  			c, err := tls.Dial(netw, addr, &tls.Config{
  2363  				InsecureSkipVerify: true,
  2364  			})
  2365  			if err != nil {
  2366  				return nil, err
  2367  			}
  2368  			return c, c.Handshake()
  2369  		},
  2370  	}
  2371  	defer tr.CloseIdleConnections()
  2372  	client := &Client{Transport: tr}
  2373  	res, err := client.Get(ts.URL)
  2374  	if err != nil {
  2375  		t.Fatal(err)
  2376  	}
  2377  	res.Body.Close()
  2378  	mu.Lock()
  2379  	if !gotReq {
  2380  		t.Error("didn't get request")
  2381  	}
  2382  	if !didDial {
  2383  		t.Error("didn't use dial hook")
  2384  	}
  2385  }
  2386  
  2387  // Test for issue 8755
  2388  // Ensure that if a proxy returns an error, it is exposed by RoundTrip
  2389  func TestRoundTripReturnsProxyError(t *testing.T) {
  2390  	badProxy := func(*Request) (*url.URL, error) {
  2391  		return nil, errors.New("errorMessage")
  2392  	}
  2393  
  2394  	tr := &Transport{Proxy: badProxy}
  2395  
  2396  	req, _ := NewRequest("GET", "http://example.com", nil)
  2397  
  2398  	_, err := tr.RoundTrip(req)
  2399  
  2400  	if err == nil {
  2401  		t.Error("Expected proxy error to be returned by RoundTrip")
  2402  	}
  2403  }
  2404  
  2405  // tests that putting an idle conn after a call to CloseIdleConns does return it
  2406  func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
  2407  	tr := &Transport{}
  2408  	wantIdle := func(when string, n int) bool {
  2409  		got := tr.IdleConnCountForTesting("|http|example.com") // key used by PutIdleTestConn
  2410  		if got == n {
  2411  			return true
  2412  		}
  2413  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  2414  		return false
  2415  	}
  2416  	wantIdle("start", 0)
  2417  	if !tr.PutIdleTestConn() {
  2418  		t.Fatal("put failed")
  2419  	}
  2420  	if !tr.PutIdleTestConn() {
  2421  		t.Fatal("second put failed")
  2422  	}
  2423  	wantIdle("after put", 2)
  2424  	tr.CloseIdleConnections()
  2425  	if !tr.IsIdleForTesting() {
  2426  		t.Error("should be idle after CloseIdleConnections")
  2427  	}
  2428  	wantIdle("after close idle", 0)
  2429  	if tr.PutIdleTestConn() {
  2430  		t.Fatal("put didn't fail")
  2431  	}
  2432  	wantIdle("after second put", 0)
  2433  
  2434  	tr.RequestIdleConnChForTesting() // should toggle the transport out of idle mode
  2435  	if tr.IsIdleForTesting() {
  2436  		t.Error("shouldn't be idle after RequestIdleConnChForTesting")
  2437  	}
  2438  	if !tr.PutIdleTestConn() {
  2439  		t.Fatal("after re-activation")
  2440  	}
  2441  	wantIdle("after final put", 1)
  2442  }
  2443  
  2444  // This tests that an client requesting a content range won't also
  2445  // implicitly ask for gzip support. If they want that, they need to do it
  2446  // on their own.
  2447  // golang.org/issue/8923
  2448  func TestTransportRangeAndGzip(t *testing.T) {
  2449  	defer afterTest(t)
  2450  	reqc := make(chan *Request, 1)
  2451  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2452  		reqc <- r
  2453  	}))
  2454  	defer ts.Close()
  2455  
  2456  	req, _ := NewRequest("GET", ts.URL, nil)
  2457  	req.Header.Set("Range", "bytes=7-11")
  2458  	res, err := DefaultClient.Do(req)
  2459  	if err != nil {
  2460  		t.Fatal(err)
  2461  	}
  2462  
  2463  	select {
  2464  	case r := <-reqc:
  2465  		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  2466  			t.Error("Transport advertised gzip support in the Accept header")
  2467  		}
  2468  		if r.Header.Get("Range") == "" {
  2469  			t.Error("no Range in request")
  2470  		}
  2471  	case <-time.After(10 * time.Second):
  2472  		t.Fatal("timeout")
  2473  	}
  2474  	res.Body.Close()
  2475  }
  2476  
  2477  // Previously, we used to handle a logical race within RoundTrip by waiting for 100ms
  2478  // in the case of an error. Changing the order of the channel operations got rid of this
  2479  // race.
  2480  //
  2481  // In order to test that the channel op reordering works, we install a hook into the
  2482  // roundTrip function which gets called if we saw the connection go away and
  2483  // we subsequently received a response.
  2484  func TestTransportResponseCloseRace(t *testing.T) {
  2485  	if testing.Short() {
  2486  		t.Skip("skipping in short mode")
  2487  	}
  2488  	defer afterTest(t)
  2489  
  2490  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2491  	}))
  2492  	defer ts.Close()
  2493  	sawRace := false
  2494  	SetInstallConnClosedHook(func() {
  2495  		sawRace = true
  2496  	})
  2497  	defer SetInstallConnClosedHook(nil)
  2498  	tr := &Transport{
  2499  		DisableKeepAlives: true,
  2500  	}
  2501  	req, err := NewRequest("GET", ts.URL, nil)
  2502  	if err != nil {
  2503  		t.Fatal(err)
  2504  	}
  2505  	// selects are not deterministic, so do this a bunch
  2506  	// and see if we handle the logical race at least once.
  2507  	for i := 0; i < 10000; i++ {
  2508  		resp, err := tr.RoundTrip(req)
  2509  		if err != nil {
  2510  			t.Fatalf("unexpected error: %s", err)
  2511  			continue
  2512  		}
  2513  		resp.Body.Close()
  2514  		if sawRace {
  2515  			break
  2516  		}
  2517  	}
  2518  	if !sawRace {
  2519  		t.Errorf("didn't see response/connection going away race")
  2520  	}
  2521  }
  2522  
  2523  // Test for issue 10474
  2524  func TestTransportResponseCancelRace(t *testing.T) {
  2525  	defer afterTest(t)
  2526  
  2527  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2528  		// important that this response has a body.
  2529  		var b [1024]byte
  2530  		w.Write(b[:])
  2531  	}))
  2532  	defer ts.Close()
  2533  
  2534  	tr := &Transport{}
  2535  	defer tr.CloseIdleConnections()
  2536  
  2537  	req, err := NewRequest("GET", ts.URL, nil)
  2538  	if err != nil {
  2539  		t.Fatal(err)
  2540  	}
  2541  	res, err := tr.RoundTrip(req)
  2542  	if err != nil {
  2543  		t.Fatal(err)
  2544  	}
  2545  	// If we do an early close, Transport just throws the connection away and
  2546  	// doesn't reuse it. In order to trigger the bug, it has to reuse the connection
  2547  	// so read the body
  2548  	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
  2549  		t.Fatal(err)
  2550  	}
  2551  
  2552  	req2, err := NewRequest("GET", ts.URL, nil)
  2553  	if err != nil {
  2554  		t.Fatal(err)
  2555  	}
  2556  	tr.CancelRequest(req)
  2557  	res, err = tr.RoundTrip(req2)
  2558  	if err != nil {
  2559  		t.Fatal(err)
  2560  	}
  2561  	res.Body.Close()
  2562  }
  2563  
  2564  func TestTransportDialCancelRace(t *testing.T) {
  2565  	defer afterTest(t)
  2566  
  2567  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  2568  	defer ts.Close()
  2569  
  2570  	tr := &Transport{}
  2571  	defer tr.CloseIdleConnections()
  2572  
  2573  	req, err := NewRequest("GET", ts.URL, nil)
  2574  	if err != nil {
  2575  		t.Fatal(err)
  2576  	}
  2577  	SetEnterRoundTripHook(func() {
  2578  		tr.CancelRequest(req)
  2579  	})
  2580  	defer SetEnterRoundTripHook(nil)
  2581  	res, err := tr.RoundTrip(req)
  2582  	if err != ExportErrRequestCanceled {
  2583  		t.Errorf("expected canceled request error; got %v", err)
  2584  		if err == nil {
  2585  			res.Body.Close()
  2586  		}
  2587  	}
  2588  }
  2589  
  2590  // logWritesConn is a net.Conn that logs each Write call to writes
  2591  // and then proxies to w.
  2592  // It proxies Read calls to a reader it receives from rch.
  2593  type logWritesConn struct {
  2594  	net.Conn // nil. crash on use.
  2595  
  2596  	w io.Writer
  2597  
  2598  	rch <-chan io.Reader
  2599  	r   io.Reader // nil until received by rch
  2600  
  2601  	mu     sync.Mutex
  2602  	writes []string
  2603  }
  2604  
  2605  func (c *logWritesConn) Write(p []byte) (n int, err error) {
  2606  	c.mu.Lock()
  2607  	defer c.mu.Unlock()
  2608  	c.writes = append(c.writes, string(p))
  2609  	return c.w.Write(p)
  2610  }
  2611  
  2612  func (c *logWritesConn) Read(p []byte) (n int, err error) {
  2613  	if c.r == nil {
  2614  		c.r = <-c.rch
  2615  	}
  2616  	return c.r.Read(p)
  2617  }
  2618  
  2619  func (c *logWritesConn) Close() error { return nil }
  2620  
  2621  // Issue 6574
  2622  func TestTransportFlushesBodyChunks(t *testing.T) {
  2623  	defer afterTest(t)
  2624  	resBody := make(chan io.Reader, 1)
  2625  	connr, connw := io.Pipe() // connection pipe pair
  2626  	lw := &logWritesConn{
  2627  		rch: resBody,
  2628  		w:   connw,
  2629  	}
  2630  	tr := &Transport{
  2631  		Dial: func(network, addr string) (net.Conn, error) {
  2632  			return lw, nil
  2633  		},
  2634  	}
  2635  	bodyr, bodyw := io.Pipe() // body pipe pair
  2636  	go func() {
  2637  		defer bodyw.Close()
  2638  		for i := 0; i < 3; i++ {
  2639  			fmt.Fprintf(bodyw, "num%d\n", i)
  2640  		}
  2641  	}()
  2642  	resc := make(chan *Response)
  2643  	go func() {
  2644  		req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
  2645  		req.Header.Set("User-Agent", "x") // known value for test
  2646  		res, err := tr.RoundTrip(req)
  2647  		if err != nil {
  2648  			t.Errorf("RoundTrip: %v", err)
  2649  			close(resc)
  2650  			return
  2651  		}
  2652  		resc <- res
  2653  
  2654  	}()
  2655  	// Fully consume the request before checking the Write log vs. want.
  2656  	req, err := ReadRequest(bufio.NewReader(connr))
  2657  	if err != nil {
  2658  		t.Fatal(err)
  2659  	}
  2660  	io.Copy(ioutil.Discard, req.Body)
  2661  
  2662  	// Unblock the transport's roundTrip goroutine.
  2663  	resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
  2664  	res, ok := <-resc
  2665  	if !ok {
  2666  		return
  2667  	}
  2668  	defer res.Body.Close()
  2669  
  2670  	want := []string{
  2671  		// Because Request.ContentLength = 0, the body is sniffed for 1 byte to determine whether there's content.
  2672  		// That explains the initial "num0" being split into "n" and "um0".
  2673  		// The first byte is included with the request headers Write. Perhaps in the future
  2674  		// we will want to flush the headers out early if the first byte of the request body is
  2675  		// taking a long time to arrive. But not yet.
  2676  		"POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n" +
  2677  			"1\r\nn\r\n",
  2678  		"4\r\num0\n\r\n",
  2679  		"5\r\nnum1\n\r\n",
  2680  		"5\r\nnum2\n\r\n",
  2681  		"0\r\n\r\n",
  2682  	}
  2683  	if !reflect.DeepEqual(lw.writes, want) {
  2684  		t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
  2685  	}
  2686  }
  2687  
  2688  // Issue 11745.
  2689  func TestTransportPrefersResponseOverWriteError(t *testing.T) {
  2690  	if testing.Short() {
  2691  		t.Skip("skipping in short mode")
  2692  	}
  2693  	defer afterTest(t)
  2694  	const contentLengthLimit = 1024 * 1024 // 1MB
  2695  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2696  		if r.ContentLength >= contentLengthLimit {
  2697  			w.WriteHeader(StatusBadRequest)
  2698  			r.Body.Close()
  2699  			return
  2700  		}
  2701  		w.WriteHeader(StatusOK)
  2702  	}))
  2703  	defer ts.Close()
  2704  
  2705  	fail := 0
  2706  	count := 100
  2707  	bigBody := strings.Repeat("a", contentLengthLimit*2)
  2708  	for i := 0; i < count; i++ {
  2709  		req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
  2710  		if err != nil {
  2711  			t.Fatal(err)
  2712  		}
  2713  		tr := new(Transport)
  2714  		defer tr.CloseIdleConnections()
  2715  		client := &Client{Transport: tr}
  2716  		resp, err := client.Do(req)
  2717  		if err != nil {
  2718  			fail++
  2719  			t.Logf("%d = %#v", i, err)
  2720  			if ue, ok := err.(*url.Error); ok {
  2721  				t.Logf("urlErr = %#v", ue.Err)
  2722  				if ne, ok := ue.Err.(*net.OpError); ok {
  2723  					t.Logf("netOpError = %#v", ne.Err)
  2724  				}
  2725  			}
  2726  		} else {
  2727  			resp.Body.Close()
  2728  			if resp.StatusCode != 400 {
  2729  				t.Errorf("Expected status code 400, got %v", resp.Status)
  2730  			}
  2731  		}
  2732  	}
  2733  	if fail > 0 {
  2734  		t.Errorf("Failed %v out of %v\n", fail, count)
  2735  	}
  2736  }
  2737  
  2738  func wantBody(res *Response, err error, want string) error {
  2739  	if err != nil {
  2740  		return err
  2741  	}
  2742  	slurp, err := ioutil.ReadAll(res.Body)
  2743  	if err != nil {
  2744  		return fmt.Errorf("error reading body: %v", err)
  2745  	}
  2746  	if string(slurp) != want {
  2747  		return fmt.Errorf("body = %q; want %q", slurp, want)
  2748  	}
  2749  	if err := res.Body.Close(); err != nil {
  2750  		return fmt.Errorf("body Close = %v", err)
  2751  	}
  2752  	return nil
  2753  }
  2754  
  2755  func newLocalListener(t *testing.T) net.Listener {
  2756  	ln, err := net.Listen("tcp", "127.0.0.1:0")
  2757  	if err != nil {
  2758  		ln, err = net.Listen("tcp6", "[::1]:0")
  2759  	}
  2760  	if err != nil {
  2761  		t.Fatal(err)
  2762  	}
  2763  	return ln
  2764  }
  2765  
  2766  type countCloseReader struct {
  2767  	n *int
  2768  	io.Reader
  2769  }
  2770  
  2771  func (cr countCloseReader) Close() error {
  2772  	(*cr.n)++
  2773  	return nil
  2774  }
  2775  
  2776  // rgz is a gzip quine that uncompresses to itself.
  2777  var rgz = []byte{
  2778  	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  2779  	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  2780  	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  2781  	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  2782  	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  2783  	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  2784  	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  2785  	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  2786  	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  2787  	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  2788  	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  2789  	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  2790  	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  2791  	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  2792  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  2793  	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  2794  	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  2795  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  2796  	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  2797  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  2798  	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  2799  	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  2800  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  2801  	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  2802  	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  2803  	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  2804  	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  2805  	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  2806  	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  2807  	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  2808  	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  2809  	0x00, 0x00,
  2810  }