github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/src/net/http/transport_test.go (about)

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