github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/pkg/net/http/transport_test.go (about)

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