github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/src/net/http/transport_test.go (about)

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