github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/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  // More tests are in clientserver_test.go (for things testing both client & server for both
     8  // HTTP/1 and HTTP/2). This
     9  
    10  package http_test
    11  
    12  import (
    13  	"bufio"
    14  	"bytes"
    15  	"compress/gzip"
    16  	"context"
    17  	"crypto/rand"
    18  	"crypto/tls"
    19  	"errors"
    20  	"fmt"
    21  	"internal/nettrace"
    22  	"internal/testenv"
    23  	"io"
    24  	"io/ioutil"
    25  	"log"
    26  	"net"
    27  	. "net/http"
    28  	"net/http/httptest"
    29  	"net/http/httptrace"
    30  	"net/http/httputil"
    31  	"net/http/internal"
    32  	"net/url"
    33  	"os"
    34  	"reflect"
    35  	"runtime"
    36  	"strconv"
    37  	"strings"
    38  	"sync"
    39  	"testing"
    40  	"time"
    41  )
    42  
    43  // TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
    44  //       and then verify that the final 2 responses get errors back.
    45  
    46  // hostPortHandler writes back the client's "host:port".
    47  var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
    48  	if r.FormValue("close") == "true" {
    49  		w.Header().Set("Connection", "close")
    50  	}
    51  	w.Header().Set("X-Saw-Close", fmt.Sprint(r.Close))
    52  	w.Write([]byte(r.RemoteAddr))
    53  })
    54  
    55  // testCloseConn is a net.Conn tracked by a testConnSet.
    56  type testCloseConn struct {
    57  	net.Conn
    58  	set *testConnSet
    59  }
    60  
    61  func (c *testCloseConn) Close() error {
    62  	c.set.remove(c)
    63  	return c.Conn.Close()
    64  }
    65  
    66  // testConnSet tracks a set of TCP connections and whether they've
    67  // been closed.
    68  type testConnSet struct {
    69  	t      *testing.T
    70  	mu     sync.Mutex // guards closed and list
    71  	closed map[net.Conn]bool
    72  	list   []net.Conn // in order created
    73  }
    74  
    75  func (tcs *testConnSet) insert(c net.Conn) {
    76  	tcs.mu.Lock()
    77  	defer tcs.mu.Unlock()
    78  	tcs.closed[c] = false
    79  	tcs.list = append(tcs.list, c)
    80  }
    81  
    82  func (tcs *testConnSet) remove(c net.Conn) {
    83  	tcs.mu.Lock()
    84  	defer tcs.mu.Unlock()
    85  	tcs.closed[c] = true
    86  }
    87  
    88  // some tests use this to manage raw tcp connections for later inspection
    89  func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) {
    90  	connSet := &testConnSet{
    91  		t:      t,
    92  		closed: make(map[net.Conn]bool),
    93  	}
    94  	dial := func(n, addr string) (net.Conn, error) {
    95  		c, err := net.Dial(n, addr)
    96  		if err != nil {
    97  			return nil, err
    98  		}
    99  		tc := &testCloseConn{c, connSet}
   100  		connSet.insert(tc)
   101  		return tc, nil
   102  	}
   103  	return connSet, dial
   104  }
   105  
   106  func (tcs *testConnSet) check(t *testing.T) {
   107  	tcs.mu.Lock()
   108  	defer tcs.mu.Unlock()
   109  	for i := 4; i >= 0; i-- {
   110  		for i, c := range tcs.list {
   111  			if tcs.closed[c] {
   112  				continue
   113  			}
   114  			if i != 0 {
   115  				tcs.mu.Unlock()
   116  				time.Sleep(50 * time.Millisecond)
   117  				tcs.mu.Lock()
   118  				continue
   119  			}
   120  			t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list))
   121  		}
   122  	}
   123  }
   124  
   125  // Two subsequent requests and verify their response is the same.
   126  // The response from the server is our own IP:port
   127  func TestTransportKeepAlives(t *testing.T) {
   128  	defer afterTest(t)
   129  	ts := httptest.NewServer(hostPortHandler)
   130  	defer ts.Close()
   131  
   132  	for _, disableKeepAlive := range []bool{false, true} {
   133  		tr := &Transport{DisableKeepAlives: disableKeepAlive}
   134  		defer tr.CloseIdleConnections()
   135  		c := &Client{Transport: tr}
   136  
   137  		fetch := func(n int) string {
   138  			res, err := c.Get(ts.URL)
   139  			if err != nil {
   140  				t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
   141  			}
   142  			body, err := ioutil.ReadAll(res.Body)
   143  			if err != nil {
   144  				t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
   145  			}
   146  			return string(body)
   147  		}
   148  
   149  		body1 := fetch(1)
   150  		body2 := fetch(2)
   151  
   152  		bodiesDiffer := body1 != body2
   153  		if bodiesDiffer != disableKeepAlive {
   154  			t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   155  				disableKeepAlive, bodiesDiffer, body1, body2)
   156  		}
   157  	}
   158  }
   159  
   160  func TestTransportConnectionCloseOnResponse(t *testing.T) {
   161  	defer afterTest(t)
   162  	ts := httptest.NewServer(hostPortHandler)
   163  	defer ts.Close()
   164  
   165  	connSet, testDial := makeTestDial(t)
   166  
   167  	for _, connectionClose := range []bool{false, true} {
   168  		tr := &Transport{
   169  			Dial: testDial,
   170  		}
   171  		c := &Client{Transport: tr}
   172  
   173  		fetch := func(n int) string {
   174  			req := new(Request)
   175  			var err error
   176  			req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
   177  			if err != nil {
   178  				t.Fatalf("URL parse error: %v", err)
   179  			}
   180  			req.Method = "GET"
   181  			req.Proto = "HTTP/1.1"
   182  			req.ProtoMajor = 1
   183  			req.ProtoMinor = 1
   184  
   185  			res, err := c.Do(req)
   186  			if err != nil {
   187  				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
   188  			}
   189  			defer res.Body.Close()
   190  			body, err := ioutil.ReadAll(res.Body)
   191  			if err != nil {
   192  				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
   193  			}
   194  			return string(body)
   195  		}
   196  
   197  		body1 := fetch(1)
   198  		body2 := fetch(2)
   199  		bodiesDiffer := body1 != body2
   200  		if bodiesDiffer != connectionClose {
   201  			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   202  				connectionClose, bodiesDiffer, body1, body2)
   203  		}
   204  
   205  		tr.CloseIdleConnections()
   206  	}
   207  
   208  	connSet.check(t)
   209  }
   210  
   211  func TestTransportConnectionCloseOnRequest(t *testing.T) {
   212  	defer afterTest(t)
   213  	ts := httptest.NewServer(hostPortHandler)
   214  	defer ts.Close()
   215  
   216  	connSet, testDial := makeTestDial(t)
   217  
   218  	for _, connectionClose := range []bool{false, true} {
   219  		tr := &Transport{
   220  			Dial: testDial,
   221  		}
   222  		c := &Client{Transport: tr}
   223  
   224  		fetch := func(n int) string {
   225  			req := new(Request)
   226  			var err error
   227  			req.URL, err = url.Parse(ts.URL)
   228  			if err != nil {
   229  				t.Fatalf("URL parse error: %v", err)
   230  			}
   231  			req.Method = "GET"
   232  			req.Proto = "HTTP/1.1"
   233  			req.ProtoMajor = 1
   234  			req.ProtoMinor = 1
   235  			req.Close = connectionClose
   236  
   237  			res, err := c.Do(req)
   238  			if err != nil {
   239  				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
   240  			}
   241  			if got, want := res.Header.Get("X-Saw-Close"), fmt.Sprint(connectionClose); got != want {
   242  				t.Errorf("For connectionClose = %v; handler's X-Saw-Close was %v; want %v",
   243  					connectionClose, got, !connectionClose)
   244  			}
   245  			body, err := ioutil.ReadAll(res.Body)
   246  			if err != nil {
   247  				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
   248  			}
   249  			return string(body)
   250  		}
   251  
   252  		body1 := fetch(1)
   253  		body2 := fetch(2)
   254  		bodiesDiffer := body1 != body2
   255  		if bodiesDiffer != connectionClose {
   256  			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   257  				connectionClose, bodiesDiffer, body1, body2)
   258  		}
   259  
   260  		tr.CloseIdleConnections()
   261  	}
   262  
   263  	connSet.check(t)
   264  }
   265  
   266  // if the Transport's DisableKeepAlives is set, all requests should
   267  // send Connection: close.
   268  // HTTP/1-only (Connection: close doesn't exist in h2)
   269  func TestTransportConnectionCloseOnRequestDisableKeepAlive(t *testing.T) {
   270  	defer afterTest(t)
   271  	ts := httptest.NewServer(hostPortHandler)
   272  	defer ts.Close()
   273  
   274  	tr := &Transport{
   275  		DisableKeepAlives: true,
   276  	}
   277  	c := &Client{Transport: tr}
   278  	res, err := c.Get(ts.URL)
   279  	if err != nil {
   280  		t.Fatal(err)
   281  	}
   282  	res.Body.Close()
   283  	if res.Header.Get("X-Saw-Close") != "true" {
   284  		t.Errorf("handler didn't see Connection: close ")
   285  	}
   286  }
   287  
   288  func TestTransportIdleCacheKeys(t *testing.T) {
   289  	defer afterTest(t)
   290  	ts := httptest.NewServer(hostPortHandler)
   291  	defer ts.Close()
   292  
   293  	tr := &Transport{DisableKeepAlives: false}
   294  	c := &Client{Transport: tr}
   295  
   296  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   297  		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
   298  	}
   299  
   300  	resp, err := c.Get(ts.URL)
   301  	if err != nil {
   302  		t.Error(err)
   303  	}
   304  	ioutil.ReadAll(resp.Body)
   305  
   306  	keys := tr.IdleConnKeysForTesting()
   307  	if e, g := 1, len(keys); e != g {
   308  		t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
   309  	}
   310  
   311  	if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
   312  		t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
   313  	}
   314  
   315  	tr.CloseIdleConnections()
   316  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   317  		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
   318  	}
   319  }
   320  
   321  // Tests that the HTTP transport re-uses connections when a client
   322  // reads to the end of a response Body without closing it.
   323  func TestTransportReadToEndReusesConn(t *testing.T) {
   324  	defer afterTest(t)
   325  	const msg = "foobar"
   326  
   327  	var addrSeen map[string]int
   328  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   329  		addrSeen[r.RemoteAddr]++
   330  		if r.URL.Path == "/chunked/" {
   331  			w.WriteHeader(200)
   332  			w.(Flusher).Flush()
   333  		} else {
   334  			w.Header().Set("Content-Type", strconv.Itoa(len(msg)))
   335  			w.WriteHeader(200)
   336  		}
   337  		w.Write([]byte(msg))
   338  	}))
   339  	defer ts.Close()
   340  
   341  	buf := make([]byte, len(msg))
   342  
   343  	for pi, path := range []string{"/content-length/", "/chunked/"} {
   344  		wantLen := []int{len(msg), -1}[pi]
   345  		addrSeen = make(map[string]int)
   346  		for i := 0; i < 3; i++ {
   347  			res, err := Get(ts.URL + path)
   348  			if err != nil {
   349  				t.Errorf("Get %s: %v", path, err)
   350  				continue
   351  			}
   352  			// We want to close this body eventually (before the
   353  			// defer afterTest at top runs), but not before the
   354  			// len(addrSeen) check at the bottom of this test,
   355  			// since Closing this early in the loop would risk
   356  			// making connections be re-used for the wrong reason.
   357  			defer res.Body.Close()
   358  
   359  			if res.ContentLength != int64(wantLen) {
   360  				t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen)
   361  			}
   362  			n, err := res.Body.Read(buf)
   363  			if n != len(msg) || err != io.EOF {
   364  				t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg))
   365  			}
   366  		}
   367  		if len(addrSeen) != 1 {
   368  			t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen))
   369  		}
   370  	}
   371  }
   372  
   373  func TestTransportMaxPerHostIdleConns(t *testing.T) {
   374  	defer afterTest(t)
   375  	resch := make(chan string)
   376  	gotReq := make(chan bool)
   377  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   378  		gotReq <- true
   379  		msg := <-resch
   380  		_, err := w.Write([]byte(msg))
   381  		if err != nil {
   382  			t.Fatalf("Write: %v", err)
   383  		}
   384  	}))
   385  	defer ts.Close()
   386  	maxIdleConnsPerHost := 2
   387  	tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConnsPerHost}
   388  	c := &Client{Transport: tr}
   389  
   390  	// Start 3 outstanding requests and wait for the server to get them.
   391  	// Their responses will hang until we write to resch, though.
   392  	donech := make(chan bool)
   393  	doReq := func() {
   394  		resp, err := c.Get(ts.URL)
   395  		if err != nil {
   396  			t.Error(err)
   397  			return
   398  		}
   399  		if _, err := ioutil.ReadAll(resp.Body); err != nil {
   400  			t.Errorf("ReadAll: %v", err)
   401  			return
   402  		}
   403  		donech <- true
   404  	}
   405  	go doReq()
   406  	<-gotReq
   407  	go doReq()
   408  	<-gotReq
   409  	go doReq()
   410  	<-gotReq
   411  
   412  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   413  		t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
   414  	}
   415  
   416  	resch <- "res1"
   417  	<-donech
   418  	keys := tr.IdleConnKeysForTesting()
   419  	if e, g := 1, len(keys); e != g {
   420  		t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
   421  	}
   422  	cacheKey := "|http|" + ts.Listener.Addr().String()
   423  	if keys[0] != cacheKey {
   424  		t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
   425  	}
   426  	if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
   427  		t.Errorf("after first response, expected %d idle conns; got %d", e, g)
   428  	}
   429  
   430  	resch <- "res2"
   431  	<-donech
   432  	if g, w := tr.IdleConnCountForTesting(cacheKey), 2; g != w {
   433  		t.Errorf("after second response, idle conns = %d; want %d", g, w)
   434  	}
   435  
   436  	resch <- "res3"
   437  	<-donech
   438  	if g, w := tr.IdleConnCountForTesting(cacheKey), maxIdleConnsPerHost; g != w {
   439  		t.Errorf("after third response, idle conns = %d; want %d", g, w)
   440  	}
   441  }
   442  
   443  func TestTransportRemovesDeadIdleConnections(t *testing.T) {
   444  	if runtime.GOOS == "plan9" {
   445  		t.Skip("skipping test; see https://golang.org/issue/15464")
   446  	}
   447  	defer afterTest(t)
   448  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   449  		io.WriteString(w, r.RemoteAddr)
   450  	}))
   451  	defer ts.Close()
   452  
   453  	tr := &Transport{}
   454  	defer tr.CloseIdleConnections()
   455  	c := &Client{Transport: tr}
   456  
   457  	doReq := func(name string) string {
   458  		// Do a POST instead of a GET to prevent the Transport's
   459  		// idempotent request retry logic from kicking in...
   460  		res, err := c.Post(ts.URL, "", nil)
   461  		if err != nil {
   462  			t.Fatalf("%s: %v", name, err)
   463  		}
   464  		if res.StatusCode != 200 {
   465  			t.Fatalf("%s: %v", name, res.Status)
   466  		}
   467  		defer res.Body.Close()
   468  		slurp, err := ioutil.ReadAll(res.Body)
   469  		if err != nil {
   470  			t.Fatalf("%s: %v", name, err)
   471  		}
   472  		return string(slurp)
   473  	}
   474  
   475  	first := doReq("first")
   476  	keys1 := tr.IdleConnKeysForTesting()
   477  
   478  	ts.CloseClientConnections()
   479  
   480  	var keys2 []string
   481  	if !waitCondition(3*time.Second, 50*time.Millisecond, func() bool {
   482  		keys2 = tr.IdleConnKeysForTesting()
   483  		return len(keys2) == 0
   484  	}) {
   485  		t.Fatalf("Transport didn't notice idle connection's death.\nbefore: %q\n after: %q\n", keys1, keys2)
   486  	}
   487  
   488  	second := doReq("second")
   489  	if first == second {
   490  		t.Errorf("expected a different connection between requests. got %q both times", first)
   491  	}
   492  }
   493  
   494  func TestTransportServerClosingUnexpectedly(t *testing.T) {
   495  	setParallel(t)
   496  	defer afterTest(t)
   497  	ts := httptest.NewServer(hostPortHandler)
   498  	defer ts.Close()
   499  
   500  	tr := &Transport{}
   501  	c := &Client{Transport: tr}
   502  
   503  	fetch := func(n, retries int) string {
   504  		condFatalf := func(format string, arg ...interface{}) {
   505  			if retries <= 0 {
   506  				t.Fatalf(format, arg...)
   507  			}
   508  			t.Logf("retrying shortly after expected error: "+format, arg...)
   509  			time.Sleep(time.Second / time.Duration(retries))
   510  		}
   511  		for retries >= 0 {
   512  			retries--
   513  			res, err := c.Get(ts.URL)
   514  			if err != nil {
   515  				condFatalf("error in req #%d, GET: %v", n, err)
   516  				continue
   517  			}
   518  			body, err := ioutil.ReadAll(res.Body)
   519  			if err != nil {
   520  				condFatalf("error in req #%d, ReadAll: %v", n, err)
   521  				continue
   522  			}
   523  			res.Body.Close()
   524  			return string(body)
   525  		}
   526  		panic("unreachable")
   527  	}
   528  
   529  	body1 := fetch(1, 0)
   530  	body2 := fetch(2, 0)
   531  
   532  	ts.CloseClientConnections() // surprise!
   533  
   534  	// This test has an expected race. Sleeping for 25 ms prevents
   535  	// it on most fast machines, causing the next fetch() call to
   536  	// succeed quickly. But if we do get errors, fetch() will retry 5
   537  	// times with some delays between.
   538  	time.Sleep(25 * time.Millisecond)
   539  
   540  	body3 := fetch(3, 5)
   541  
   542  	if body1 != body2 {
   543  		t.Errorf("expected body1 and body2 to be equal")
   544  	}
   545  	if body2 == body3 {
   546  		t.Errorf("expected body2 and body3 to be different")
   547  	}
   548  }
   549  
   550  // Test for https://golang.org/issue/2616 (appropriate issue number)
   551  // This fails pretty reliably with GOMAXPROCS=100 or something high.
   552  func TestStressSurpriseServerCloses(t *testing.T) {
   553  	defer afterTest(t)
   554  	if testing.Short() {
   555  		t.Skip("skipping test in short mode")
   556  	}
   557  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   558  		w.Header().Set("Content-Length", "5")
   559  		w.Header().Set("Content-Type", "text/plain")
   560  		w.Write([]byte("Hello"))
   561  		w.(Flusher).Flush()
   562  		conn, buf, _ := w.(Hijacker).Hijack()
   563  		buf.Flush()
   564  		conn.Close()
   565  	}))
   566  	defer ts.Close()
   567  
   568  	tr := &Transport{DisableKeepAlives: false}
   569  	c := &Client{Transport: tr}
   570  	defer tr.CloseIdleConnections()
   571  
   572  	// Do a bunch of traffic from different goroutines. Send to activityc
   573  	// after each request completes, regardless of whether it failed.
   574  	// If these are too high, OS X exhausts its ephemeral ports
   575  	// and hangs waiting for them to transition TCP states. That's
   576  	// not what we want to test. TODO(bradfitz): use an io.Pipe
   577  	// dialer for this test instead?
   578  	const (
   579  		numClients    = 20
   580  		reqsPerClient = 25
   581  	)
   582  	activityc := make(chan bool)
   583  	for i := 0; i < numClients; i++ {
   584  		go func() {
   585  			for i := 0; i < reqsPerClient; i++ {
   586  				res, err := c.Get(ts.URL)
   587  				if err == nil {
   588  					// We expect errors since the server is
   589  					// hanging up on us after telling us to
   590  					// send more requests, so we don't
   591  					// actually care what the error is.
   592  					// But we want to close the body in cases
   593  					// where we won the race.
   594  					res.Body.Close()
   595  				}
   596  				activityc <- true
   597  			}
   598  		}()
   599  	}
   600  
   601  	// Make sure all the request come back, one way or another.
   602  	for i := 0; i < numClients*reqsPerClient; i++ {
   603  		select {
   604  		case <-activityc:
   605  		case <-time.After(5 * time.Second):
   606  			t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
   607  		}
   608  	}
   609  }
   610  
   611  // TestTransportHeadResponses verifies that we deal with Content-Lengths
   612  // with no bodies properly
   613  func TestTransportHeadResponses(t *testing.T) {
   614  	defer afterTest(t)
   615  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   616  		if r.Method != "HEAD" {
   617  			panic("expected HEAD; got " + r.Method)
   618  		}
   619  		w.Header().Set("Content-Length", "123")
   620  		w.WriteHeader(200)
   621  	}))
   622  	defer ts.Close()
   623  
   624  	tr := &Transport{DisableKeepAlives: false}
   625  	c := &Client{Transport: tr}
   626  	for i := 0; i < 2; i++ {
   627  		res, err := c.Head(ts.URL)
   628  		if err != nil {
   629  			t.Errorf("error on loop %d: %v", i, err)
   630  			continue
   631  		}
   632  		if e, g := "123", res.Header.Get("Content-Length"); e != g {
   633  			t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
   634  		}
   635  		if e, g := int64(123), res.ContentLength; e != g {
   636  			t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
   637  		}
   638  		if all, err := ioutil.ReadAll(res.Body); err != nil {
   639  			t.Errorf("loop %d: Body ReadAll: %v", i, err)
   640  		} else if len(all) != 0 {
   641  			t.Errorf("Bogus body %q", all)
   642  		}
   643  	}
   644  }
   645  
   646  // TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
   647  // on responses to HEAD requests.
   648  func TestTransportHeadChunkedResponse(t *testing.T) {
   649  	defer afterTest(t)
   650  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   651  		if r.Method != "HEAD" {
   652  			panic("expected HEAD; got " + r.Method)
   653  		}
   654  		w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
   655  		w.Header().Set("x-client-ipport", r.RemoteAddr)
   656  		w.WriteHeader(200)
   657  	}))
   658  	defer ts.Close()
   659  
   660  	tr := &Transport{DisableKeepAlives: false}
   661  	c := &Client{Transport: tr}
   662  	defer tr.CloseIdleConnections()
   663  
   664  	// Ensure that we wait for the readLoop to complete before
   665  	// calling Head again
   666  	didRead := make(chan bool)
   667  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
   668  	defer SetReadLoopBeforeNextReadHook(nil)
   669  
   670  	res1, err := c.Head(ts.URL)
   671  	<-didRead
   672  
   673  	if err != nil {
   674  		t.Fatalf("request 1 error: %v", err)
   675  	}
   676  
   677  	res2, err := c.Head(ts.URL)
   678  	<-didRead
   679  
   680  	if err != nil {
   681  		t.Fatalf("request 2 error: %v", err)
   682  	}
   683  	if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
   684  		t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
   685  	}
   686  }
   687  
   688  var roundTripTests = []struct {
   689  	accept       string
   690  	expectAccept string
   691  	compressed   bool
   692  }{
   693  	// Requests with no accept-encoding header use transparent compression
   694  	{"", "gzip", false},
   695  	// Requests with other accept-encoding should pass through unmodified
   696  	{"foo", "foo", false},
   697  	// Requests with accept-encoding == gzip should be passed through
   698  	{"gzip", "gzip", true},
   699  }
   700  
   701  // Test that the modification made to the Request by the RoundTripper is cleaned up
   702  func TestRoundTripGzip(t *testing.T) {
   703  	defer afterTest(t)
   704  	const responseBody = "test response body"
   705  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   706  		accept := req.Header.Get("Accept-Encoding")
   707  		if expect := req.FormValue("expect_accept"); accept != expect {
   708  			t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
   709  				req.FormValue("testnum"), accept, expect)
   710  		}
   711  		if accept == "gzip" {
   712  			rw.Header().Set("Content-Encoding", "gzip")
   713  			gz := gzip.NewWriter(rw)
   714  			gz.Write([]byte(responseBody))
   715  			gz.Close()
   716  		} else {
   717  			rw.Header().Set("Content-Encoding", accept)
   718  			rw.Write([]byte(responseBody))
   719  		}
   720  	}))
   721  	defer ts.Close()
   722  
   723  	for i, test := range roundTripTests {
   724  		// Test basic request (no accept-encoding)
   725  		req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
   726  		if test.accept != "" {
   727  			req.Header.Set("Accept-Encoding", test.accept)
   728  		}
   729  		res, err := DefaultTransport.RoundTrip(req)
   730  		var body []byte
   731  		if test.compressed {
   732  			var r *gzip.Reader
   733  			r, err = gzip.NewReader(res.Body)
   734  			if err != nil {
   735  				t.Errorf("%d. gzip NewReader: %v", i, err)
   736  				continue
   737  			}
   738  			body, err = ioutil.ReadAll(r)
   739  			res.Body.Close()
   740  		} else {
   741  			body, err = ioutil.ReadAll(res.Body)
   742  		}
   743  		if err != nil {
   744  			t.Errorf("%d. Error: %q", i, err)
   745  			continue
   746  		}
   747  		if g, e := string(body), responseBody; g != e {
   748  			t.Errorf("%d. body = %q; want %q", i, g, e)
   749  		}
   750  		if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
   751  			t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
   752  		}
   753  		if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
   754  			t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
   755  		}
   756  	}
   757  
   758  }
   759  
   760  func TestTransportGzip(t *testing.T) {
   761  	defer afterTest(t)
   762  	const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
   763  	const nRandBytes = 1024 * 1024
   764  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   765  		if req.Method == "HEAD" {
   766  			if g := req.Header.Get("Accept-Encoding"); g != "" {
   767  				t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g)
   768  			}
   769  			return
   770  		}
   771  		if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
   772  			t.Errorf("Accept-Encoding = %q, want %q", g, e)
   773  		}
   774  		rw.Header().Set("Content-Encoding", "gzip")
   775  
   776  		var w io.Writer = rw
   777  		var buf bytes.Buffer
   778  		if req.FormValue("chunked") == "0" {
   779  			w = &buf
   780  			defer io.Copy(rw, &buf)
   781  			defer func() {
   782  				rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
   783  			}()
   784  		}
   785  		gz := gzip.NewWriter(w)
   786  		gz.Write([]byte(testString))
   787  		if req.FormValue("body") == "large" {
   788  			io.CopyN(gz, rand.Reader, nRandBytes)
   789  		}
   790  		gz.Close()
   791  	}))
   792  	defer ts.Close()
   793  
   794  	for _, chunked := range []string{"1", "0"} {
   795  		c := &Client{Transport: &Transport{}}
   796  
   797  		// First fetch something large, but only read some of it.
   798  		res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
   799  		if err != nil {
   800  			t.Fatalf("large get: %v", err)
   801  		}
   802  		buf := make([]byte, len(testString))
   803  		n, err := io.ReadFull(res.Body, buf)
   804  		if err != nil {
   805  			t.Fatalf("partial read of large response: size=%d, %v", n, err)
   806  		}
   807  		if e, g := testString, string(buf); e != g {
   808  			t.Errorf("partial read got %q, expected %q", g, e)
   809  		}
   810  		res.Body.Close()
   811  		// Read on the body, even though it's closed
   812  		n, err = res.Body.Read(buf)
   813  		if n != 0 || err == nil {
   814  			t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
   815  		}
   816  
   817  		// Then something small.
   818  		res, err = c.Get(ts.URL + "/?chunked=" + chunked)
   819  		if err != nil {
   820  			t.Fatal(err)
   821  		}
   822  		body, err := ioutil.ReadAll(res.Body)
   823  		if err != nil {
   824  			t.Fatal(err)
   825  		}
   826  		if g, e := string(body), testString; g != e {
   827  			t.Fatalf("body = %q; want %q", g, e)
   828  		}
   829  		if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
   830  			t.Fatalf("Content-Encoding = %q; want %q", g, e)
   831  		}
   832  
   833  		// Read on the body after it's been fully read:
   834  		n, err = res.Body.Read(buf)
   835  		if n != 0 || err == nil {
   836  			t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
   837  		}
   838  		res.Body.Close()
   839  		n, err = res.Body.Read(buf)
   840  		if n != 0 || err == nil {
   841  			t.Errorf("expected Read error after Close; got %d, %v", n, err)
   842  		}
   843  	}
   844  
   845  	// And a HEAD request too, because they're always weird.
   846  	c := &Client{Transport: &Transport{}}
   847  	res, err := c.Head(ts.URL)
   848  	if err != nil {
   849  		t.Fatalf("Head: %v", err)
   850  	}
   851  	if res.StatusCode != 200 {
   852  		t.Errorf("Head status=%d; want=200", res.StatusCode)
   853  	}
   854  }
   855  
   856  // If a request has Expect:100-continue header, the request blocks sending body until the first response.
   857  // Premature consumption of the request body should not be occurred.
   858  func TestTransportExpect100Continue(t *testing.T) {
   859  	defer afterTest(t)
   860  
   861  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   862  		switch req.URL.Path {
   863  		case "/100":
   864  			// This endpoint implicitly responds 100 Continue and reads body.
   865  			if _, err := io.Copy(ioutil.Discard, req.Body); err != nil {
   866  				t.Error("Failed to read Body", err)
   867  			}
   868  			rw.WriteHeader(StatusOK)
   869  		case "/200":
   870  			// Go 1.5 adds Connection: close header if the client expect
   871  			// continue but not entire request body is consumed.
   872  			rw.WriteHeader(StatusOK)
   873  		case "/500":
   874  			rw.WriteHeader(StatusInternalServerError)
   875  		case "/keepalive":
   876  			// This hijacked endpoint responds error without Connection:close.
   877  			_, bufrw, err := rw.(Hijacker).Hijack()
   878  			if err != nil {
   879  				log.Fatal(err)
   880  			}
   881  			bufrw.WriteString("HTTP/1.1 500 Internal Server Error\r\n")
   882  			bufrw.WriteString("Content-Length: 0\r\n\r\n")
   883  			bufrw.Flush()
   884  		case "/timeout":
   885  			// This endpoint tries to read body without 100 (Continue) response.
   886  			// After ExpectContinueTimeout, the reading will be started.
   887  			conn, bufrw, err := rw.(Hijacker).Hijack()
   888  			if err != nil {
   889  				log.Fatal(err)
   890  			}
   891  			if _, err := io.CopyN(ioutil.Discard, bufrw, req.ContentLength); err != nil {
   892  				t.Error("Failed to read Body", err)
   893  			}
   894  			bufrw.WriteString("HTTP/1.1 200 OK\r\n\r\n")
   895  			bufrw.Flush()
   896  			conn.Close()
   897  		}
   898  
   899  	}))
   900  	defer ts.Close()
   901  
   902  	tests := []struct {
   903  		path   string
   904  		body   []byte
   905  		sent   int
   906  		status int
   907  	}{
   908  		{path: "/100", body: []byte("hello"), sent: 5, status: 200},       // Got 100 followed by 200, entire body is sent.
   909  		{path: "/200", body: []byte("hello"), sent: 0, status: 200},       // Got 200 without 100. body isn't sent.
   910  		{path: "/500", body: []byte("hello"), sent: 0, status: 500},       // Got 500 without 100. body isn't sent.
   911  		{path: "/keepalive", body: []byte("hello"), sent: 0, status: 500}, // Although without Connection:close, body isn't sent.
   912  		{path: "/timeout", body: []byte("hello"), sent: 5, status: 200},   // Timeout exceeded and entire body is sent.
   913  	}
   914  
   915  	for i, v := range tests {
   916  		tr := &Transport{ExpectContinueTimeout: 2 * time.Second}
   917  		defer tr.CloseIdleConnections()
   918  		c := &Client{Transport: tr}
   919  
   920  		body := bytes.NewReader(v.body)
   921  		req, err := NewRequest("PUT", ts.URL+v.path, body)
   922  		if err != nil {
   923  			t.Fatal(err)
   924  		}
   925  		req.Header.Set("Expect", "100-continue")
   926  		req.ContentLength = int64(len(v.body))
   927  
   928  		resp, err := c.Do(req)
   929  		if err != nil {
   930  			t.Fatal(err)
   931  		}
   932  		resp.Body.Close()
   933  
   934  		sent := len(v.body) - body.Len()
   935  		if v.status != resp.StatusCode {
   936  			t.Errorf("test %d: status code should be %d but got %d. (%s)", i, v.status, resp.StatusCode, v.path)
   937  		}
   938  		if v.sent != sent {
   939  			t.Errorf("test %d: sent body should be %d but sent %d. (%s)", i, v.sent, sent, v.path)
   940  		}
   941  	}
   942  }
   943  
   944  func TestTransportProxy(t *testing.T) {
   945  	defer afterTest(t)
   946  	ch := make(chan string, 1)
   947  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   948  		ch <- "real server"
   949  	}))
   950  	defer ts.Close()
   951  	proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   952  		ch <- "proxy for " + r.URL.String()
   953  	}))
   954  	defer proxy.Close()
   955  
   956  	pu, err := url.Parse(proxy.URL)
   957  	if err != nil {
   958  		t.Fatal(err)
   959  	}
   960  	c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
   961  	c.Head(ts.URL)
   962  	got := <-ch
   963  	want := "proxy for " + ts.URL + "/"
   964  	if got != want {
   965  		t.Errorf("want %q, got %q", want, got)
   966  	}
   967  }
   968  
   969  // TestTransportGzipRecursive sends a gzip quine and checks that the
   970  // client gets the same value back. This is more cute than anything,
   971  // but checks that we don't recurse forever, and checks that
   972  // Content-Encoding is removed.
   973  func TestTransportGzipRecursive(t *testing.T) {
   974  	defer afterTest(t)
   975  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   976  		w.Header().Set("Content-Encoding", "gzip")
   977  		w.Write(rgz)
   978  	}))
   979  	defer ts.Close()
   980  
   981  	tr := &Transport{}
   982  	defer tr.CloseIdleConnections()
   983  	c := &Client{Transport: tr}
   984  	res, err := c.Get(ts.URL)
   985  	if err != nil {
   986  		t.Fatal(err)
   987  	}
   988  	body, err := ioutil.ReadAll(res.Body)
   989  	if err != nil {
   990  		t.Fatal(err)
   991  	}
   992  	if !bytes.Equal(body, rgz) {
   993  		t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
   994  			body, rgz)
   995  	}
   996  	if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
   997  		t.Fatalf("Content-Encoding = %q; want %q", g, e)
   998  	}
   999  }
  1000  
  1001  // golang.org/issue/7750: request fails when server replies with
  1002  // a short gzip body
  1003  func TestTransportGzipShort(t *testing.T) {
  1004  	defer afterTest(t)
  1005  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1006  		w.Header().Set("Content-Encoding", "gzip")
  1007  		w.Write([]byte{0x1f, 0x8b})
  1008  	}))
  1009  	defer ts.Close()
  1010  
  1011  	tr := &Transport{}
  1012  	defer tr.CloseIdleConnections()
  1013  	c := &Client{Transport: tr}
  1014  	res, err := c.Get(ts.URL)
  1015  	if err != nil {
  1016  		t.Fatal(err)
  1017  	}
  1018  	defer res.Body.Close()
  1019  	_, err = ioutil.ReadAll(res.Body)
  1020  	if err == nil {
  1021  		t.Fatal("Expect an error from reading a body.")
  1022  	}
  1023  	if err != io.ErrUnexpectedEOF {
  1024  		t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err)
  1025  	}
  1026  }
  1027  
  1028  // Wait until number of goroutines is no greater than nmax, or time out.
  1029  func waitNumGoroutine(nmax int) int {
  1030  	nfinal := runtime.NumGoroutine()
  1031  	for ntries := 10; ntries > 0 && nfinal > nmax; ntries-- {
  1032  		time.Sleep(50 * time.Millisecond)
  1033  		runtime.GC()
  1034  		nfinal = runtime.NumGoroutine()
  1035  	}
  1036  	return nfinal
  1037  }
  1038  
  1039  // tests that persistent goroutine connections shut down when no longer desired.
  1040  func TestTransportPersistConnLeak(t *testing.T) {
  1041  	setParallel(t)
  1042  	defer afterTest(t)
  1043  	gotReqCh := make(chan bool)
  1044  	unblockCh := make(chan bool)
  1045  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1046  		gotReqCh <- true
  1047  		<-unblockCh
  1048  		w.Header().Set("Content-Length", "0")
  1049  		w.WriteHeader(204)
  1050  	}))
  1051  	defer ts.Close()
  1052  
  1053  	tr := &Transport{}
  1054  	c := &Client{Transport: tr}
  1055  
  1056  	n0 := runtime.NumGoroutine()
  1057  
  1058  	const numReq = 25
  1059  	didReqCh := make(chan bool)
  1060  	for i := 0; i < numReq; i++ {
  1061  		go func() {
  1062  			res, err := c.Get(ts.URL)
  1063  			didReqCh <- true
  1064  			if err != nil {
  1065  				t.Errorf("client fetch error: %v", err)
  1066  				return
  1067  			}
  1068  			res.Body.Close()
  1069  		}()
  1070  	}
  1071  
  1072  	// Wait for all goroutines to be stuck in the Handler.
  1073  	for i := 0; i < numReq; i++ {
  1074  		<-gotReqCh
  1075  	}
  1076  
  1077  	nhigh := runtime.NumGoroutine()
  1078  
  1079  	// Tell all handlers to unblock and reply.
  1080  	for i := 0; i < numReq; i++ {
  1081  		unblockCh <- true
  1082  	}
  1083  
  1084  	// Wait for all HTTP clients to be done.
  1085  	for i := 0; i < numReq; i++ {
  1086  		<-didReqCh
  1087  	}
  1088  
  1089  	tr.CloseIdleConnections()
  1090  	nfinal := waitNumGoroutine(n0 + 5)
  1091  
  1092  	growth := nfinal - n0
  1093  
  1094  	// We expect 0 or 1 extra goroutine, empirically. Allow up to 5.
  1095  	// Previously we were leaking one per numReq.
  1096  	if int(growth) > 5 {
  1097  		t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
  1098  		t.Error("too many new goroutines")
  1099  	}
  1100  }
  1101  
  1102  // golang.org/issue/4531: Transport leaks goroutines when
  1103  // request.ContentLength is explicitly short
  1104  func TestTransportPersistConnLeakShortBody(t *testing.T) {
  1105  	setParallel(t)
  1106  	defer afterTest(t)
  1107  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1108  	}))
  1109  	defer ts.Close()
  1110  
  1111  	tr := &Transport{}
  1112  	c := &Client{Transport: tr}
  1113  
  1114  	n0 := runtime.NumGoroutine()
  1115  	body := []byte("Hello")
  1116  	for i := 0; i < 20; i++ {
  1117  		req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
  1118  		if err != nil {
  1119  			t.Fatal(err)
  1120  		}
  1121  		req.ContentLength = int64(len(body) - 2) // explicitly short
  1122  		_, err = c.Do(req)
  1123  		if err == nil {
  1124  			t.Fatal("Expect an error from writing too long of a body.")
  1125  		}
  1126  	}
  1127  	nhigh := runtime.NumGoroutine()
  1128  	tr.CloseIdleConnections()
  1129  	nfinal := waitNumGoroutine(n0 + 5)
  1130  
  1131  	growth := nfinal - n0
  1132  
  1133  	// We expect 0 or 1 extra goroutine, empirically. Allow up to 5.
  1134  	// Previously we were leaking one per numReq.
  1135  	t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
  1136  	if int(growth) > 5 {
  1137  		t.Error("too many new goroutines")
  1138  	}
  1139  }
  1140  
  1141  // This used to crash; https://golang.org/issue/3266
  1142  func TestTransportIdleConnCrash(t *testing.T) {
  1143  	defer afterTest(t)
  1144  	tr := &Transport{}
  1145  	c := &Client{Transport: tr}
  1146  
  1147  	unblockCh := make(chan bool, 1)
  1148  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1149  		<-unblockCh
  1150  		tr.CloseIdleConnections()
  1151  	}))
  1152  	defer ts.Close()
  1153  
  1154  	didreq := make(chan bool)
  1155  	go func() {
  1156  		res, err := c.Get(ts.URL)
  1157  		if err != nil {
  1158  			t.Error(err)
  1159  		} else {
  1160  			res.Body.Close() // returns idle conn
  1161  		}
  1162  		didreq <- true
  1163  	}()
  1164  	unblockCh <- true
  1165  	<-didreq
  1166  }
  1167  
  1168  // Test that the transport doesn't close the TCP connection early,
  1169  // before the response body has been read. This was a regression
  1170  // which sadly lacked a triggering test. The large response body made
  1171  // the old race easier to trigger.
  1172  func TestIssue3644(t *testing.T) {
  1173  	defer afterTest(t)
  1174  	const numFoos = 5000
  1175  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1176  		w.Header().Set("Connection", "close")
  1177  		for i := 0; i < numFoos; i++ {
  1178  			w.Write([]byte("foo "))
  1179  		}
  1180  	}))
  1181  	defer ts.Close()
  1182  	tr := &Transport{}
  1183  	c := &Client{Transport: tr}
  1184  	res, err := c.Get(ts.URL)
  1185  	if err != nil {
  1186  		t.Fatal(err)
  1187  	}
  1188  	defer res.Body.Close()
  1189  	bs, err := ioutil.ReadAll(res.Body)
  1190  	if err != nil {
  1191  		t.Fatal(err)
  1192  	}
  1193  	if len(bs) != numFoos*len("foo ") {
  1194  		t.Errorf("unexpected response length")
  1195  	}
  1196  }
  1197  
  1198  // Test that a client receives a server's reply, even if the server doesn't read
  1199  // the entire request body.
  1200  func TestIssue3595(t *testing.T) {
  1201  	defer afterTest(t)
  1202  	const deniedMsg = "sorry, denied."
  1203  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1204  		Error(w, deniedMsg, StatusUnauthorized)
  1205  	}))
  1206  	defer ts.Close()
  1207  	tr := &Transport{}
  1208  	c := &Client{Transport: tr}
  1209  	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
  1210  	if err != nil {
  1211  		t.Errorf("Post: %v", err)
  1212  		return
  1213  	}
  1214  	got, err := ioutil.ReadAll(res.Body)
  1215  	if err != nil {
  1216  		t.Fatalf("Body ReadAll: %v", err)
  1217  	}
  1218  	if !strings.Contains(string(got), deniedMsg) {
  1219  		t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
  1220  	}
  1221  }
  1222  
  1223  // From https://golang.org/issue/4454 ,
  1224  // "client fails to handle requests with no body and chunked encoding"
  1225  func TestChunkedNoContent(t *testing.T) {
  1226  	defer afterTest(t)
  1227  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1228  		w.WriteHeader(StatusNoContent)
  1229  	}))
  1230  	defer ts.Close()
  1231  
  1232  	for _, closeBody := range []bool{true, false} {
  1233  		c := &Client{Transport: &Transport{}}
  1234  		const n = 4
  1235  		for i := 1; i <= n; i++ {
  1236  			res, err := c.Get(ts.URL)
  1237  			if err != nil {
  1238  				t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
  1239  			} else {
  1240  				if closeBody {
  1241  					res.Body.Close()
  1242  				}
  1243  			}
  1244  		}
  1245  	}
  1246  }
  1247  
  1248  func TestTransportConcurrency(t *testing.T) {
  1249  	defer afterTest(t)
  1250  	maxProcs, numReqs := 16, 500
  1251  	if testing.Short() {
  1252  		maxProcs, numReqs = 4, 50
  1253  	}
  1254  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
  1255  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1256  		fmt.Fprintf(w, "%v", r.FormValue("echo"))
  1257  	}))
  1258  	defer ts.Close()
  1259  
  1260  	var wg sync.WaitGroup
  1261  	wg.Add(numReqs)
  1262  
  1263  	// Due to the Transport's "socket late binding" (see
  1264  	// idleConnCh in transport.go), the numReqs HTTP requests
  1265  	// below can finish with a dial still outstanding. To keep
  1266  	// the leak checker happy, keep track of pending dials and
  1267  	// wait for them to finish (and be closed or returned to the
  1268  	// idle pool) before we close idle connections.
  1269  	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  1270  	defer SetPendingDialHooks(nil, nil)
  1271  
  1272  	tr := &Transport{}
  1273  	defer tr.CloseIdleConnections()
  1274  
  1275  	c := &Client{Transport: tr}
  1276  	reqs := make(chan string)
  1277  	defer close(reqs)
  1278  
  1279  	for i := 0; i < maxProcs*2; i++ {
  1280  		go func() {
  1281  			for req := range reqs {
  1282  				res, err := c.Get(ts.URL + "/?echo=" + req)
  1283  				if err != nil {
  1284  					t.Errorf("error on req %s: %v", req, err)
  1285  					wg.Done()
  1286  					continue
  1287  				}
  1288  				all, err := ioutil.ReadAll(res.Body)
  1289  				if err != nil {
  1290  					t.Errorf("read error on req %s: %v", req, err)
  1291  					wg.Done()
  1292  					continue
  1293  				}
  1294  				if string(all) != req {
  1295  					t.Errorf("body of req %s = %q; want %q", req, all, req)
  1296  				}
  1297  				res.Body.Close()
  1298  				wg.Done()
  1299  			}
  1300  		}()
  1301  	}
  1302  	for i := 0; i < numReqs; i++ {
  1303  		reqs <- fmt.Sprintf("request-%d", i)
  1304  	}
  1305  	wg.Wait()
  1306  }
  1307  
  1308  func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
  1309  	if runtime.GOOS == "plan9" {
  1310  		t.Skip("skipping test; see https://golang.org/issue/7237")
  1311  	}
  1312  	defer afterTest(t)
  1313  	const debug = false
  1314  	mux := NewServeMux()
  1315  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1316  		io.Copy(w, neverEnding('a'))
  1317  	})
  1318  	ts := httptest.NewServer(mux)
  1319  	timeout := 100 * time.Millisecond
  1320  
  1321  	client := &Client{
  1322  		Transport: &Transport{
  1323  			Dial: func(n, addr string) (net.Conn, error) {
  1324  				conn, err := net.Dial(n, addr)
  1325  				if err != nil {
  1326  					return nil, err
  1327  				}
  1328  				conn.SetDeadline(time.Now().Add(timeout))
  1329  				if debug {
  1330  					conn = NewLoggingConn("client", conn)
  1331  				}
  1332  				return conn, nil
  1333  			},
  1334  			DisableKeepAlives: true,
  1335  		},
  1336  	}
  1337  
  1338  	getFailed := false
  1339  	nRuns := 5
  1340  	if testing.Short() {
  1341  		nRuns = 1
  1342  	}
  1343  	for i := 0; i < nRuns; i++ {
  1344  		if debug {
  1345  			println("run", i+1, "of", nRuns)
  1346  		}
  1347  		sres, err := client.Get(ts.URL + "/get")
  1348  		if err != nil {
  1349  			if !getFailed {
  1350  				// Make the timeout longer, once.
  1351  				getFailed = true
  1352  				t.Logf("increasing timeout")
  1353  				i--
  1354  				timeout *= 10
  1355  				continue
  1356  			}
  1357  			t.Errorf("Error issuing GET: %v", err)
  1358  			break
  1359  		}
  1360  		_, err = io.Copy(ioutil.Discard, sres.Body)
  1361  		if err == nil {
  1362  			t.Errorf("Unexpected successful copy")
  1363  			break
  1364  		}
  1365  	}
  1366  	if debug {
  1367  		println("tests complete; waiting for handlers to finish")
  1368  	}
  1369  	ts.Close()
  1370  }
  1371  
  1372  func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
  1373  	if runtime.GOOS == "plan9" {
  1374  		t.Skip("skipping test; see https://golang.org/issue/7237")
  1375  	}
  1376  	defer afterTest(t)
  1377  	const debug = false
  1378  	mux := NewServeMux()
  1379  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1380  		io.Copy(w, neverEnding('a'))
  1381  	})
  1382  	mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
  1383  		defer r.Body.Close()
  1384  		io.Copy(ioutil.Discard, r.Body)
  1385  	})
  1386  	ts := httptest.NewServer(mux)
  1387  	timeout := 100 * time.Millisecond
  1388  
  1389  	client := &Client{
  1390  		Transport: &Transport{
  1391  			Dial: func(n, addr string) (net.Conn, error) {
  1392  				conn, err := net.Dial(n, addr)
  1393  				if err != nil {
  1394  					return nil, err
  1395  				}
  1396  				conn.SetDeadline(time.Now().Add(timeout))
  1397  				if debug {
  1398  					conn = NewLoggingConn("client", conn)
  1399  				}
  1400  				return conn, nil
  1401  			},
  1402  			DisableKeepAlives: true,
  1403  		},
  1404  	}
  1405  
  1406  	getFailed := false
  1407  	nRuns := 5
  1408  	if testing.Short() {
  1409  		nRuns = 1
  1410  	}
  1411  	for i := 0; i < nRuns; i++ {
  1412  		if debug {
  1413  			println("run", i+1, "of", nRuns)
  1414  		}
  1415  		sres, err := client.Get(ts.URL + "/get")
  1416  		if err != nil {
  1417  			if !getFailed {
  1418  				// Make the timeout longer, once.
  1419  				getFailed = true
  1420  				t.Logf("increasing timeout")
  1421  				i--
  1422  				timeout *= 10
  1423  				continue
  1424  			}
  1425  			t.Errorf("Error issuing GET: %v", err)
  1426  			break
  1427  		}
  1428  		req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
  1429  		_, err = client.Do(req)
  1430  		if err == nil {
  1431  			sres.Body.Close()
  1432  			t.Errorf("Unexpected successful PUT")
  1433  			break
  1434  		}
  1435  		sres.Body.Close()
  1436  	}
  1437  	if debug {
  1438  		println("tests complete; waiting for handlers to finish")
  1439  	}
  1440  	ts.Close()
  1441  }
  1442  
  1443  func TestTransportResponseHeaderTimeout(t *testing.T) {
  1444  	setParallel(t)
  1445  	defer afterTest(t)
  1446  	if testing.Short() {
  1447  		t.Skip("skipping timeout test in -short mode")
  1448  	}
  1449  	inHandler := make(chan bool, 1)
  1450  	mux := NewServeMux()
  1451  	mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {
  1452  		inHandler <- true
  1453  	})
  1454  	mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
  1455  		inHandler <- true
  1456  		time.Sleep(2 * time.Second)
  1457  	})
  1458  	ts := httptest.NewServer(mux)
  1459  	defer ts.Close()
  1460  
  1461  	tr := &Transport{
  1462  		ResponseHeaderTimeout: 500 * time.Millisecond,
  1463  	}
  1464  	defer tr.CloseIdleConnections()
  1465  	c := &Client{Transport: tr}
  1466  
  1467  	tests := []struct {
  1468  		path    string
  1469  		want    int
  1470  		wantErr string
  1471  	}{
  1472  		{path: "/fast", want: 200},
  1473  		{path: "/slow", wantErr: "timeout awaiting response headers"},
  1474  		{path: "/fast", want: 200},
  1475  	}
  1476  	for i, tt := range tests {
  1477  		res, err := c.Get(ts.URL + tt.path)
  1478  		select {
  1479  		case <-inHandler:
  1480  		case <-time.After(5 * time.Second):
  1481  			t.Errorf("never entered handler for test index %d, %s", i, tt.path)
  1482  			continue
  1483  		}
  1484  		if err != nil {
  1485  			uerr, ok := err.(*url.Error)
  1486  			if !ok {
  1487  				t.Errorf("error is not an url.Error; got: %#v", err)
  1488  				continue
  1489  			}
  1490  			nerr, ok := uerr.Err.(net.Error)
  1491  			if !ok {
  1492  				t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
  1493  				continue
  1494  			}
  1495  			if !nerr.Timeout() {
  1496  				t.Errorf("want timeout error; got: %q", nerr)
  1497  				continue
  1498  			}
  1499  			if strings.Contains(err.Error(), tt.wantErr) {
  1500  				continue
  1501  			}
  1502  			t.Errorf("%d. unexpected error: %v", i, err)
  1503  			continue
  1504  		}
  1505  		if tt.wantErr != "" {
  1506  			t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
  1507  			continue
  1508  		}
  1509  		if res.StatusCode != tt.want {
  1510  			t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
  1511  		}
  1512  	}
  1513  }
  1514  
  1515  func TestTransportCancelRequest(t *testing.T) {
  1516  	setParallel(t)
  1517  	defer afterTest(t)
  1518  	if testing.Short() {
  1519  		t.Skip("skipping test in -short mode")
  1520  	}
  1521  	unblockc := make(chan bool)
  1522  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1523  		fmt.Fprintf(w, "Hello")
  1524  		w.(Flusher).Flush() // send headers and some body
  1525  		<-unblockc
  1526  	}))
  1527  	defer ts.Close()
  1528  	defer close(unblockc)
  1529  
  1530  	tr := &Transport{}
  1531  	defer tr.CloseIdleConnections()
  1532  	c := &Client{Transport: tr}
  1533  
  1534  	req, _ := NewRequest("GET", ts.URL, nil)
  1535  	res, err := c.Do(req)
  1536  	if err != nil {
  1537  		t.Fatal(err)
  1538  	}
  1539  	go func() {
  1540  		time.Sleep(1 * time.Second)
  1541  		tr.CancelRequest(req)
  1542  	}()
  1543  	t0 := time.Now()
  1544  	body, err := ioutil.ReadAll(res.Body)
  1545  	d := time.Since(t0)
  1546  
  1547  	if err != ExportErrRequestCanceled {
  1548  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  1549  	}
  1550  	if string(body) != "Hello" {
  1551  		t.Errorf("Body = %q; want Hello", body)
  1552  	}
  1553  	if d < 500*time.Millisecond {
  1554  		t.Errorf("expected ~1 second delay; got %v", d)
  1555  	}
  1556  	// Verify no outstanding requests after readLoop/writeLoop
  1557  	// goroutines shut down.
  1558  	for tries := 5; tries > 0; tries-- {
  1559  		n := tr.NumPendingRequestsForTesting()
  1560  		if n == 0 {
  1561  			break
  1562  		}
  1563  		time.Sleep(100 * time.Millisecond)
  1564  		if tries == 1 {
  1565  			t.Errorf("pending requests = %d; want 0", n)
  1566  		}
  1567  	}
  1568  }
  1569  
  1570  func TestTransportCancelRequestInDial(t *testing.T) {
  1571  	defer afterTest(t)
  1572  	if testing.Short() {
  1573  		t.Skip("skipping test in -short mode")
  1574  	}
  1575  	var logbuf bytes.Buffer
  1576  	eventLog := log.New(&logbuf, "", 0)
  1577  
  1578  	unblockDial := make(chan bool)
  1579  	defer close(unblockDial)
  1580  
  1581  	inDial := make(chan bool)
  1582  	tr := &Transport{
  1583  		Dial: func(network, addr string) (net.Conn, error) {
  1584  			eventLog.Println("dial: blocking")
  1585  			inDial <- true
  1586  			<-unblockDial
  1587  			return nil, errors.New("nope")
  1588  		},
  1589  	}
  1590  	cl := &Client{Transport: tr}
  1591  	gotres := make(chan bool)
  1592  	req, _ := NewRequest("GET", "http://something.no-network.tld/", nil)
  1593  	go func() {
  1594  		_, err := cl.Do(req)
  1595  		eventLog.Printf("Get = %v", err)
  1596  		gotres <- true
  1597  	}()
  1598  
  1599  	select {
  1600  	case <-inDial:
  1601  	case <-time.After(5 * time.Second):
  1602  		t.Fatal("timeout; never saw blocking dial")
  1603  	}
  1604  
  1605  	eventLog.Printf("canceling")
  1606  	tr.CancelRequest(req)
  1607  	tr.CancelRequest(req) // used to panic on second call
  1608  
  1609  	select {
  1610  	case <-gotres:
  1611  	case <-time.After(5 * time.Second):
  1612  		panic("hang. events are: " + logbuf.String())
  1613  	}
  1614  
  1615  	got := logbuf.String()
  1616  	want := `dial: blocking
  1617  canceling
  1618  Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection
  1619  `
  1620  	if got != want {
  1621  		t.Errorf("Got events:\n%s\nWant:\n%s", got, want)
  1622  	}
  1623  }
  1624  
  1625  func TestCancelRequestWithChannel(t *testing.T) {
  1626  	setParallel(t)
  1627  	defer afterTest(t)
  1628  	if testing.Short() {
  1629  		t.Skip("skipping test in -short mode")
  1630  	}
  1631  	unblockc := make(chan bool)
  1632  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1633  		fmt.Fprintf(w, "Hello")
  1634  		w.(Flusher).Flush() // send headers and some body
  1635  		<-unblockc
  1636  	}))
  1637  	defer ts.Close()
  1638  	defer close(unblockc)
  1639  
  1640  	tr := &Transport{}
  1641  	defer tr.CloseIdleConnections()
  1642  	c := &Client{Transport: tr}
  1643  
  1644  	req, _ := NewRequest("GET", ts.URL, nil)
  1645  	ch := make(chan struct{})
  1646  	req.Cancel = ch
  1647  
  1648  	res, err := c.Do(req)
  1649  	if err != nil {
  1650  		t.Fatal(err)
  1651  	}
  1652  	go func() {
  1653  		time.Sleep(1 * time.Second)
  1654  		close(ch)
  1655  	}()
  1656  	t0 := time.Now()
  1657  	body, err := ioutil.ReadAll(res.Body)
  1658  	d := time.Since(t0)
  1659  
  1660  	if err != ExportErrRequestCanceled {
  1661  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  1662  	}
  1663  	if string(body) != "Hello" {
  1664  		t.Errorf("Body = %q; want Hello", body)
  1665  	}
  1666  	if d < 500*time.Millisecond {
  1667  		t.Errorf("expected ~1 second delay; got %v", d)
  1668  	}
  1669  	// Verify no outstanding requests after readLoop/writeLoop
  1670  	// goroutines shut down.
  1671  	for tries := 5; tries > 0; tries-- {
  1672  		n := tr.NumPendingRequestsForTesting()
  1673  		if n == 0 {
  1674  			break
  1675  		}
  1676  		time.Sleep(100 * time.Millisecond)
  1677  		if tries == 1 {
  1678  			t.Errorf("pending requests = %d; want 0", n)
  1679  		}
  1680  	}
  1681  }
  1682  
  1683  func TestCancelRequestWithChannelBeforeDo_Cancel(t *testing.T) {
  1684  	testCancelRequestWithChannelBeforeDo(t, false)
  1685  }
  1686  func TestCancelRequestWithChannelBeforeDo_Context(t *testing.T) {
  1687  	testCancelRequestWithChannelBeforeDo(t, true)
  1688  }
  1689  func testCancelRequestWithChannelBeforeDo(t *testing.T, withCtx bool) {
  1690  	setParallel(t)
  1691  	defer afterTest(t)
  1692  	unblockc := make(chan bool)
  1693  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1694  		<-unblockc
  1695  	}))
  1696  	defer ts.Close()
  1697  	defer close(unblockc)
  1698  
  1699  	// Don't interfere with the next test on plan9.
  1700  	// Cf. https://golang.org/issues/11476
  1701  	if runtime.GOOS == "plan9" {
  1702  		defer time.Sleep(500 * time.Millisecond)
  1703  	}
  1704  
  1705  	tr := &Transport{}
  1706  	defer tr.CloseIdleConnections()
  1707  	c := &Client{Transport: tr}
  1708  
  1709  	req, _ := NewRequest("GET", ts.URL, nil)
  1710  	if withCtx {
  1711  		ctx, cancel := context.WithCancel(context.Background())
  1712  		cancel()
  1713  		req = req.WithContext(ctx)
  1714  	} else {
  1715  		ch := make(chan struct{})
  1716  		req.Cancel = ch
  1717  		close(ch)
  1718  	}
  1719  
  1720  	_, err := c.Do(req)
  1721  	if ue, ok := err.(*url.Error); ok {
  1722  		err = ue.Err
  1723  	}
  1724  	if withCtx {
  1725  		if err != context.Canceled {
  1726  			t.Errorf("Do error = %v; want %v", err, context.Canceled)
  1727  		}
  1728  	} else {
  1729  		if err == nil || !strings.Contains(err.Error(), "canceled") {
  1730  			t.Errorf("Do error = %v; want cancelation", err)
  1731  		}
  1732  	}
  1733  }
  1734  
  1735  // Issue 11020. The returned error message should be errRequestCanceled
  1736  func TestTransportCancelBeforeResponseHeaders(t *testing.T) {
  1737  	defer afterTest(t)
  1738  
  1739  	serverConnCh := make(chan net.Conn, 1)
  1740  	tr := &Transport{
  1741  		Dial: func(network, addr string) (net.Conn, error) {
  1742  			cc, sc := net.Pipe()
  1743  			serverConnCh <- sc
  1744  			return cc, nil
  1745  		},
  1746  	}
  1747  	defer tr.CloseIdleConnections()
  1748  	errc := make(chan error, 1)
  1749  	req, _ := NewRequest("GET", "http://example.com/", nil)
  1750  	go func() {
  1751  		_, err := tr.RoundTrip(req)
  1752  		errc <- err
  1753  	}()
  1754  
  1755  	sc := <-serverConnCh
  1756  	verb := make([]byte, 3)
  1757  	if _, err := io.ReadFull(sc, verb); err != nil {
  1758  		t.Errorf("Error reading HTTP verb from server: %v", err)
  1759  	}
  1760  	if string(verb) != "GET" {
  1761  		t.Errorf("server received %q; want GET", verb)
  1762  	}
  1763  	defer sc.Close()
  1764  
  1765  	tr.CancelRequest(req)
  1766  
  1767  	err := <-errc
  1768  	if err == nil {
  1769  		t.Fatalf("unexpected success from RoundTrip")
  1770  	}
  1771  	if err != ExportErrRequestCanceled {
  1772  		t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err)
  1773  	}
  1774  }
  1775  
  1776  // golang.org/issue/3672 -- Client can't close HTTP stream
  1777  // Calling Close on a Response.Body used to just read until EOF.
  1778  // Now it actually closes the TCP connection.
  1779  func TestTransportCloseResponseBody(t *testing.T) {
  1780  	defer afterTest(t)
  1781  	writeErr := make(chan error, 1)
  1782  	msg := []byte("young\n")
  1783  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1784  		for {
  1785  			_, err := w.Write(msg)
  1786  			if err != nil {
  1787  				writeErr <- err
  1788  				return
  1789  			}
  1790  			w.(Flusher).Flush()
  1791  		}
  1792  	}))
  1793  	defer ts.Close()
  1794  
  1795  	tr := &Transport{}
  1796  	defer tr.CloseIdleConnections()
  1797  	c := &Client{Transport: tr}
  1798  
  1799  	req, _ := NewRequest("GET", ts.URL, nil)
  1800  	defer tr.CancelRequest(req)
  1801  
  1802  	res, err := c.Do(req)
  1803  	if err != nil {
  1804  		t.Fatal(err)
  1805  	}
  1806  
  1807  	const repeats = 3
  1808  	buf := make([]byte, len(msg)*repeats)
  1809  	want := bytes.Repeat(msg, repeats)
  1810  
  1811  	_, err = io.ReadFull(res.Body, buf)
  1812  	if err != nil {
  1813  		t.Fatal(err)
  1814  	}
  1815  	if !bytes.Equal(buf, want) {
  1816  		t.Fatalf("read %q; want %q", buf, want)
  1817  	}
  1818  	didClose := make(chan error, 1)
  1819  	go func() {
  1820  		didClose <- res.Body.Close()
  1821  	}()
  1822  	select {
  1823  	case err := <-didClose:
  1824  		if err != nil {
  1825  			t.Errorf("Close = %v", err)
  1826  		}
  1827  	case <-time.After(10 * time.Second):
  1828  		t.Fatal("too long waiting for close")
  1829  	}
  1830  	select {
  1831  	case err := <-writeErr:
  1832  		if err == nil {
  1833  			t.Errorf("expected non-nil write error")
  1834  		}
  1835  	case <-time.After(10 * time.Second):
  1836  		t.Fatal("too long waiting for write error")
  1837  	}
  1838  }
  1839  
  1840  type fooProto struct{}
  1841  
  1842  func (fooProto) RoundTrip(req *Request) (*Response, error) {
  1843  	res := &Response{
  1844  		Status:     "200 OK",
  1845  		StatusCode: 200,
  1846  		Header:     make(Header),
  1847  		Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
  1848  	}
  1849  	return res, nil
  1850  }
  1851  
  1852  func TestTransportAltProto(t *testing.T) {
  1853  	defer afterTest(t)
  1854  	tr := &Transport{}
  1855  	c := &Client{Transport: tr}
  1856  	tr.RegisterProtocol("foo", fooProto{})
  1857  	res, err := c.Get("foo://bar.com/path")
  1858  	if err != nil {
  1859  		t.Fatal(err)
  1860  	}
  1861  	bodyb, err := ioutil.ReadAll(res.Body)
  1862  	if err != nil {
  1863  		t.Fatal(err)
  1864  	}
  1865  	body := string(bodyb)
  1866  	if e := "You wanted foo://bar.com/path"; body != e {
  1867  		t.Errorf("got response %q, want %q", body, e)
  1868  	}
  1869  }
  1870  
  1871  func TestTransportNoHost(t *testing.T) {
  1872  	defer afterTest(t)
  1873  	tr := &Transport{}
  1874  	_, err := tr.RoundTrip(&Request{
  1875  		Header: make(Header),
  1876  		URL: &url.URL{
  1877  			Scheme: "http",
  1878  		},
  1879  	})
  1880  	want := "http: no Host in request URL"
  1881  	if got := fmt.Sprint(err); got != want {
  1882  		t.Errorf("error = %v; want %q", err, want)
  1883  	}
  1884  }
  1885  
  1886  // Issue 13311
  1887  func TestTransportEmptyMethod(t *testing.T) {
  1888  	req, _ := NewRequest("GET", "http://foo.com/", nil)
  1889  	req.Method = ""                                 // docs say "For client requests an empty string means GET"
  1890  	got, err := httputil.DumpRequestOut(req, false) // DumpRequestOut uses Transport
  1891  	if err != nil {
  1892  		t.Fatal(err)
  1893  	}
  1894  	if !strings.Contains(string(got), "GET ") {
  1895  		t.Fatalf("expected substring 'GET '; got: %s", got)
  1896  	}
  1897  }
  1898  
  1899  func TestTransportSocketLateBinding(t *testing.T) {
  1900  	defer afterTest(t)
  1901  
  1902  	mux := NewServeMux()
  1903  	fooGate := make(chan bool, 1)
  1904  	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
  1905  		w.Header().Set("foo-ipport", r.RemoteAddr)
  1906  		w.(Flusher).Flush()
  1907  		<-fooGate
  1908  	})
  1909  	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
  1910  		w.Header().Set("bar-ipport", r.RemoteAddr)
  1911  	})
  1912  	ts := httptest.NewServer(mux)
  1913  	defer ts.Close()
  1914  
  1915  	dialGate := make(chan bool, 1)
  1916  	tr := &Transport{
  1917  		Dial: func(n, addr string) (net.Conn, error) {
  1918  			if <-dialGate {
  1919  				return net.Dial(n, addr)
  1920  			}
  1921  			return nil, errors.New("manually closed")
  1922  		},
  1923  		DisableKeepAlives: false,
  1924  	}
  1925  	defer tr.CloseIdleConnections()
  1926  	c := &Client{
  1927  		Transport: tr,
  1928  	}
  1929  
  1930  	dialGate <- true // only allow one dial
  1931  	fooRes, err := c.Get(ts.URL + "/foo")
  1932  	if err != nil {
  1933  		t.Fatal(err)
  1934  	}
  1935  	fooAddr := fooRes.Header.Get("foo-ipport")
  1936  	if fooAddr == "" {
  1937  		t.Fatal("No addr on /foo request")
  1938  	}
  1939  	time.AfterFunc(200*time.Millisecond, func() {
  1940  		// let the foo response finish so we can use its
  1941  		// connection for /bar
  1942  		fooGate <- true
  1943  		io.Copy(ioutil.Discard, fooRes.Body)
  1944  		fooRes.Body.Close()
  1945  	})
  1946  
  1947  	barRes, err := c.Get(ts.URL + "/bar")
  1948  	if err != nil {
  1949  		t.Fatal(err)
  1950  	}
  1951  	barAddr := barRes.Header.Get("bar-ipport")
  1952  	if barAddr != fooAddr {
  1953  		t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
  1954  	}
  1955  	barRes.Body.Close()
  1956  	dialGate <- false
  1957  }
  1958  
  1959  // Issue 2184
  1960  func TestTransportReading100Continue(t *testing.T) {
  1961  	defer afterTest(t)
  1962  
  1963  	const numReqs = 5
  1964  	reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
  1965  	reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
  1966  
  1967  	send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
  1968  		defer w.Close()
  1969  		defer r.Close()
  1970  		br := bufio.NewReader(r)
  1971  		n := 0
  1972  		for {
  1973  			n++
  1974  			req, err := ReadRequest(br)
  1975  			if err == io.EOF {
  1976  				return
  1977  			}
  1978  			if err != nil {
  1979  				t.Error(err)
  1980  				return
  1981  			}
  1982  			slurp, err := ioutil.ReadAll(req.Body)
  1983  			if err != nil {
  1984  				t.Errorf("Server request body slurp: %v", err)
  1985  				return
  1986  			}
  1987  			id := req.Header.Get("Request-Id")
  1988  			resCode := req.Header.Get("X-Want-Response-Code")
  1989  			if resCode == "" {
  1990  				resCode = "100 Continue"
  1991  				if string(slurp) != reqBody(n) {
  1992  					t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
  1993  				}
  1994  			}
  1995  			body := fmt.Sprintf("Response number %d", n)
  1996  			v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
  1997  Date: Thu, 28 Feb 2013 17:55:41 GMT
  1998  
  1999  HTTP/1.1 200 OK
  2000  Content-Type: text/html
  2001  Echo-Request-Id: %s
  2002  Content-Length: %d
  2003  
  2004  %s`, resCode, id, len(body), body), "\n", "\r\n", -1))
  2005  			w.Write(v)
  2006  			if id == reqID(numReqs) {
  2007  				return
  2008  			}
  2009  		}
  2010  
  2011  	}
  2012  
  2013  	tr := &Transport{
  2014  		Dial: func(n, addr string) (net.Conn, error) {
  2015  			sr, sw := io.Pipe() // server read/write
  2016  			cr, cw := io.Pipe() // client read/write
  2017  			conn := &rwTestConn{
  2018  				Reader: cr,
  2019  				Writer: sw,
  2020  				closeFunc: func() error {
  2021  					sw.Close()
  2022  					cw.Close()
  2023  					return nil
  2024  				},
  2025  			}
  2026  			go send100Response(cw, sr)
  2027  			return conn, nil
  2028  		},
  2029  		DisableKeepAlives: false,
  2030  	}
  2031  	defer tr.CloseIdleConnections()
  2032  	c := &Client{Transport: tr}
  2033  
  2034  	testResponse := func(req *Request, name string, wantCode int) {
  2035  		res, err := c.Do(req)
  2036  		if err != nil {
  2037  			t.Fatalf("%s: Do: %v", name, err)
  2038  		}
  2039  		if res.StatusCode != wantCode {
  2040  			t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
  2041  		}
  2042  		if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
  2043  			t.Errorf("%s: response id %q != request id %q", name, idBack, id)
  2044  		}
  2045  		_, err = ioutil.ReadAll(res.Body)
  2046  		if err != nil {
  2047  			t.Fatalf("%s: Slurp error: %v", name, err)
  2048  		}
  2049  	}
  2050  
  2051  	// Few 100 responses, making sure we're not off-by-one.
  2052  	for i := 1; i <= numReqs; i++ {
  2053  		req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
  2054  		req.Header.Set("Request-Id", reqID(i))
  2055  		testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
  2056  	}
  2057  
  2058  	// And some other informational 1xx but non-100 responses, to test
  2059  	// we return them but don't re-use the connection.
  2060  	for i := 1; i <= numReqs; i++ {
  2061  		req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i)))
  2062  		req.Header.Set("X-Want-Response-Code", "123 Sesame Street")
  2063  		testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123)
  2064  	}
  2065  }
  2066  
  2067  type proxyFromEnvTest struct {
  2068  	req string // URL to fetch; blank means "http://example.com"
  2069  
  2070  	env      string // HTTP_PROXY
  2071  	httpsenv string // HTTPS_PROXY
  2072  	noenv    string // NO_PROXY
  2073  	reqmeth  string // REQUEST_METHOD
  2074  
  2075  	want    string
  2076  	wanterr error
  2077  }
  2078  
  2079  func (t proxyFromEnvTest) String() string {
  2080  	var buf bytes.Buffer
  2081  	space := func() {
  2082  		if buf.Len() > 0 {
  2083  			buf.WriteByte(' ')
  2084  		}
  2085  	}
  2086  	if t.env != "" {
  2087  		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
  2088  	}
  2089  	if t.httpsenv != "" {
  2090  		space()
  2091  		fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv)
  2092  	}
  2093  	if t.noenv != "" {
  2094  		space()
  2095  		fmt.Fprintf(&buf, "no_proxy=%q", t.noenv)
  2096  	}
  2097  	if t.reqmeth != "" {
  2098  		space()
  2099  		fmt.Fprintf(&buf, "request_method=%q", t.reqmeth)
  2100  	}
  2101  	req := "http://example.com"
  2102  	if t.req != "" {
  2103  		req = t.req
  2104  	}
  2105  	space()
  2106  	fmt.Fprintf(&buf, "req=%q", req)
  2107  	return strings.TrimSpace(buf.String())
  2108  }
  2109  
  2110  var proxyFromEnvTests = []proxyFromEnvTest{
  2111  	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2112  	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
  2113  	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
  2114  	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
  2115  	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2116  	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
  2117  
  2118  	// Don't use secure for http
  2119  	{req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"},
  2120  	// Use secure for https.
  2121  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"},
  2122  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"},
  2123  
  2124  	// Issue 16405: don't use HTTP_PROXY in a CGI environment,
  2125  	// where HTTP_PROXY can be attacker-controlled.
  2126  	{env: "http://10.1.2.3:8080", reqmeth: "POST",
  2127  		want:    "<nil>",
  2128  		wanterr: errors.New("net/http: refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxy")},
  2129  
  2130  	{want: "<nil>"},
  2131  
  2132  	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  2133  	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  2134  	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2135  	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
  2136  	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2137  }
  2138  
  2139  func TestProxyFromEnvironment(t *testing.T) {
  2140  	ResetProxyEnv()
  2141  	for _, tt := range proxyFromEnvTests {
  2142  		os.Setenv("HTTP_PROXY", tt.env)
  2143  		os.Setenv("HTTPS_PROXY", tt.httpsenv)
  2144  		os.Setenv("NO_PROXY", tt.noenv)
  2145  		os.Setenv("REQUEST_METHOD", tt.reqmeth)
  2146  		ResetCachedEnvironment()
  2147  		reqURL := tt.req
  2148  		if reqURL == "" {
  2149  			reqURL = "http://example.com"
  2150  		}
  2151  		req, _ := NewRequest("GET", reqURL, nil)
  2152  		url, err := ProxyFromEnvironment(req)
  2153  		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
  2154  			t.Errorf("%v: got error = %q, want %q", tt, g, e)
  2155  			continue
  2156  		}
  2157  		if got := fmt.Sprintf("%s", url); got != tt.want {
  2158  			t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
  2159  		}
  2160  	}
  2161  }
  2162  
  2163  func TestIdleConnChannelLeak(t *testing.T) {
  2164  	var mu sync.Mutex
  2165  	var n int
  2166  
  2167  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2168  		mu.Lock()
  2169  		n++
  2170  		mu.Unlock()
  2171  	}))
  2172  	defer ts.Close()
  2173  
  2174  	const nReqs = 5
  2175  	didRead := make(chan bool, nReqs)
  2176  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
  2177  	defer SetReadLoopBeforeNextReadHook(nil)
  2178  
  2179  	tr := &Transport{
  2180  		Dial: func(netw, addr string) (net.Conn, error) {
  2181  			return net.Dial(netw, ts.Listener.Addr().String())
  2182  		},
  2183  	}
  2184  	defer tr.CloseIdleConnections()
  2185  
  2186  	c := &Client{Transport: tr}
  2187  
  2188  	// First, without keep-alives.
  2189  	for _, disableKeep := range []bool{true, false} {
  2190  		tr.DisableKeepAlives = disableKeep
  2191  		for i := 0; i < nReqs; i++ {
  2192  			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
  2193  			if err != nil {
  2194  				t.Fatal(err)
  2195  			}
  2196  			// Note: no res.Body.Close is needed here, since the
  2197  			// response Content-Length is zero. Perhaps the test
  2198  			// should be more explicit and use a HEAD, but tests
  2199  			// elsewhere guarantee that zero byte responses generate
  2200  			// a "Content-Length: 0" instead of chunking.
  2201  		}
  2202  
  2203  		// At this point, each of the 5 Transport.readLoop goroutines
  2204  		// are scheduling noting that there are no response bodies (see
  2205  		// earlier comment), and are then calling putIdleConn, which
  2206  		// decrements this count. Usually that happens quickly, which is
  2207  		// why this test has seemed to work for ages. But it's still
  2208  		// racey: we have wait for them to finish first. See Issue 10427
  2209  		for i := 0; i < nReqs; i++ {
  2210  			<-didRead
  2211  		}
  2212  
  2213  		if got := tr.IdleConnChMapSizeForTesting(); got != 0 {
  2214  			t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
  2215  		}
  2216  	}
  2217  }
  2218  
  2219  // Verify the status quo: that the Client.Post function coerces its
  2220  // body into a ReadCloser if it's a Closer, and that the Transport
  2221  // then closes it.
  2222  func TestTransportClosesRequestBody(t *testing.T) {
  2223  	defer afterTest(t)
  2224  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2225  		io.Copy(ioutil.Discard, r.Body)
  2226  	}))
  2227  	defer ts.Close()
  2228  
  2229  	tr := &Transport{}
  2230  	defer tr.CloseIdleConnections()
  2231  	cl := &Client{Transport: tr}
  2232  
  2233  	closes := 0
  2234  
  2235  	res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
  2236  	if err != nil {
  2237  		t.Fatal(err)
  2238  	}
  2239  	res.Body.Close()
  2240  	if closes != 1 {
  2241  		t.Errorf("closes = %d; want 1", closes)
  2242  	}
  2243  }
  2244  
  2245  func TestTransportTLSHandshakeTimeout(t *testing.T) {
  2246  	defer afterTest(t)
  2247  	if testing.Short() {
  2248  		t.Skip("skipping in short mode")
  2249  	}
  2250  	ln := newLocalListener(t)
  2251  	defer ln.Close()
  2252  	testdonec := make(chan struct{})
  2253  	defer close(testdonec)
  2254  
  2255  	go func() {
  2256  		c, err := ln.Accept()
  2257  		if err != nil {
  2258  			t.Error(err)
  2259  			return
  2260  		}
  2261  		<-testdonec
  2262  		c.Close()
  2263  	}()
  2264  
  2265  	getdonec := make(chan struct{})
  2266  	go func() {
  2267  		defer close(getdonec)
  2268  		tr := &Transport{
  2269  			Dial: func(_, _ string) (net.Conn, error) {
  2270  				return net.Dial("tcp", ln.Addr().String())
  2271  			},
  2272  			TLSHandshakeTimeout: 250 * time.Millisecond,
  2273  		}
  2274  		cl := &Client{Transport: tr}
  2275  		_, err := cl.Get("https://dummy.tld/")
  2276  		if err == nil {
  2277  			t.Error("expected error")
  2278  			return
  2279  		}
  2280  		ue, ok := err.(*url.Error)
  2281  		if !ok {
  2282  			t.Errorf("expected url.Error; got %#v", err)
  2283  			return
  2284  		}
  2285  		ne, ok := ue.Err.(net.Error)
  2286  		if !ok {
  2287  			t.Errorf("expected net.Error; got %#v", err)
  2288  			return
  2289  		}
  2290  		if !ne.Timeout() {
  2291  			t.Errorf("expected timeout error; got %v", err)
  2292  		}
  2293  		if !strings.Contains(err.Error(), "handshake timeout") {
  2294  			t.Errorf("expected 'handshake timeout' in error; got %v", err)
  2295  		}
  2296  	}()
  2297  	select {
  2298  	case <-getdonec:
  2299  	case <-time.After(5 * time.Second):
  2300  		t.Error("test timeout; TLS handshake hung?")
  2301  	}
  2302  }
  2303  
  2304  // Trying to repro golang.org/issue/3514
  2305  func TestTLSServerClosesConnection(t *testing.T) {
  2306  	defer afterTest(t)
  2307  	testenv.SkipFlaky(t, 7634)
  2308  
  2309  	closedc := make(chan bool, 1)
  2310  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2311  		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
  2312  			conn, _, _ := w.(Hijacker).Hijack()
  2313  			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
  2314  			conn.Close()
  2315  			closedc <- true
  2316  			return
  2317  		}
  2318  		fmt.Fprintf(w, "hello")
  2319  	}))
  2320  	defer ts.Close()
  2321  	tr := &Transport{
  2322  		TLSClientConfig: &tls.Config{
  2323  			InsecureSkipVerify: true,
  2324  		},
  2325  	}
  2326  	defer tr.CloseIdleConnections()
  2327  	client := &Client{Transport: tr}
  2328  
  2329  	var nSuccess = 0
  2330  	var errs []error
  2331  	const trials = 20
  2332  	for i := 0; i < trials; i++ {
  2333  		tr.CloseIdleConnections()
  2334  		res, err := client.Get(ts.URL + "/keep-alive-then-die")
  2335  		if err != nil {
  2336  			t.Fatal(err)
  2337  		}
  2338  		<-closedc
  2339  		slurp, err := ioutil.ReadAll(res.Body)
  2340  		if err != nil {
  2341  			t.Fatal(err)
  2342  		}
  2343  		if string(slurp) != "foo" {
  2344  			t.Errorf("Got %q, want foo", slurp)
  2345  		}
  2346  
  2347  		// Now try again and see if we successfully
  2348  		// pick a new connection.
  2349  		res, err = client.Get(ts.URL + "/")
  2350  		if err != nil {
  2351  			errs = append(errs, err)
  2352  			continue
  2353  		}
  2354  		slurp, err = ioutil.ReadAll(res.Body)
  2355  		if err != nil {
  2356  			errs = append(errs, err)
  2357  			continue
  2358  		}
  2359  		nSuccess++
  2360  	}
  2361  	if nSuccess > 0 {
  2362  		t.Logf("successes = %d of %d", nSuccess, trials)
  2363  	} else {
  2364  		t.Errorf("All runs failed:")
  2365  	}
  2366  	for _, err := range errs {
  2367  		t.Logf("  err: %v", err)
  2368  	}
  2369  }
  2370  
  2371  // byteFromChanReader is an io.Reader that reads a single byte at a
  2372  // time from the channel. When the channel is closed, the reader
  2373  // returns io.EOF.
  2374  type byteFromChanReader chan byte
  2375  
  2376  func (c byteFromChanReader) Read(p []byte) (n int, err error) {
  2377  	if len(p) == 0 {
  2378  		return
  2379  	}
  2380  	b, ok := <-c
  2381  	if !ok {
  2382  		return 0, io.EOF
  2383  	}
  2384  	p[0] = b
  2385  	return 1, nil
  2386  }
  2387  
  2388  // Verifies that the Transport doesn't reuse a connection in the case
  2389  // where the server replies before the request has been fully
  2390  // written. We still honor that reply (see TestIssue3595), but don't
  2391  // send future requests on the connection because it's then in a
  2392  // questionable state.
  2393  // golang.org/issue/7569
  2394  func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
  2395  	defer afterTest(t)
  2396  	var sconn struct {
  2397  		sync.Mutex
  2398  		c net.Conn
  2399  	}
  2400  	var getOkay bool
  2401  	closeConn := func() {
  2402  		sconn.Lock()
  2403  		defer sconn.Unlock()
  2404  		if sconn.c != nil {
  2405  			sconn.c.Close()
  2406  			sconn.c = nil
  2407  			if !getOkay {
  2408  				t.Logf("Closed server connection")
  2409  			}
  2410  		}
  2411  	}
  2412  	defer closeConn()
  2413  
  2414  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2415  		if r.Method == "GET" {
  2416  			io.WriteString(w, "bar")
  2417  			return
  2418  		}
  2419  		conn, _, _ := w.(Hijacker).Hijack()
  2420  		sconn.Lock()
  2421  		sconn.c = conn
  2422  		sconn.Unlock()
  2423  		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
  2424  		go io.Copy(ioutil.Discard, conn)
  2425  	}))
  2426  	defer ts.Close()
  2427  	tr := &Transport{}
  2428  	defer tr.CloseIdleConnections()
  2429  	client := &Client{Transport: tr}
  2430  
  2431  	const bodySize = 256 << 10
  2432  	finalBit := make(byteFromChanReader, 1)
  2433  	req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
  2434  	req.ContentLength = bodySize
  2435  	res, err := client.Do(req)
  2436  	if err := wantBody(res, err, "foo"); err != nil {
  2437  		t.Errorf("POST response: %v", err)
  2438  	}
  2439  	donec := make(chan bool)
  2440  	go func() {
  2441  		defer close(donec)
  2442  		res, err = client.Get(ts.URL)
  2443  		if err := wantBody(res, err, "bar"); err != nil {
  2444  			t.Errorf("GET response: %v", err)
  2445  			return
  2446  		}
  2447  		getOkay = true // suppress test noise
  2448  	}()
  2449  	time.AfterFunc(5*time.Second, closeConn)
  2450  	select {
  2451  	case <-donec:
  2452  		finalBit <- 'x' // unblock the writeloop of the first Post
  2453  		close(finalBit)
  2454  	case <-time.After(7 * time.Second):
  2455  		t.Fatal("timeout waiting for GET request to finish")
  2456  	}
  2457  }
  2458  
  2459  // Tests that we don't leak Transport persistConn.readLoop goroutines
  2460  // when a server hangs up immediately after saying it would keep-alive.
  2461  func TestTransportIssue10457(t *testing.T) {
  2462  	defer afterTest(t) // used to fail in goroutine leak check
  2463  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2464  		// Send a response with no body, keep-alive
  2465  		// (implicit), and then lie and immediately close the
  2466  		// connection. This forces the Transport's readLoop to
  2467  		// immediately Peek an io.EOF and get to the point
  2468  		// that used to hang.
  2469  		conn, _, _ := w.(Hijacker).Hijack()
  2470  		conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
  2471  		conn.Close()
  2472  	}))
  2473  	defer ts.Close()
  2474  	tr := &Transport{}
  2475  	defer tr.CloseIdleConnections()
  2476  	cl := &Client{Transport: tr}
  2477  	res, err := cl.Get(ts.URL)
  2478  	if err != nil {
  2479  		t.Fatalf("Get: %v", err)
  2480  	}
  2481  	defer res.Body.Close()
  2482  
  2483  	// Just a sanity check that we at least get the response. The real
  2484  	// test here is that the "defer afterTest" above doesn't find any
  2485  	// leaked goroutines.
  2486  	if got, want := res.Header.Get("Foo"), "Bar"; got != want {
  2487  		t.Errorf("Foo header = %q; want %q", got, want)
  2488  	}
  2489  }
  2490  
  2491  type errorReader struct {
  2492  	err error
  2493  }
  2494  
  2495  func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
  2496  
  2497  type plan9SleepReader struct{}
  2498  
  2499  func (plan9SleepReader) Read(p []byte) (int, error) {
  2500  	if runtime.GOOS == "plan9" {
  2501  		// After the fix to unblock TCP Reads in
  2502  		// https://golang.org/cl/15941, this sleep is required
  2503  		// on plan9 to make sure TCP Writes before an
  2504  		// immediate TCP close go out on the wire. On Plan 9,
  2505  		// it seems that a hangup of a TCP connection with
  2506  		// queued data doesn't send the queued data first.
  2507  		// https://golang.org/issue/9554
  2508  		time.Sleep(50 * time.Millisecond)
  2509  	}
  2510  	return 0, io.EOF
  2511  }
  2512  
  2513  type closerFunc func() error
  2514  
  2515  func (f closerFunc) Close() error { return f() }
  2516  
  2517  // Issue 4677. If we try to reuse a connection that the server is in the
  2518  // process of closing, we may end up successfully writing out our request (or a
  2519  // portion of our request) only to find a connection error when we try to read
  2520  // from (or finish writing to) the socket.
  2521  //
  2522  // NOTE: we resend a request only if the request is idempotent, we reused a
  2523  // keep-alive connection, and we haven't yet received any header data. This
  2524  // automatically prevents an infinite resend loop because we'll run out of the
  2525  // cached keep-alive connections eventually.
  2526  func TestRetryIdempotentRequestsOnError(t *testing.T) {
  2527  	defer afterTest(t)
  2528  
  2529  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2530  	}))
  2531  	defer ts.Close()
  2532  
  2533  	tr := &Transport{}
  2534  	c := &Client{Transport: tr}
  2535  
  2536  	const N = 2
  2537  	retryc := make(chan struct{}, N)
  2538  	SetRoundTripRetried(func() {
  2539  		retryc <- struct{}{}
  2540  	})
  2541  	defer SetRoundTripRetried(nil)
  2542  
  2543  	for n := 0; n < 100; n++ {
  2544  		// open 2 conns
  2545  		errc := make(chan error, N)
  2546  		for i := 0; i < N; i++ {
  2547  			// start goroutines, send on errc
  2548  			go func() {
  2549  				res, err := c.Get(ts.URL)
  2550  				if err == nil {
  2551  					res.Body.Close()
  2552  				}
  2553  				errc <- err
  2554  			}()
  2555  		}
  2556  		for i := 0; i < N; i++ {
  2557  			if err := <-errc; err != nil {
  2558  				t.Fatal(err)
  2559  			}
  2560  		}
  2561  
  2562  		ts.CloseClientConnections()
  2563  		for i := 0; i < N; i++ {
  2564  			go func() {
  2565  				res, err := c.Get(ts.URL)
  2566  				if err == nil {
  2567  					res.Body.Close()
  2568  				}
  2569  				errc <- err
  2570  			}()
  2571  		}
  2572  
  2573  		for i := 0; i < N; i++ {
  2574  			if err := <-errc; err != nil {
  2575  				t.Fatal(err)
  2576  			}
  2577  		}
  2578  		for i := 0; i < N; i++ {
  2579  			select {
  2580  			case <-retryc:
  2581  				// we triggered a retry, test was successful
  2582  				t.Logf("finished after %d runs\n", n)
  2583  				return
  2584  			default:
  2585  			}
  2586  		}
  2587  	}
  2588  	t.Fatal("did not trigger any retries")
  2589  }
  2590  
  2591  // Issue 6981
  2592  func TestTransportClosesBodyOnError(t *testing.T) {
  2593  	setParallel(t)
  2594  	defer afterTest(t)
  2595  	readBody := make(chan error, 1)
  2596  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2597  		_, err := ioutil.ReadAll(r.Body)
  2598  		readBody <- err
  2599  	}))
  2600  	defer ts.Close()
  2601  	fakeErr := errors.New("fake error")
  2602  	didClose := make(chan bool, 1)
  2603  	req, _ := NewRequest("POST", ts.URL, struct {
  2604  		io.Reader
  2605  		io.Closer
  2606  	}{
  2607  		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), plan9SleepReader{}, errorReader{fakeErr}),
  2608  		closerFunc(func() error {
  2609  			select {
  2610  			case didClose <- true:
  2611  			default:
  2612  			}
  2613  			return nil
  2614  		}),
  2615  	})
  2616  	res, err := DefaultClient.Do(req)
  2617  	if res != nil {
  2618  		defer res.Body.Close()
  2619  	}
  2620  	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
  2621  		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
  2622  	}
  2623  	select {
  2624  	case err := <-readBody:
  2625  		if err == nil {
  2626  			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
  2627  		}
  2628  	case <-time.After(5 * time.Second):
  2629  		t.Error("timeout waiting for server handler to complete")
  2630  	}
  2631  	select {
  2632  	case <-didClose:
  2633  	default:
  2634  		t.Errorf("didn't see Body.Close")
  2635  	}
  2636  }
  2637  
  2638  func TestTransportDialTLS(t *testing.T) {
  2639  	var mu sync.Mutex // guards following
  2640  	var gotReq, didDial bool
  2641  
  2642  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2643  		mu.Lock()
  2644  		gotReq = true
  2645  		mu.Unlock()
  2646  	}))
  2647  	defer ts.Close()
  2648  	tr := &Transport{
  2649  		DialTLS: func(netw, addr string) (net.Conn, error) {
  2650  			mu.Lock()
  2651  			didDial = true
  2652  			mu.Unlock()
  2653  			c, err := tls.Dial(netw, addr, &tls.Config{
  2654  				InsecureSkipVerify: true,
  2655  			})
  2656  			if err != nil {
  2657  				return nil, err
  2658  			}
  2659  			return c, c.Handshake()
  2660  		},
  2661  	}
  2662  	defer tr.CloseIdleConnections()
  2663  	client := &Client{Transport: tr}
  2664  	res, err := client.Get(ts.URL)
  2665  	if err != nil {
  2666  		t.Fatal(err)
  2667  	}
  2668  	res.Body.Close()
  2669  	mu.Lock()
  2670  	if !gotReq {
  2671  		t.Error("didn't get request")
  2672  	}
  2673  	if !didDial {
  2674  		t.Error("didn't use dial hook")
  2675  	}
  2676  }
  2677  
  2678  // Test for issue 8755
  2679  // Ensure that if a proxy returns an error, it is exposed by RoundTrip
  2680  func TestRoundTripReturnsProxyError(t *testing.T) {
  2681  	badProxy := func(*Request) (*url.URL, error) {
  2682  		return nil, errors.New("errorMessage")
  2683  	}
  2684  
  2685  	tr := &Transport{Proxy: badProxy}
  2686  
  2687  	req, _ := NewRequest("GET", "http://example.com", nil)
  2688  
  2689  	_, err := tr.RoundTrip(req)
  2690  
  2691  	if err == nil {
  2692  		t.Error("Expected proxy error to be returned by RoundTrip")
  2693  	}
  2694  }
  2695  
  2696  // tests that putting an idle conn after a call to CloseIdleConns does return it
  2697  func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
  2698  	tr := &Transport{}
  2699  	wantIdle := func(when string, n int) bool {
  2700  		got := tr.IdleConnCountForTesting("|http|example.com") // key used by PutIdleTestConn
  2701  		if got == n {
  2702  			return true
  2703  		}
  2704  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  2705  		return false
  2706  	}
  2707  	wantIdle("start", 0)
  2708  	if !tr.PutIdleTestConn() {
  2709  		t.Fatal("put failed")
  2710  	}
  2711  	if !tr.PutIdleTestConn() {
  2712  		t.Fatal("second put failed")
  2713  	}
  2714  	wantIdle("after put", 2)
  2715  	tr.CloseIdleConnections()
  2716  	if !tr.IsIdleForTesting() {
  2717  		t.Error("should be idle after CloseIdleConnections")
  2718  	}
  2719  	wantIdle("after close idle", 0)
  2720  	if tr.PutIdleTestConn() {
  2721  		t.Fatal("put didn't fail")
  2722  	}
  2723  	wantIdle("after second put", 0)
  2724  
  2725  	tr.RequestIdleConnChForTesting() // should toggle the transport out of idle mode
  2726  	if tr.IsIdleForTesting() {
  2727  		t.Error("shouldn't be idle after RequestIdleConnChForTesting")
  2728  	}
  2729  	if !tr.PutIdleTestConn() {
  2730  		t.Fatal("after re-activation")
  2731  	}
  2732  	wantIdle("after final put", 1)
  2733  }
  2734  
  2735  // This tests that an client requesting a content range won't also
  2736  // implicitly ask for gzip support. If they want that, they need to do it
  2737  // on their own.
  2738  // golang.org/issue/8923
  2739  func TestTransportRangeAndGzip(t *testing.T) {
  2740  	defer afterTest(t)
  2741  	reqc := make(chan *Request, 1)
  2742  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2743  		reqc <- r
  2744  	}))
  2745  	defer ts.Close()
  2746  
  2747  	req, _ := NewRequest("GET", ts.URL, nil)
  2748  	req.Header.Set("Range", "bytes=7-11")
  2749  	res, err := DefaultClient.Do(req)
  2750  	if err != nil {
  2751  		t.Fatal(err)
  2752  	}
  2753  
  2754  	select {
  2755  	case r := <-reqc:
  2756  		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  2757  			t.Error("Transport advertised gzip support in the Accept header")
  2758  		}
  2759  		if r.Header.Get("Range") == "" {
  2760  			t.Error("no Range in request")
  2761  		}
  2762  	case <-time.After(10 * time.Second):
  2763  		t.Fatal("timeout")
  2764  	}
  2765  	res.Body.Close()
  2766  }
  2767  
  2768  // Test for issue 10474
  2769  func TestTransportResponseCancelRace(t *testing.T) {
  2770  	defer afterTest(t)
  2771  
  2772  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2773  		// important that this response has a body.
  2774  		var b [1024]byte
  2775  		w.Write(b[:])
  2776  	}))
  2777  	defer ts.Close()
  2778  
  2779  	tr := &Transport{}
  2780  	defer tr.CloseIdleConnections()
  2781  
  2782  	req, err := NewRequest("GET", ts.URL, nil)
  2783  	if err != nil {
  2784  		t.Fatal(err)
  2785  	}
  2786  	res, err := tr.RoundTrip(req)
  2787  	if err != nil {
  2788  		t.Fatal(err)
  2789  	}
  2790  	// If we do an early close, Transport just throws the connection away and
  2791  	// doesn't reuse it. In order to trigger the bug, it has to reuse the connection
  2792  	// so read the body
  2793  	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
  2794  		t.Fatal(err)
  2795  	}
  2796  
  2797  	req2, err := NewRequest("GET", ts.URL, nil)
  2798  	if err != nil {
  2799  		t.Fatal(err)
  2800  	}
  2801  	tr.CancelRequest(req)
  2802  	res, err = tr.RoundTrip(req2)
  2803  	if err != nil {
  2804  		t.Fatal(err)
  2805  	}
  2806  	res.Body.Close()
  2807  }
  2808  
  2809  func TestTransportDialCancelRace(t *testing.T) {
  2810  	defer afterTest(t)
  2811  
  2812  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  2813  	defer ts.Close()
  2814  
  2815  	tr := &Transport{}
  2816  	defer tr.CloseIdleConnections()
  2817  
  2818  	req, err := NewRequest("GET", ts.URL, nil)
  2819  	if err != nil {
  2820  		t.Fatal(err)
  2821  	}
  2822  	SetEnterRoundTripHook(func() {
  2823  		tr.CancelRequest(req)
  2824  	})
  2825  	defer SetEnterRoundTripHook(nil)
  2826  	res, err := tr.RoundTrip(req)
  2827  	if err != ExportErrRequestCanceled {
  2828  		t.Errorf("expected canceled request error; got %v", err)
  2829  		if err == nil {
  2830  			res.Body.Close()
  2831  		}
  2832  	}
  2833  }
  2834  
  2835  // logWritesConn is a net.Conn that logs each Write call to writes
  2836  // and then proxies to w.
  2837  // It proxies Read calls to a reader it receives from rch.
  2838  type logWritesConn struct {
  2839  	net.Conn // nil. crash on use.
  2840  
  2841  	w io.Writer
  2842  
  2843  	rch <-chan io.Reader
  2844  	r   io.Reader // nil until received by rch
  2845  
  2846  	mu     sync.Mutex
  2847  	writes []string
  2848  }
  2849  
  2850  func (c *logWritesConn) Write(p []byte) (n int, err error) {
  2851  	c.mu.Lock()
  2852  	defer c.mu.Unlock()
  2853  	c.writes = append(c.writes, string(p))
  2854  	return c.w.Write(p)
  2855  }
  2856  
  2857  func (c *logWritesConn) Read(p []byte) (n int, err error) {
  2858  	if c.r == nil {
  2859  		c.r = <-c.rch
  2860  	}
  2861  	return c.r.Read(p)
  2862  }
  2863  
  2864  func (c *logWritesConn) Close() error { return nil }
  2865  
  2866  // Issue 6574
  2867  func TestTransportFlushesBodyChunks(t *testing.T) {
  2868  	defer afterTest(t)
  2869  	resBody := make(chan io.Reader, 1)
  2870  	connr, connw := io.Pipe() // connection pipe pair
  2871  	lw := &logWritesConn{
  2872  		rch: resBody,
  2873  		w:   connw,
  2874  	}
  2875  	tr := &Transport{
  2876  		Dial: func(network, addr string) (net.Conn, error) {
  2877  			return lw, nil
  2878  		},
  2879  	}
  2880  	bodyr, bodyw := io.Pipe() // body pipe pair
  2881  	go func() {
  2882  		defer bodyw.Close()
  2883  		for i := 0; i < 3; i++ {
  2884  			fmt.Fprintf(bodyw, "num%d\n", i)
  2885  		}
  2886  	}()
  2887  	resc := make(chan *Response)
  2888  	go func() {
  2889  		req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
  2890  		req.Header.Set("User-Agent", "x") // known value for test
  2891  		res, err := tr.RoundTrip(req)
  2892  		if err != nil {
  2893  			t.Errorf("RoundTrip: %v", err)
  2894  			close(resc)
  2895  			return
  2896  		}
  2897  		resc <- res
  2898  
  2899  	}()
  2900  	// Fully consume the request before checking the Write log vs. want.
  2901  	req, err := ReadRequest(bufio.NewReader(connr))
  2902  	if err != nil {
  2903  		t.Fatal(err)
  2904  	}
  2905  	io.Copy(ioutil.Discard, req.Body)
  2906  
  2907  	// Unblock the transport's roundTrip goroutine.
  2908  	resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
  2909  	res, ok := <-resc
  2910  	if !ok {
  2911  		return
  2912  	}
  2913  	defer res.Body.Close()
  2914  
  2915  	want := []string{
  2916  		// Because Request.ContentLength = 0, the body is sniffed for 1 byte to determine whether there's content.
  2917  		// That explains the initial "num0" being split into "n" and "um0".
  2918  		// The first byte is included with the request headers Write. Perhaps in the future
  2919  		// we will want to flush the headers out early if the first byte of the request body is
  2920  		// taking a long time to arrive. But not yet.
  2921  		"POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n" +
  2922  			"1\r\nn\r\n",
  2923  		"4\r\num0\n\r\n",
  2924  		"5\r\nnum1\n\r\n",
  2925  		"5\r\nnum2\n\r\n",
  2926  		"0\r\n\r\n",
  2927  	}
  2928  	if !reflect.DeepEqual(lw.writes, want) {
  2929  		t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
  2930  	}
  2931  }
  2932  
  2933  // Issue 11745.
  2934  func TestTransportPrefersResponseOverWriteError(t *testing.T) {
  2935  	if testing.Short() {
  2936  		t.Skip("skipping in short mode")
  2937  	}
  2938  	defer afterTest(t)
  2939  	const contentLengthLimit = 1024 * 1024 // 1MB
  2940  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2941  		if r.ContentLength >= contentLengthLimit {
  2942  			w.WriteHeader(StatusBadRequest)
  2943  			r.Body.Close()
  2944  			return
  2945  		}
  2946  		w.WriteHeader(StatusOK)
  2947  	}))
  2948  	defer ts.Close()
  2949  
  2950  	fail := 0
  2951  	count := 100
  2952  	bigBody := strings.Repeat("a", contentLengthLimit*2)
  2953  	for i := 0; i < count; i++ {
  2954  		req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
  2955  		if err != nil {
  2956  			t.Fatal(err)
  2957  		}
  2958  		tr := new(Transport)
  2959  		defer tr.CloseIdleConnections()
  2960  		client := &Client{Transport: tr}
  2961  		resp, err := client.Do(req)
  2962  		if err != nil {
  2963  			fail++
  2964  			t.Logf("%d = %#v", i, err)
  2965  			if ue, ok := err.(*url.Error); ok {
  2966  				t.Logf("urlErr = %#v", ue.Err)
  2967  				if ne, ok := ue.Err.(*net.OpError); ok {
  2968  					t.Logf("netOpError = %#v", ne.Err)
  2969  				}
  2970  			}
  2971  		} else {
  2972  			resp.Body.Close()
  2973  			if resp.StatusCode != 400 {
  2974  				t.Errorf("Expected status code 400, got %v", resp.Status)
  2975  			}
  2976  		}
  2977  	}
  2978  	if fail > 0 {
  2979  		t.Errorf("Failed %v out of %v\n", fail, count)
  2980  	}
  2981  }
  2982  
  2983  func TestTransportAutomaticHTTP2(t *testing.T) {
  2984  	testTransportAutoHTTP(t, &Transport{}, true)
  2985  }
  2986  
  2987  // golang.org/issue/14391: also check DefaultTransport
  2988  func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
  2989  	testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
  2990  }
  2991  
  2992  func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
  2993  	testTransportAutoHTTP(t, &Transport{
  2994  		TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
  2995  	}, false)
  2996  }
  2997  
  2998  func TestTransportAutomaticHTTP2_TLSConfig(t *testing.T) {
  2999  	testTransportAutoHTTP(t, &Transport{
  3000  		TLSClientConfig: new(tls.Config),
  3001  	}, false)
  3002  }
  3003  
  3004  func TestTransportAutomaticHTTP2_ExpectContinueTimeout(t *testing.T) {
  3005  	testTransportAutoHTTP(t, &Transport{
  3006  		ExpectContinueTimeout: 1 * time.Second,
  3007  	}, true)
  3008  }
  3009  
  3010  func TestTransportAutomaticHTTP2_Dial(t *testing.T) {
  3011  	var d net.Dialer
  3012  	testTransportAutoHTTP(t, &Transport{
  3013  		Dial: d.Dial,
  3014  	}, false)
  3015  }
  3016  
  3017  func TestTransportAutomaticHTTP2_DialTLS(t *testing.T) {
  3018  	testTransportAutoHTTP(t, &Transport{
  3019  		DialTLS: func(network, addr string) (net.Conn, error) {
  3020  			panic("unused")
  3021  		},
  3022  	}, false)
  3023  }
  3024  
  3025  func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) {
  3026  	_, err := tr.RoundTrip(new(Request))
  3027  	if err == nil {
  3028  		t.Error("expected error from RoundTrip")
  3029  	}
  3030  	if reg := tr.TLSNextProto["h2"] != nil; reg != wantH2 {
  3031  		t.Errorf("HTTP/2 registered = %v; want %v", reg, wantH2)
  3032  	}
  3033  }
  3034  
  3035  // Issue 13633: there was a race where we returned bodyless responses
  3036  // to callers before recycling the persistent connection, which meant
  3037  // a client doing two subsequent requests could end up on different
  3038  // connections. It's somewhat harmless but enough tests assume it's
  3039  // not true in order to test other things that it's worth fixing.
  3040  // Plus it's nice to be consistent and not have timing-dependent
  3041  // behavior.
  3042  func TestTransportReuseConnEmptyResponseBody(t *testing.T) {
  3043  	defer afterTest(t)
  3044  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  3045  		w.Header().Set("X-Addr", r.RemoteAddr)
  3046  		// Empty response body.
  3047  	}))
  3048  	defer cst.close()
  3049  	n := 100
  3050  	if testing.Short() {
  3051  		n = 10
  3052  	}
  3053  	var firstAddr string
  3054  	for i := 0; i < n; i++ {
  3055  		res, err := cst.c.Get(cst.ts.URL)
  3056  		if err != nil {
  3057  			log.Fatal(err)
  3058  		}
  3059  		addr := res.Header.Get("X-Addr")
  3060  		if i == 0 {
  3061  			firstAddr = addr
  3062  		} else if addr != firstAddr {
  3063  			t.Fatalf("On request %d, addr %q != original addr %q", i+1, addr, firstAddr)
  3064  		}
  3065  		res.Body.Close()
  3066  	}
  3067  }
  3068  
  3069  // Issue 13839
  3070  func TestNoCrashReturningTransportAltConn(t *testing.T) {
  3071  	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
  3072  	if err != nil {
  3073  		t.Fatal(err)
  3074  	}
  3075  	ln := newLocalListener(t)
  3076  	defer ln.Close()
  3077  
  3078  	handledPendingDial := make(chan bool, 1)
  3079  	SetPendingDialHooks(nil, func() { handledPendingDial <- true })
  3080  	defer SetPendingDialHooks(nil, nil)
  3081  
  3082  	testDone := make(chan struct{})
  3083  	defer close(testDone)
  3084  	go func() {
  3085  		tln := tls.NewListener(ln, &tls.Config{
  3086  			NextProtos:   []string{"foo"},
  3087  			Certificates: []tls.Certificate{cert},
  3088  		})
  3089  		sc, err := tln.Accept()
  3090  		if err != nil {
  3091  			t.Error(err)
  3092  			return
  3093  		}
  3094  		if err := sc.(*tls.Conn).Handshake(); err != nil {
  3095  			t.Error(err)
  3096  			return
  3097  		}
  3098  		<-testDone
  3099  		sc.Close()
  3100  	}()
  3101  
  3102  	addr := ln.Addr().String()
  3103  
  3104  	req, _ := NewRequest("GET", "https://fake.tld/", nil)
  3105  	cancel := make(chan struct{})
  3106  	req.Cancel = cancel
  3107  
  3108  	doReturned := make(chan bool, 1)
  3109  	madeRoundTripper := make(chan bool, 1)
  3110  
  3111  	tr := &Transport{
  3112  		DisableKeepAlives: true,
  3113  		TLSNextProto: map[string]func(string, *tls.Conn) RoundTripper{
  3114  			"foo": func(authority string, c *tls.Conn) RoundTripper {
  3115  				madeRoundTripper <- true
  3116  				return funcRoundTripper(func() {
  3117  					t.Error("foo RoundTripper should not be called")
  3118  				})
  3119  			},
  3120  		},
  3121  		Dial: func(_, _ string) (net.Conn, error) {
  3122  			panic("shouldn't be called")
  3123  		},
  3124  		DialTLS: func(_, _ string) (net.Conn, error) {
  3125  			tc, err := tls.Dial("tcp", addr, &tls.Config{
  3126  				InsecureSkipVerify: true,
  3127  				NextProtos:         []string{"foo"},
  3128  			})
  3129  			if err != nil {
  3130  				return nil, err
  3131  			}
  3132  			if err := tc.Handshake(); err != nil {
  3133  				return nil, err
  3134  			}
  3135  			close(cancel)
  3136  			<-doReturned
  3137  			return tc, nil
  3138  		},
  3139  	}
  3140  	c := &Client{Transport: tr}
  3141  
  3142  	_, err = c.Do(req)
  3143  	if ue, ok := err.(*url.Error); !ok || ue.Err != ExportErrRequestCanceledConn {
  3144  		t.Fatalf("Do error = %v; want url.Error with errRequestCanceledConn", err)
  3145  	}
  3146  
  3147  	doReturned <- true
  3148  	<-madeRoundTripper
  3149  	<-handledPendingDial
  3150  }
  3151  
  3152  func TestTransportReuseConnection_Gzip_Chunked(t *testing.T) {
  3153  	testTransportReuseConnection_Gzip(t, true)
  3154  }
  3155  
  3156  func TestTransportReuseConnection_Gzip_ContentLength(t *testing.T) {
  3157  	testTransportReuseConnection_Gzip(t, false)
  3158  }
  3159  
  3160  // Make sure we re-use underlying TCP connection for gzipped responses too.
  3161  func testTransportReuseConnection_Gzip(t *testing.T, chunked bool) {
  3162  	defer afterTest(t)
  3163  	addr := make(chan string, 2)
  3164  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3165  		addr <- r.RemoteAddr
  3166  		w.Header().Set("Content-Encoding", "gzip")
  3167  		if chunked {
  3168  			w.(Flusher).Flush()
  3169  		}
  3170  		w.Write(rgz) // arbitrary gzip response
  3171  	}))
  3172  	defer ts.Close()
  3173  
  3174  	tr := &Transport{}
  3175  	defer tr.CloseIdleConnections()
  3176  	c := &Client{Transport: tr}
  3177  	for i := 0; i < 2; i++ {
  3178  		res, err := c.Get(ts.URL)
  3179  		if err != nil {
  3180  			t.Fatal(err)
  3181  		}
  3182  		buf := make([]byte, len(rgz))
  3183  		if n, err := io.ReadFull(res.Body, buf); err != nil {
  3184  			t.Errorf("%d. ReadFull = %v, %v", i, n, err)
  3185  		}
  3186  		// Note: no res.Body.Close call. It should work without it,
  3187  		// since the flate.Reader's internal buffering will hit EOF
  3188  		// and that should be sufficient.
  3189  	}
  3190  	a1, a2 := <-addr, <-addr
  3191  	if a1 != a2 {
  3192  		t.Fatalf("didn't reuse connection")
  3193  	}
  3194  }
  3195  
  3196  func TestTransportResponseHeaderLength(t *testing.T) {
  3197  	defer afterTest(t)
  3198  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3199  		if r.URL.Path == "/long" {
  3200  			w.Header().Set("Long", strings.Repeat("a", 1<<20))
  3201  		}
  3202  	}))
  3203  	defer ts.Close()
  3204  
  3205  	tr := &Transport{
  3206  		MaxResponseHeaderBytes: 512 << 10,
  3207  	}
  3208  	defer tr.CloseIdleConnections()
  3209  	c := &Client{Transport: tr}
  3210  	if res, err := c.Get(ts.URL); err != nil {
  3211  		t.Fatal(err)
  3212  	} else {
  3213  		res.Body.Close()
  3214  	}
  3215  
  3216  	res, err := c.Get(ts.URL + "/long")
  3217  	if err == nil {
  3218  		defer res.Body.Close()
  3219  		var n int64
  3220  		for k, vv := range res.Header {
  3221  			for _, v := range vv {
  3222  				n += int64(len(k)) + int64(len(v))
  3223  			}
  3224  		}
  3225  		t.Fatalf("Unexpected success. Got %v and %d bytes of response headers", res.Status, n)
  3226  	}
  3227  	if want := "server response headers exceeded 524288 bytes"; !strings.Contains(err.Error(), want) {
  3228  		t.Errorf("got error: %v; want %q", err, want)
  3229  	}
  3230  }
  3231  
  3232  func TestTransportEventTrace(t *testing.T)    { testTransportEventTrace(t, h1Mode, false) }
  3233  func TestTransportEventTrace_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, false) }
  3234  
  3235  // test a non-nil httptrace.ClientTrace but with all hooks set to zero.
  3236  func TestTransportEventTrace_NoHooks(t *testing.T)    { testTransportEventTrace(t, h1Mode, true) }
  3237  func TestTransportEventTrace_NoHooks_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, true) }
  3238  
  3239  func testTransportEventTrace(t *testing.T, h2 bool, noHooks bool) {
  3240  	defer afterTest(t)
  3241  	const resBody = "some body"
  3242  	gotWroteReqEvent := make(chan struct{})
  3243  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  3244  		if _, err := ioutil.ReadAll(r.Body); err != nil {
  3245  			t.Error(err)
  3246  		}
  3247  		if !noHooks {
  3248  			select {
  3249  			case <-gotWroteReqEvent:
  3250  			case <-time.After(5 * time.Second):
  3251  				t.Error("timeout waiting for WroteRequest event")
  3252  			}
  3253  		}
  3254  		io.WriteString(w, resBody)
  3255  	}))
  3256  	defer cst.close()
  3257  
  3258  	cst.tr.ExpectContinueTimeout = 1 * time.Second
  3259  
  3260  	var mu sync.Mutex
  3261  	var buf bytes.Buffer
  3262  	logf := func(format string, args ...interface{}) {
  3263  		mu.Lock()
  3264  		defer mu.Unlock()
  3265  		fmt.Fprintf(&buf, format, args...)
  3266  		buf.WriteByte('\n')
  3267  	}
  3268  
  3269  	addrStr := cst.ts.Listener.Addr().String()
  3270  	ip, port, err := net.SplitHostPort(addrStr)
  3271  	if err != nil {
  3272  		t.Fatal(err)
  3273  	}
  3274  
  3275  	// Install a fake DNS server.
  3276  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) {
  3277  		if host != "dns-is-faked.golang" {
  3278  			t.Errorf("unexpected DNS host lookup for %q", host)
  3279  			return nil, nil
  3280  		}
  3281  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  3282  	})
  3283  
  3284  	req, _ := NewRequest("POST", cst.scheme()+"://dns-is-faked.golang:"+port, strings.NewReader("some body"))
  3285  	trace := &httptrace.ClientTrace{
  3286  		GetConn:              func(hostPort string) { logf("Getting conn for %v ...", hostPort) },
  3287  		GotConn:              func(ci httptrace.GotConnInfo) { logf("got conn: %+v", ci) },
  3288  		GotFirstResponseByte: func() { logf("first response byte") },
  3289  		PutIdleConn:          func(err error) { logf("PutIdleConn = %v", err) },
  3290  		DNSStart:             func(e httptrace.DNSStartInfo) { logf("DNS start: %+v", e) },
  3291  		DNSDone:              func(e httptrace.DNSDoneInfo) { logf("DNS done: %+v", e) },
  3292  		ConnectStart:         func(network, addr string) { logf("ConnectStart: Connecting to %s %s ...", network, addr) },
  3293  		ConnectDone: func(network, addr string, err error) {
  3294  			if err != nil {
  3295  				t.Errorf("ConnectDone: %v", err)
  3296  			}
  3297  			logf("ConnectDone: connected to %s %s = %v", network, addr, err)
  3298  		},
  3299  		Wait100Continue: func() { logf("Wait100Continue") },
  3300  		Got100Continue:  func() { logf("Got100Continue") },
  3301  		WroteRequest: func(e httptrace.WroteRequestInfo) {
  3302  			close(gotWroteReqEvent)
  3303  			logf("WroteRequest: %+v", e)
  3304  		},
  3305  	}
  3306  	if noHooks {
  3307  		// zero out all func pointers, trying to get some path to crash
  3308  		*trace = httptrace.ClientTrace{}
  3309  	}
  3310  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  3311  
  3312  	req.Header.Set("Expect", "100-continue")
  3313  	res, err := cst.c.Do(req)
  3314  	if err != nil {
  3315  		t.Fatal(err)
  3316  	}
  3317  	logf("got roundtrip.response")
  3318  	slurp, err := ioutil.ReadAll(res.Body)
  3319  	if err != nil {
  3320  		t.Fatal(err)
  3321  	}
  3322  	logf("consumed body")
  3323  	if string(slurp) != resBody || res.StatusCode != 200 {
  3324  		t.Fatalf("Got %q, %v; want %q, 200 OK", slurp, res.Status, resBody)
  3325  	}
  3326  	res.Body.Close()
  3327  
  3328  	if noHooks {
  3329  		// Done at this point. Just testing a full HTTP
  3330  		// requests can happen with a trace pointing to a zero
  3331  		// ClientTrace, full of nil func pointers.
  3332  		return
  3333  	}
  3334  
  3335  	got := buf.String()
  3336  	wantOnce := func(sub string) {
  3337  		if strings.Count(got, sub) != 1 {
  3338  			t.Errorf("expected substring %q exactly once in output.", sub)
  3339  		}
  3340  	}
  3341  	wantOnceOrMore := func(sub string) {
  3342  		if strings.Count(got, sub) == 0 {
  3343  			t.Errorf("expected substring %q at least once in output.", sub)
  3344  		}
  3345  	}
  3346  	wantOnce("Getting conn for dns-is-faked.golang:" + port)
  3347  	wantOnce("DNS start: {Host:dns-is-faked.golang}")
  3348  	wantOnce("DNS done: {Addrs:[{IP:" + ip + " Zone:}] Err:<nil> Coalesced:false}")
  3349  	wantOnce("got conn: {")
  3350  	wantOnceOrMore("Connecting to tcp " + addrStr)
  3351  	wantOnceOrMore("connected to tcp " + addrStr + " = <nil>")
  3352  	wantOnce("Reused:false WasIdle:false IdleTime:0s")
  3353  	wantOnce("first response byte")
  3354  	if !h2 {
  3355  		wantOnce("PutIdleConn = <nil>")
  3356  	}
  3357  	wantOnce("Wait100Continue")
  3358  	wantOnce("Got100Continue")
  3359  	wantOnce("WroteRequest: {Err:<nil>}")
  3360  	if strings.Contains(got, " to udp ") {
  3361  		t.Errorf("should not see UDP (DNS) connections")
  3362  	}
  3363  	if t.Failed() {
  3364  		t.Errorf("Output:\n%s", got)
  3365  	}
  3366  }
  3367  
  3368  func TestTransportEventTraceRealDNS(t *testing.T) {
  3369  	defer afterTest(t)
  3370  	tr := &Transport{}
  3371  	defer tr.CloseIdleConnections()
  3372  	c := &Client{Transport: tr}
  3373  
  3374  	var mu sync.Mutex
  3375  	var buf bytes.Buffer
  3376  	logf := func(format string, args ...interface{}) {
  3377  		mu.Lock()
  3378  		defer mu.Unlock()
  3379  		fmt.Fprintf(&buf, format, args...)
  3380  		buf.WriteByte('\n')
  3381  	}
  3382  
  3383  	req, _ := NewRequest("GET", "http://dns-should-not-resolve.golang:80", nil)
  3384  	trace := &httptrace.ClientTrace{
  3385  		DNSStart:     func(e httptrace.DNSStartInfo) { logf("DNSStart: %+v", e) },
  3386  		DNSDone:      func(e httptrace.DNSDoneInfo) { logf("DNSDone: %+v", e) },
  3387  		ConnectStart: func(network, addr string) { logf("ConnectStart: %s %s", network, addr) },
  3388  		ConnectDone:  func(network, addr string, err error) { logf("ConnectDone: %s %s %v", network, addr, err) },
  3389  	}
  3390  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  3391  
  3392  	resp, err := c.Do(req)
  3393  	if err == nil {
  3394  		resp.Body.Close()
  3395  		t.Fatal("expected error during DNS lookup")
  3396  	}
  3397  
  3398  	got := buf.String()
  3399  	wantSub := func(sub string) {
  3400  		if !strings.Contains(got, sub) {
  3401  			t.Errorf("expected substring %q in output.", sub)
  3402  		}
  3403  	}
  3404  	wantSub("DNSStart: {Host:dns-should-not-resolve.golang}")
  3405  	wantSub("DNSDone: {Addrs:[] Err:")
  3406  	if strings.Contains(got, "ConnectStart") || strings.Contains(got, "ConnectDone") {
  3407  		t.Errorf("should not see Connect events")
  3408  	}
  3409  	if t.Failed() {
  3410  		t.Errorf("Output:\n%s", got)
  3411  	}
  3412  }
  3413  
  3414  func TestTransportMaxIdleConns(t *testing.T) {
  3415  	defer afterTest(t)
  3416  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3417  		// No body for convenience.
  3418  	}))
  3419  	defer ts.Close()
  3420  	tr := &Transport{
  3421  		MaxIdleConns: 4,
  3422  	}
  3423  	defer tr.CloseIdleConnections()
  3424  
  3425  	ip, port, err := net.SplitHostPort(ts.Listener.Addr().String())
  3426  	if err != nil {
  3427  		t.Fatal(err)
  3428  	}
  3429  	c := &Client{Transport: tr}
  3430  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) {
  3431  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  3432  	})
  3433  
  3434  	hitHost := func(n int) {
  3435  		req, _ := NewRequest("GET", fmt.Sprintf("http://host-%d.dns-is-faked.golang:"+port, n), nil)
  3436  		req = req.WithContext(ctx)
  3437  		res, err := c.Do(req)
  3438  		if err != nil {
  3439  			t.Fatal(err)
  3440  		}
  3441  		res.Body.Close()
  3442  	}
  3443  	for i := 0; i < 4; i++ {
  3444  		hitHost(i)
  3445  	}
  3446  	want := []string{
  3447  		"|http|host-0.dns-is-faked.golang:" + port,
  3448  		"|http|host-1.dns-is-faked.golang:" + port,
  3449  		"|http|host-2.dns-is-faked.golang:" + port,
  3450  		"|http|host-3.dns-is-faked.golang:" + port,
  3451  	}
  3452  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  3453  		t.Fatalf("idle conn keys mismatch.\n got: %q\nwant: %q\n", got, want)
  3454  	}
  3455  
  3456  	// Now hitting the 5th host should kick out the first host:
  3457  	hitHost(4)
  3458  	want = []string{
  3459  		"|http|host-1.dns-is-faked.golang:" + port,
  3460  		"|http|host-2.dns-is-faked.golang:" + port,
  3461  		"|http|host-3.dns-is-faked.golang:" + port,
  3462  		"|http|host-4.dns-is-faked.golang:" + port,
  3463  	}
  3464  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  3465  		t.Fatalf("idle conn keys mismatch after 5th host.\n got: %q\nwant: %q\n", got, want)
  3466  	}
  3467  }
  3468  
  3469  func TestTransportIdleConnTimeout(t *testing.T) {
  3470  	if testing.Short() {
  3471  		t.Skip("skipping in short mode")
  3472  	}
  3473  	defer afterTest(t)
  3474  
  3475  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3476  		// No body for convenience.
  3477  	}))
  3478  	defer ts.Close()
  3479  
  3480  	const timeout = 1 * time.Second
  3481  	tr := &Transport{
  3482  		IdleConnTimeout: timeout,
  3483  	}
  3484  	defer tr.CloseIdleConnections()
  3485  	c := &Client{Transport: tr}
  3486  
  3487  	var conn string
  3488  	doReq := func(n int) {
  3489  		req, _ := NewRequest("GET", ts.URL, nil)
  3490  		req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  3491  			PutIdleConn: func(err error) {
  3492  				if err != nil {
  3493  					t.Errorf("failed to keep idle conn: %v", err)
  3494  				}
  3495  			},
  3496  		}))
  3497  		res, err := c.Do(req)
  3498  		if err != nil {
  3499  			t.Fatal(err)
  3500  		}
  3501  		res.Body.Close()
  3502  		conns := tr.IdleConnStrsForTesting()
  3503  		if len(conns) != 1 {
  3504  			t.Fatalf("req %v: unexpected number of idle conns: %q", n, conns)
  3505  		}
  3506  		if conn == "" {
  3507  			conn = conns[0]
  3508  		}
  3509  		if conn != conns[0] {
  3510  			t.Fatalf("req %v: cached connection changed; expected the same one throughout the test", n)
  3511  		}
  3512  	}
  3513  	for i := 0; i < 3; i++ {
  3514  		doReq(i)
  3515  		time.Sleep(timeout / 2)
  3516  	}
  3517  	time.Sleep(timeout * 3 / 2)
  3518  	if got := tr.IdleConnStrsForTesting(); len(got) != 0 {
  3519  		t.Errorf("idle conns = %q; want none", got)
  3520  	}
  3521  }
  3522  
  3523  // Issue 16208: Go 1.7 crashed after Transport.IdleConnTimeout if an
  3524  // HTTP/2 connection was established but but its caller no longer
  3525  // wanted it. (Assuming the connection cache was enabled, which it is
  3526  // by default)
  3527  //
  3528  // This test reproduced the crash by setting the IdleConnTimeout low
  3529  // (to make the test reasonable) and then making a request which is
  3530  // canceled by the DialTLS hook, which then also waits to return the
  3531  // real connection until after the RoundTrip saw the error.  Then we
  3532  // know the successful tls.Dial from DialTLS will need to go into the
  3533  // idle pool. Then we give it a of time to explode.
  3534  func TestIdleConnH2Crash(t *testing.T) {
  3535  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  3536  		// nothing
  3537  	}))
  3538  	defer cst.close()
  3539  
  3540  	ctx, cancel := context.WithCancel(context.Background())
  3541  	defer cancel()
  3542  
  3543  	gotErr := make(chan bool, 1)
  3544  
  3545  	cst.tr.IdleConnTimeout = 5 * time.Millisecond
  3546  	cst.tr.DialTLS = func(network, addr string) (net.Conn, error) {
  3547  		cancel()
  3548  		<-gotErr
  3549  		c, err := tls.Dial(network, addr, &tls.Config{
  3550  			InsecureSkipVerify: true,
  3551  			NextProtos:         []string{"h2"},
  3552  		})
  3553  		if err != nil {
  3554  			t.Error(err)
  3555  			return nil, err
  3556  		}
  3557  		if cs := c.ConnectionState(); cs.NegotiatedProtocol != "h2" {
  3558  			t.Errorf("protocol = %q; want %q", cs.NegotiatedProtocol, "h2")
  3559  			c.Close()
  3560  			return nil, errors.New("bogus")
  3561  		}
  3562  		return c, nil
  3563  	}
  3564  
  3565  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  3566  	req = req.WithContext(ctx)
  3567  	res, err := cst.c.Do(req)
  3568  	if err == nil {
  3569  		res.Body.Close()
  3570  		t.Fatal("unexpected success")
  3571  	}
  3572  	gotErr <- true
  3573  
  3574  	// Wait for the explosion.
  3575  	time.Sleep(cst.tr.IdleConnTimeout * 10)
  3576  }
  3577  
  3578  type funcConn struct {
  3579  	net.Conn
  3580  	read  func([]byte) (int, error)
  3581  	write func([]byte) (int, error)
  3582  }
  3583  
  3584  func (c funcConn) Read(p []byte) (int, error)  { return c.read(p) }
  3585  func (c funcConn) Write(p []byte) (int, error) { return c.write(p) }
  3586  func (c funcConn) Close() error                { return nil }
  3587  
  3588  // Issue 16465: Transport.RoundTrip should return the raw net.Conn.Read error from Peek
  3589  // back to the caller.
  3590  func TestTransportReturnsPeekError(t *testing.T) {
  3591  	errValue := errors.New("specific error value")
  3592  
  3593  	wrote := make(chan struct{})
  3594  	var wroteOnce sync.Once
  3595  
  3596  	tr := &Transport{
  3597  		Dial: func(network, addr string) (net.Conn, error) {
  3598  			c := funcConn{
  3599  				read: func([]byte) (int, error) {
  3600  					<-wrote
  3601  					return 0, errValue
  3602  				},
  3603  				write: func(p []byte) (int, error) {
  3604  					wroteOnce.Do(func() { close(wrote) })
  3605  					return len(p), nil
  3606  				},
  3607  			}
  3608  			return c, nil
  3609  		},
  3610  	}
  3611  	_, err := tr.RoundTrip(httptest.NewRequest("GET", "http://fake.tld/", nil))
  3612  	if err != errValue {
  3613  		t.Errorf("error = %#v; want %v", err, errValue)
  3614  	}
  3615  }
  3616  
  3617  var errFakeRoundTrip = errors.New("fake roundtrip")
  3618  
  3619  type funcRoundTripper func()
  3620  
  3621  func (fn funcRoundTripper) RoundTrip(*Request) (*Response, error) {
  3622  	fn()
  3623  	return nil, errFakeRoundTrip
  3624  }
  3625  
  3626  func wantBody(res *Response, err error, want string) error {
  3627  	if err != nil {
  3628  		return err
  3629  	}
  3630  	slurp, err := ioutil.ReadAll(res.Body)
  3631  	if err != nil {
  3632  		return fmt.Errorf("error reading body: %v", err)
  3633  	}
  3634  	if string(slurp) != want {
  3635  		return fmt.Errorf("body = %q; want %q", slurp, want)
  3636  	}
  3637  	if err := res.Body.Close(); err != nil {
  3638  		return fmt.Errorf("body Close = %v", err)
  3639  	}
  3640  	return nil
  3641  }
  3642  
  3643  func newLocalListener(t *testing.T) net.Listener {
  3644  	ln, err := net.Listen("tcp", "127.0.0.1:0")
  3645  	if err != nil {
  3646  		ln, err = net.Listen("tcp6", "[::1]:0")
  3647  	}
  3648  	if err != nil {
  3649  		t.Fatal(err)
  3650  	}
  3651  	return ln
  3652  }
  3653  
  3654  type countCloseReader struct {
  3655  	n *int
  3656  	io.Reader
  3657  }
  3658  
  3659  func (cr countCloseReader) Close() error {
  3660  	(*cr.n)++
  3661  	return nil
  3662  }
  3663  
  3664  // rgz is a gzip quine that uncompresses to itself.
  3665  var rgz = []byte{
  3666  	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  3667  	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  3668  	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  3669  	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  3670  	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  3671  	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  3672  	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  3673  	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  3674  	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  3675  	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  3676  	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  3677  	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  3678  	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  3679  	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  3680  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  3681  	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  3682  	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  3683  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  3684  	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  3685  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  3686  	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  3687  	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  3688  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  3689  	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  3690  	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  3691  	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  3692  	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  3693  	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  3694  	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  3695  	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  3696  	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  3697  	0x00, 0x00,
  3698  }