github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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  	"crypto/x509"
    20  	"encoding/binary"
    21  	"errors"
    22  	"fmt"
    23  	"go/token"
    24  	"internal/nettrace"
    25  	"io"
    26  	"io/ioutil"
    27  	"log"
    28  	"net"
    29  	. "net/http"
    30  	"net/http/httptest"
    31  	"net/http/httptrace"
    32  	"net/http/httputil"
    33  	"net/http/internal"
    34  	"net/textproto"
    35  	"net/url"
    36  	"os"
    37  	"reflect"
    38  	"runtime"
    39  	"strconv"
    40  	"strings"
    41  	"sync"
    42  	"sync/atomic"
    43  	"testing"
    44  	"time"
    45  
    46  	"golang.org/x/net/http/httpguts"
    47  )
    48  
    49  // TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
    50  //       and then verify that the final 2 responses get errors back.
    51  
    52  // hostPortHandler writes back the client's "host:port".
    53  var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
    54  	if r.FormValue("close") == "true" {
    55  		w.Header().Set("Connection", "close")
    56  	}
    57  	w.Header().Set("X-Saw-Close", fmt.Sprint(r.Close))
    58  	w.Write([]byte(r.RemoteAddr))
    59  })
    60  
    61  // testCloseConn is a net.Conn tracked by a testConnSet.
    62  type testCloseConn struct {
    63  	net.Conn
    64  	set *testConnSet
    65  }
    66  
    67  func (c *testCloseConn) Close() error {
    68  	c.set.remove(c)
    69  	return c.Conn.Close()
    70  }
    71  
    72  // testConnSet tracks a set of TCP connections and whether they've
    73  // been closed.
    74  type testConnSet struct {
    75  	t      *testing.T
    76  	mu     sync.Mutex // guards closed and list
    77  	closed map[net.Conn]bool
    78  	list   []net.Conn // in order created
    79  }
    80  
    81  func (tcs *testConnSet) insert(c net.Conn) {
    82  	tcs.mu.Lock()
    83  	defer tcs.mu.Unlock()
    84  	tcs.closed[c] = false
    85  	tcs.list = append(tcs.list, c)
    86  }
    87  
    88  func (tcs *testConnSet) remove(c net.Conn) {
    89  	tcs.mu.Lock()
    90  	defer tcs.mu.Unlock()
    91  	tcs.closed[c] = true
    92  }
    93  
    94  // some tests use this to manage raw tcp connections for later inspection
    95  func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) {
    96  	connSet := &testConnSet{
    97  		t:      t,
    98  		closed: make(map[net.Conn]bool),
    99  	}
   100  	dial := func(n, addr string) (net.Conn, error) {
   101  		c, err := net.Dial(n, addr)
   102  		if err != nil {
   103  			return nil, err
   104  		}
   105  		tc := &testCloseConn{c, connSet}
   106  		connSet.insert(tc)
   107  		return tc, nil
   108  	}
   109  	return connSet, dial
   110  }
   111  
   112  func (tcs *testConnSet) check(t *testing.T) {
   113  	tcs.mu.Lock()
   114  	defer tcs.mu.Unlock()
   115  	for i := 4; i >= 0; i-- {
   116  		for i, c := range tcs.list {
   117  			if tcs.closed[c] {
   118  				continue
   119  			}
   120  			if i != 0 {
   121  				tcs.mu.Unlock()
   122  				time.Sleep(50 * time.Millisecond)
   123  				tcs.mu.Lock()
   124  				continue
   125  			}
   126  			t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list))
   127  		}
   128  	}
   129  }
   130  
   131  func TestReuseRequest(t *testing.T) {
   132  	defer afterTest(t)
   133  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   134  		w.Write([]byte("{}"))
   135  	}))
   136  	defer ts.Close()
   137  
   138  	c := ts.Client()
   139  	req, _ := NewRequest("GET", ts.URL, nil)
   140  	res, err := c.Do(req)
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  	err = res.Body.Close()
   145  	if err != nil {
   146  		t.Fatal(err)
   147  	}
   148  
   149  	res, err = c.Do(req)
   150  	if err != nil {
   151  		t.Fatal(err)
   152  	}
   153  	err = res.Body.Close()
   154  	if err != nil {
   155  		t.Fatal(err)
   156  	}
   157  }
   158  
   159  // Two subsequent requests and verify their response is the same.
   160  // The response from the server is our own IP:port
   161  func TestTransportKeepAlives(t *testing.T) {
   162  	defer afterTest(t)
   163  	ts := httptest.NewServer(hostPortHandler)
   164  	defer ts.Close()
   165  
   166  	c := ts.Client()
   167  	for _, disableKeepAlive := range []bool{false, true} {
   168  		c.Transport.(*Transport).DisableKeepAlives = disableKeepAlive
   169  		fetch := func(n int) string {
   170  			res, err := c.Get(ts.URL)
   171  			if err != nil {
   172  				t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
   173  			}
   174  			body, err := ioutil.ReadAll(res.Body)
   175  			if err != nil {
   176  				t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
   177  			}
   178  			return string(body)
   179  		}
   180  
   181  		body1 := fetch(1)
   182  		body2 := fetch(2)
   183  
   184  		bodiesDiffer := body1 != body2
   185  		if bodiesDiffer != disableKeepAlive {
   186  			t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   187  				disableKeepAlive, bodiesDiffer, body1, body2)
   188  		}
   189  	}
   190  }
   191  
   192  func TestTransportConnectionCloseOnResponse(t *testing.T) {
   193  	defer afterTest(t)
   194  	ts := httptest.NewServer(hostPortHandler)
   195  	defer ts.Close()
   196  
   197  	connSet, testDial := makeTestDial(t)
   198  
   199  	c := ts.Client()
   200  	tr := c.Transport.(*Transport)
   201  	tr.Dial = testDial
   202  
   203  	for _, connectionClose := range []bool{false, true} {
   204  		fetch := func(n int) string {
   205  			req := new(Request)
   206  			var err error
   207  			req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
   208  			if err != nil {
   209  				t.Fatalf("URL parse error: %v", err)
   210  			}
   211  			req.Method = "GET"
   212  			req.Proto = "HTTP/1.1"
   213  			req.ProtoMajor = 1
   214  			req.ProtoMinor = 1
   215  
   216  			res, err := c.Do(req)
   217  			if err != nil {
   218  				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
   219  			}
   220  			defer res.Body.Close()
   221  			body, err := ioutil.ReadAll(res.Body)
   222  			if err != nil {
   223  				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
   224  			}
   225  			return string(body)
   226  		}
   227  
   228  		body1 := fetch(1)
   229  		body2 := fetch(2)
   230  		bodiesDiffer := body1 != body2
   231  		if bodiesDiffer != connectionClose {
   232  			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   233  				connectionClose, bodiesDiffer, body1, body2)
   234  		}
   235  
   236  		tr.CloseIdleConnections()
   237  	}
   238  
   239  	connSet.check(t)
   240  }
   241  
   242  func TestTransportConnectionCloseOnRequest(t *testing.T) {
   243  	defer afterTest(t)
   244  	ts := httptest.NewServer(hostPortHandler)
   245  	defer ts.Close()
   246  
   247  	connSet, testDial := makeTestDial(t)
   248  
   249  	c := ts.Client()
   250  	tr := c.Transport.(*Transport)
   251  	tr.Dial = testDial
   252  	for _, connectionClose := range []bool{false, true} {
   253  		fetch := func(n int) string {
   254  			req := new(Request)
   255  			var err error
   256  			req.URL, err = url.Parse(ts.URL)
   257  			if err != nil {
   258  				t.Fatalf("URL parse error: %v", err)
   259  			}
   260  			req.Method = "GET"
   261  			req.Proto = "HTTP/1.1"
   262  			req.ProtoMajor = 1
   263  			req.ProtoMinor = 1
   264  			req.Close = connectionClose
   265  
   266  			res, err := c.Do(req)
   267  			if err != nil {
   268  				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
   269  			}
   270  			if got, want := res.Header.Get("X-Saw-Close"), fmt.Sprint(connectionClose); got != want {
   271  				t.Errorf("For connectionClose = %v; handler's X-Saw-Close was %v; want %v",
   272  					connectionClose, got, !connectionClose)
   273  			}
   274  			body, err := ioutil.ReadAll(res.Body)
   275  			if err != nil {
   276  				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
   277  			}
   278  			return string(body)
   279  		}
   280  
   281  		body1 := fetch(1)
   282  		body2 := fetch(2)
   283  		bodiesDiffer := body1 != body2
   284  		if bodiesDiffer != connectionClose {
   285  			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   286  				connectionClose, bodiesDiffer, body1, body2)
   287  		}
   288  
   289  		tr.CloseIdleConnections()
   290  	}
   291  
   292  	connSet.check(t)
   293  }
   294  
   295  // if the Transport's DisableKeepAlives is set, all requests should
   296  // send Connection: close.
   297  // HTTP/1-only (Connection: close doesn't exist in h2)
   298  func TestTransportConnectionCloseOnRequestDisableKeepAlive(t *testing.T) {
   299  	defer afterTest(t)
   300  	ts := httptest.NewServer(hostPortHandler)
   301  	defer ts.Close()
   302  
   303  	c := ts.Client()
   304  	c.Transport.(*Transport).DisableKeepAlives = true
   305  
   306  	res, err := c.Get(ts.URL)
   307  	if err != nil {
   308  		t.Fatal(err)
   309  	}
   310  	res.Body.Close()
   311  	if res.Header.Get("X-Saw-Close") != "true" {
   312  		t.Errorf("handler didn't see Connection: close ")
   313  	}
   314  }
   315  
   316  // Test that Transport only sends one "Connection: close", regardless of
   317  // how "close" was indicated.
   318  func TestTransportRespectRequestWantsClose(t *testing.T) {
   319  	tests := []struct {
   320  		disableKeepAlives bool
   321  		close             bool
   322  	}{
   323  		{disableKeepAlives: false, close: false},
   324  		{disableKeepAlives: false, close: true},
   325  		{disableKeepAlives: true, close: false},
   326  		{disableKeepAlives: true, close: true},
   327  	}
   328  
   329  	for _, tc := range tests {
   330  		t.Run(fmt.Sprintf("DisableKeepAlive=%v,RequestClose=%v", tc.disableKeepAlives, tc.close),
   331  			func(t *testing.T) {
   332  				defer afterTest(t)
   333  				ts := httptest.NewServer(hostPortHandler)
   334  				defer ts.Close()
   335  
   336  				c := ts.Client()
   337  				c.Transport.(*Transport).DisableKeepAlives = tc.disableKeepAlives
   338  				req, err := NewRequest("GET", ts.URL, nil)
   339  				if err != nil {
   340  					t.Fatal(err)
   341  				}
   342  				count := 0
   343  				trace := &httptrace.ClientTrace{
   344  					WroteHeaderField: func(key string, field []string) {
   345  						if key != "Connection" {
   346  							return
   347  						}
   348  						if httpguts.HeaderValuesContainsToken(field, "close") {
   349  							count += 1
   350  						}
   351  					},
   352  				}
   353  				req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
   354  				req.Close = tc.close
   355  				res, err := c.Do(req)
   356  				if err != nil {
   357  					t.Fatal(err)
   358  				}
   359  				defer res.Body.Close()
   360  				if want := tc.disableKeepAlives || tc.close; count > 1 || (count == 1) != want {
   361  					t.Errorf("expecting want:%v, got 'Connection: close':%d", want, count)
   362  				}
   363  			})
   364  	}
   365  
   366  }
   367  
   368  func TestTransportIdleCacheKeys(t *testing.T) {
   369  	defer afterTest(t)
   370  	ts := httptest.NewServer(hostPortHandler)
   371  	defer ts.Close()
   372  	c := ts.Client()
   373  	tr := c.Transport.(*Transport)
   374  
   375  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   376  		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
   377  	}
   378  
   379  	resp, err := c.Get(ts.URL)
   380  	if err != nil {
   381  		t.Error(err)
   382  	}
   383  	ioutil.ReadAll(resp.Body)
   384  
   385  	keys := tr.IdleConnKeysForTesting()
   386  	if e, g := 1, len(keys); e != g {
   387  		t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
   388  	}
   389  
   390  	if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
   391  		t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
   392  	}
   393  
   394  	tr.CloseIdleConnections()
   395  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   396  		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
   397  	}
   398  }
   399  
   400  // Tests that the HTTP transport re-uses connections when a client
   401  // reads to the end of a response Body without closing it.
   402  func TestTransportReadToEndReusesConn(t *testing.T) {
   403  	defer afterTest(t)
   404  	const msg = "foobar"
   405  
   406  	var addrSeen map[string]int
   407  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   408  		addrSeen[r.RemoteAddr]++
   409  		if r.URL.Path == "/chunked/" {
   410  			w.WriteHeader(200)
   411  			w.(Flusher).Flush()
   412  		} else {
   413  			w.Header().Set("Content-Type", strconv.Itoa(len(msg)))
   414  			w.WriteHeader(200)
   415  		}
   416  		w.Write([]byte(msg))
   417  	}))
   418  	defer ts.Close()
   419  
   420  	buf := make([]byte, len(msg))
   421  
   422  	for pi, path := range []string{"/content-length/", "/chunked/"} {
   423  		wantLen := []int{len(msg), -1}[pi]
   424  		addrSeen = make(map[string]int)
   425  		for i := 0; i < 3; i++ {
   426  			res, err := Get(ts.URL + path)
   427  			if err != nil {
   428  				t.Errorf("Get %s: %v", path, err)
   429  				continue
   430  			}
   431  			// We want to close this body eventually (before the
   432  			// defer afterTest at top runs), but not before the
   433  			// len(addrSeen) check at the bottom of this test,
   434  			// since Closing this early in the loop would risk
   435  			// making connections be re-used for the wrong reason.
   436  			defer res.Body.Close()
   437  
   438  			if res.ContentLength != int64(wantLen) {
   439  				t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen)
   440  			}
   441  			n, err := res.Body.Read(buf)
   442  			if n != len(msg) || err != io.EOF {
   443  				t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg))
   444  			}
   445  		}
   446  		if len(addrSeen) != 1 {
   447  			t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen))
   448  		}
   449  	}
   450  }
   451  
   452  func TestTransportMaxPerHostIdleConns(t *testing.T) {
   453  	defer afterTest(t)
   454  	resch := make(chan string)
   455  	gotReq := make(chan bool)
   456  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   457  		gotReq <- true
   458  		msg := <-resch
   459  		_, err := w.Write([]byte(msg))
   460  		if err != nil {
   461  			t.Fatalf("Write: %v", err)
   462  		}
   463  	}))
   464  	defer ts.Close()
   465  
   466  	c := ts.Client()
   467  	tr := c.Transport.(*Transport)
   468  	maxIdleConnsPerHost := 2
   469  	tr.MaxIdleConnsPerHost = maxIdleConnsPerHost
   470  
   471  	// Start 3 outstanding requests and wait for the server to get them.
   472  	// Their responses will hang until we write to resch, though.
   473  	donech := make(chan bool)
   474  	doReq := func() {
   475  		resp, err := c.Get(ts.URL)
   476  		if err != nil {
   477  			t.Error(err)
   478  			return
   479  		}
   480  		if _, err := ioutil.ReadAll(resp.Body); err != nil {
   481  			t.Errorf("ReadAll: %v", err)
   482  			return
   483  		}
   484  		donech <- true
   485  	}
   486  	go doReq()
   487  	<-gotReq
   488  	go doReq()
   489  	<-gotReq
   490  	go doReq()
   491  	<-gotReq
   492  
   493  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   494  		t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
   495  	}
   496  
   497  	resch <- "res1"
   498  	<-donech
   499  	keys := tr.IdleConnKeysForTesting()
   500  	if e, g := 1, len(keys); e != g {
   501  		t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
   502  	}
   503  	addr := ts.Listener.Addr().String()
   504  	cacheKey := "|http|" + addr
   505  	if keys[0] != cacheKey {
   506  		t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
   507  	}
   508  	if e, g := 1, tr.IdleConnCountForTesting("http", addr); e != g {
   509  		t.Errorf("after first response, expected %d idle conns; got %d", e, g)
   510  	}
   511  
   512  	resch <- "res2"
   513  	<-donech
   514  	if g, w := tr.IdleConnCountForTesting("http", addr), 2; g != w {
   515  		t.Errorf("after second response, idle conns = %d; want %d", g, w)
   516  	}
   517  
   518  	resch <- "res3"
   519  	<-donech
   520  	if g, w := tr.IdleConnCountForTesting("http", addr), maxIdleConnsPerHost; g != w {
   521  		t.Errorf("after third response, idle conns = %d; want %d", g, w)
   522  	}
   523  }
   524  
   525  func TestTransportMaxConnsPerHostIncludeDialInProgress(t *testing.T) {
   526  	defer afterTest(t)
   527  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   528  		_, err := w.Write([]byte("foo"))
   529  		if err != nil {
   530  			t.Fatalf("Write: %v", err)
   531  		}
   532  	}))
   533  	defer ts.Close()
   534  	c := ts.Client()
   535  	tr := c.Transport.(*Transport)
   536  	dialStarted := make(chan struct{})
   537  	stallDial := make(chan struct{})
   538  	tr.Dial = func(network, addr string) (net.Conn, error) {
   539  		dialStarted <- struct{}{}
   540  		<-stallDial
   541  		return net.Dial(network, addr)
   542  	}
   543  
   544  	tr.DisableKeepAlives = true
   545  	tr.MaxConnsPerHost = 1
   546  
   547  	preDial := make(chan struct{})
   548  	reqComplete := make(chan struct{})
   549  	doReq := func(reqId string) {
   550  		req, _ := NewRequest("GET", ts.URL, nil)
   551  		trace := &httptrace.ClientTrace{
   552  			GetConn: func(hostPort string) {
   553  				preDial <- struct{}{}
   554  			},
   555  		}
   556  		req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
   557  		resp, err := tr.RoundTrip(req)
   558  		if err != nil {
   559  			t.Errorf("unexpected error for request %s: %v", reqId, err)
   560  		}
   561  		_, err = ioutil.ReadAll(resp.Body)
   562  		if err != nil {
   563  			t.Errorf("unexpected error for request %s: %v", reqId, err)
   564  		}
   565  		reqComplete <- struct{}{}
   566  	}
   567  	// get req1 to dial-in-progress
   568  	go doReq("req1")
   569  	<-preDial
   570  	<-dialStarted
   571  
   572  	// get req2 to waiting on conns per host to go down below max
   573  	go doReq("req2")
   574  	<-preDial
   575  	select {
   576  	case <-dialStarted:
   577  		t.Error("req2 dial started while req1 dial in progress")
   578  		return
   579  	default:
   580  	}
   581  
   582  	// let req1 complete
   583  	stallDial <- struct{}{}
   584  	<-reqComplete
   585  
   586  	// let req2 complete
   587  	<-dialStarted
   588  	stallDial <- struct{}{}
   589  	<-reqComplete
   590  }
   591  
   592  func TestTransportMaxConnsPerHost(t *testing.T) {
   593  	defer afterTest(t)
   594  	CondSkipHTTP2(t)
   595  
   596  	h := HandlerFunc(func(w ResponseWriter, r *Request) {
   597  		_, err := w.Write([]byte("foo"))
   598  		if err != nil {
   599  			t.Fatalf("Write: %v", err)
   600  		}
   601  	})
   602  
   603  	testMaxConns := func(scheme string, ts *httptest.Server) {
   604  		defer ts.Close()
   605  
   606  		c := ts.Client()
   607  		tr := c.Transport.(*Transport)
   608  		tr.MaxConnsPerHost = 1
   609  		if err := ExportHttp2ConfigureTransport(tr); err != nil {
   610  			t.Fatalf("ExportHttp2ConfigureTransport: %v", err)
   611  		}
   612  
   613  		connCh := make(chan net.Conn, 1)
   614  		var dialCnt, gotConnCnt, tlsHandshakeCnt int32
   615  		tr.Dial = func(network, addr string) (net.Conn, error) {
   616  			atomic.AddInt32(&dialCnt, 1)
   617  			c, err := net.Dial(network, addr)
   618  			connCh <- c
   619  			return c, err
   620  		}
   621  
   622  		doReq := func() {
   623  			trace := &httptrace.ClientTrace{
   624  				GotConn: func(connInfo httptrace.GotConnInfo) {
   625  					if !connInfo.Reused {
   626  						atomic.AddInt32(&gotConnCnt, 1)
   627  					}
   628  				},
   629  				TLSHandshakeStart: func() {
   630  					atomic.AddInt32(&tlsHandshakeCnt, 1)
   631  				},
   632  			}
   633  			req, _ := NewRequest("GET", ts.URL, nil)
   634  			req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
   635  
   636  			resp, err := c.Do(req)
   637  			if err != nil {
   638  				t.Fatalf("request failed: %v", err)
   639  			}
   640  			defer resp.Body.Close()
   641  			_, err = ioutil.ReadAll(resp.Body)
   642  			if err != nil {
   643  				t.Fatalf("read body failed: %v", err)
   644  			}
   645  		}
   646  
   647  		wg := sync.WaitGroup{}
   648  		for i := 0; i < 10; i++ {
   649  			wg.Add(1)
   650  			go func() {
   651  				defer wg.Done()
   652  				doReq()
   653  			}()
   654  		}
   655  		wg.Wait()
   656  
   657  		expected := int32(tr.MaxConnsPerHost)
   658  		if dialCnt != expected {
   659  			t.Errorf("round 1: too many dials (%s): %d != %d", scheme, dialCnt, expected)
   660  		}
   661  		if gotConnCnt != expected {
   662  			t.Errorf("round 1: too many get connections (%s): %d != %d", scheme, gotConnCnt, expected)
   663  		}
   664  		if ts.TLS != nil && tlsHandshakeCnt != expected {
   665  			t.Errorf("round 1: too many tls handshakes (%s): %d != %d", scheme, tlsHandshakeCnt, expected)
   666  		}
   667  
   668  		if t.Failed() {
   669  			t.FailNow()
   670  		}
   671  
   672  		(<-connCh).Close()
   673  		tr.CloseIdleConnections()
   674  
   675  		doReq()
   676  		expected++
   677  		if dialCnt != expected {
   678  			t.Errorf("round 2: too many dials (%s): %d", scheme, dialCnt)
   679  		}
   680  		if gotConnCnt != expected {
   681  			t.Errorf("round 2: too many get connections (%s): %d != %d", scheme, gotConnCnt, expected)
   682  		}
   683  		if ts.TLS != nil && tlsHandshakeCnt != expected {
   684  			t.Errorf("round 2: too many tls handshakes (%s): %d != %d", scheme, tlsHandshakeCnt, expected)
   685  		}
   686  	}
   687  
   688  	testMaxConns("http", httptest.NewServer(h))
   689  	testMaxConns("https", httptest.NewTLSServer(h))
   690  
   691  	ts := httptest.NewUnstartedServer(h)
   692  	ts.TLS = &tls.Config{NextProtos: []string{"h2"}}
   693  	ts.StartTLS()
   694  	testMaxConns("http2", ts)
   695  }
   696  
   697  func TestTransportRemovesDeadIdleConnections(t *testing.T) {
   698  	setParallel(t)
   699  	defer afterTest(t)
   700  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   701  		io.WriteString(w, r.RemoteAddr)
   702  	}))
   703  	defer ts.Close()
   704  
   705  	c := ts.Client()
   706  	tr := c.Transport.(*Transport)
   707  
   708  	doReq := func(name string) string {
   709  		// Do a POST instead of a GET to prevent the Transport's
   710  		// idempotent request retry logic from kicking in...
   711  		res, err := c.Post(ts.URL, "", nil)
   712  		if err != nil {
   713  			t.Fatalf("%s: %v", name, err)
   714  		}
   715  		if res.StatusCode != 200 {
   716  			t.Fatalf("%s: %v", name, res.Status)
   717  		}
   718  		defer res.Body.Close()
   719  		slurp, err := ioutil.ReadAll(res.Body)
   720  		if err != nil {
   721  			t.Fatalf("%s: %v", name, err)
   722  		}
   723  		return string(slurp)
   724  	}
   725  
   726  	first := doReq("first")
   727  	keys1 := tr.IdleConnKeysForTesting()
   728  
   729  	ts.CloseClientConnections()
   730  
   731  	var keys2 []string
   732  	if !waitCondition(3*time.Second, 50*time.Millisecond, func() bool {
   733  		keys2 = tr.IdleConnKeysForTesting()
   734  		return len(keys2) == 0
   735  	}) {
   736  		t.Fatalf("Transport didn't notice idle connection's death.\nbefore: %q\n after: %q\n", keys1, keys2)
   737  	}
   738  
   739  	second := doReq("second")
   740  	if first == second {
   741  		t.Errorf("expected a different connection between requests. got %q both times", first)
   742  	}
   743  }
   744  
   745  // Test that the Transport notices when a server hangs up on its
   746  // unexpectedly (a keep-alive connection is closed).
   747  func TestTransportServerClosingUnexpectedly(t *testing.T) {
   748  	setParallel(t)
   749  	defer afterTest(t)
   750  	ts := httptest.NewServer(hostPortHandler)
   751  	defer ts.Close()
   752  	c := ts.Client()
   753  
   754  	fetch := func(n, retries int) string {
   755  		condFatalf := func(format string, arg ...interface{}) {
   756  			if retries <= 0 {
   757  				t.Fatalf(format, arg...)
   758  			}
   759  			t.Logf("retrying shortly after expected error: "+format, arg...)
   760  			time.Sleep(time.Second / time.Duration(retries))
   761  		}
   762  		for retries >= 0 {
   763  			retries--
   764  			res, err := c.Get(ts.URL)
   765  			if err != nil {
   766  				condFatalf("error in req #%d, GET: %v", n, err)
   767  				continue
   768  			}
   769  			body, err := ioutil.ReadAll(res.Body)
   770  			if err != nil {
   771  				condFatalf("error in req #%d, ReadAll: %v", n, err)
   772  				continue
   773  			}
   774  			res.Body.Close()
   775  			return string(body)
   776  		}
   777  		panic("unreachable")
   778  	}
   779  
   780  	body1 := fetch(1, 0)
   781  	body2 := fetch(2, 0)
   782  
   783  	// Close all the idle connections in a way that's similar to
   784  	// the server hanging up on us. We don't use
   785  	// httptest.Server.CloseClientConnections because it's
   786  	// best-effort and stops blocking after 5 seconds. On a loaded
   787  	// machine running many tests concurrently it's possible for
   788  	// that method to be async and cause the body3 fetch below to
   789  	// run on an old connection. This function is synchronous.
   790  	ExportCloseTransportConnsAbruptly(c.Transport.(*Transport))
   791  
   792  	body3 := fetch(3, 5)
   793  
   794  	if body1 != body2 {
   795  		t.Errorf("expected body1 and body2 to be equal")
   796  	}
   797  	if body2 == body3 {
   798  		t.Errorf("expected body2 and body3 to be different")
   799  	}
   800  }
   801  
   802  // Test for https://golang.org/issue/2616 (appropriate issue number)
   803  // This fails pretty reliably with GOMAXPROCS=100 or something high.
   804  func TestStressSurpriseServerCloses(t *testing.T) {
   805  	defer afterTest(t)
   806  	if testing.Short() {
   807  		t.Skip("skipping test in short mode")
   808  	}
   809  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   810  		w.Header().Set("Content-Length", "5")
   811  		w.Header().Set("Content-Type", "text/plain")
   812  		w.Write([]byte("Hello"))
   813  		w.(Flusher).Flush()
   814  		conn, buf, _ := w.(Hijacker).Hijack()
   815  		buf.Flush()
   816  		conn.Close()
   817  	}))
   818  	defer ts.Close()
   819  	c := ts.Client()
   820  
   821  	// Do a bunch of traffic from different goroutines. Send to activityc
   822  	// after each request completes, regardless of whether it failed.
   823  	// If these are too high, OS X exhausts its ephemeral ports
   824  	// and hangs waiting for them to transition TCP states. That's
   825  	// not what we want to test. TODO(bradfitz): use an io.Pipe
   826  	// dialer for this test instead?
   827  	const (
   828  		numClients    = 20
   829  		reqsPerClient = 25
   830  	)
   831  	activityc := make(chan bool)
   832  	for i := 0; i < numClients; i++ {
   833  		go func() {
   834  			for i := 0; i < reqsPerClient; i++ {
   835  				res, err := c.Get(ts.URL)
   836  				if err == nil {
   837  					// We expect errors since the server is
   838  					// hanging up on us after telling us to
   839  					// send more requests, so we don't
   840  					// actually care what the error is.
   841  					// But we want to close the body in cases
   842  					// where we won the race.
   843  					res.Body.Close()
   844  				}
   845  				activityc <- true
   846  			}
   847  		}()
   848  	}
   849  
   850  	// Make sure all the request come back, one way or another.
   851  	for i := 0; i < numClients*reqsPerClient; i++ {
   852  		select {
   853  		case <-activityc:
   854  		case <-time.After(5 * time.Second):
   855  			t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
   856  		}
   857  	}
   858  }
   859  
   860  // TestTransportHeadResponses verifies that we deal with Content-Lengths
   861  // with no bodies properly
   862  func TestTransportHeadResponses(t *testing.T) {
   863  	defer afterTest(t)
   864  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   865  		if r.Method != "HEAD" {
   866  			panic("expected HEAD; got " + r.Method)
   867  		}
   868  		w.Header().Set("Content-Length", "123")
   869  		w.WriteHeader(200)
   870  	}))
   871  	defer ts.Close()
   872  	c := ts.Client()
   873  
   874  	for i := 0; i < 2; i++ {
   875  		res, err := c.Head(ts.URL)
   876  		if err != nil {
   877  			t.Errorf("error on loop %d: %v", i, err)
   878  			continue
   879  		}
   880  		if e, g := "123", res.Header.Get("Content-Length"); e != g {
   881  			t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
   882  		}
   883  		if e, g := int64(123), res.ContentLength; e != g {
   884  			t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
   885  		}
   886  		if all, err := ioutil.ReadAll(res.Body); err != nil {
   887  			t.Errorf("loop %d: Body ReadAll: %v", i, err)
   888  		} else if len(all) != 0 {
   889  			t.Errorf("Bogus body %q", all)
   890  		}
   891  	}
   892  }
   893  
   894  // TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
   895  // on responses to HEAD requests.
   896  func TestTransportHeadChunkedResponse(t *testing.T) {
   897  	defer afterTest(t)
   898  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   899  		if r.Method != "HEAD" {
   900  			panic("expected HEAD; got " + r.Method)
   901  		}
   902  		w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
   903  		w.Header().Set("x-client-ipport", r.RemoteAddr)
   904  		w.WriteHeader(200)
   905  	}))
   906  	defer ts.Close()
   907  	c := ts.Client()
   908  
   909  	// Ensure that we wait for the readLoop to complete before
   910  	// calling Head again
   911  	didRead := make(chan bool)
   912  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
   913  	defer SetReadLoopBeforeNextReadHook(nil)
   914  
   915  	res1, err := c.Head(ts.URL)
   916  	<-didRead
   917  
   918  	if err != nil {
   919  		t.Fatalf("request 1 error: %v", err)
   920  	}
   921  
   922  	res2, err := c.Head(ts.URL)
   923  	<-didRead
   924  
   925  	if err != nil {
   926  		t.Fatalf("request 2 error: %v", err)
   927  	}
   928  	if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
   929  		t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
   930  	}
   931  }
   932  
   933  var roundTripTests = []struct {
   934  	accept       string
   935  	expectAccept string
   936  	compressed   bool
   937  }{
   938  	// Requests with no accept-encoding header use transparent compression
   939  	{"", "gzip", false},
   940  	// Requests with other accept-encoding should pass through unmodified
   941  	{"foo", "foo", false},
   942  	// Requests with accept-encoding == gzip should be passed through
   943  	{"gzip", "gzip", true},
   944  }
   945  
   946  // Test that the modification made to the Request by the RoundTripper is cleaned up
   947  func TestRoundTripGzip(t *testing.T) {
   948  	setParallel(t)
   949  	defer afterTest(t)
   950  	const responseBody = "test response body"
   951  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   952  		accept := req.Header.Get("Accept-Encoding")
   953  		if expect := req.FormValue("expect_accept"); accept != expect {
   954  			t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
   955  				req.FormValue("testnum"), accept, expect)
   956  		}
   957  		if accept == "gzip" {
   958  			rw.Header().Set("Content-Encoding", "gzip")
   959  			gz := gzip.NewWriter(rw)
   960  			gz.Write([]byte(responseBody))
   961  			gz.Close()
   962  		} else {
   963  			rw.Header().Set("Content-Encoding", accept)
   964  			rw.Write([]byte(responseBody))
   965  		}
   966  	}))
   967  	defer ts.Close()
   968  	tr := ts.Client().Transport.(*Transport)
   969  
   970  	for i, test := range roundTripTests {
   971  		// Test basic request (no accept-encoding)
   972  		req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
   973  		if test.accept != "" {
   974  			req.Header.Set("Accept-Encoding", test.accept)
   975  		}
   976  		res, err := tr.RoundTrip(req)
   977  		if err != nil {
   978  			t.Errorf("%d. RoundTrip: %v", i, err)
   979  			continue
   980  		}
   981  		var body []byte
   982  		if test.compressed {
   983  			var r *gzip.Reader
   984  			r, err = gzip.NewReader(res.Body)
   985  			if err != nil {
   986  				t.Errorf("%d. gzip NewReader: %v", i, err)
   987  				continue
   988  			}
   989  			body, err = ioutil.ReadAll(r)
   990  			res.Body.Close()
   991  		} else {
   992  			body, err = ioutil.ReadAll(res.Body)
   993  		}
   994  		if err != nil {
   995  			t.Errorf("%d. Error: %q", i, err)
   996  			continue
   997  		}
   998  		if g, e := string(body), responseBody; g != e {
   999  			t.Errorf("%d. body = %q; want %q", i, g, e)
  1000  		}
  1001  		if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
  1002  			t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
  1003  		}
  1004  		if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
  1005  			t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
  1006  		}
  1007  	}
  1008  
  1009  }
  1010  
  1011  func TestTransportGzip(t *testing.T) {
  1012  	setParallel(t)
  1013  	defer afterTest(t)
  1014  	const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  1015  	const nRandBytes = 1024 * 1024
  1016  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
  1017  		if req.Method == "HEAD" {
  1018  			if g := req.Header.Get("Accept-Encoding"); g != "" {
  1019  				t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g)
  1020  			}
  1021  			return
  1022  		}
  1023  		if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
  1024  			t.Errorf("Accept-Encoding = %q, want %q", g, e)
  1025  		}
  1026  		rw.Header().Set("Content-Encoding", "gzip")
  1027  
  1028  		var w io.Writer = rw
  1029  		var buf bytes.Buffer
  1030  		if req.FormValue("chunked") == "0" {
  1031  			w = &buf
  1032  			defer io.Copy(rw, &buf)
  1033  			defer func() {
  1034  				rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
  1035  			}()
  1036  		}
  1037  		gz := gzip.NewWriter(w)
  1038  		gz.Write([]byte(testString))
  1039  		if req.FormValue("body") == "large" {
  1040  			io.CopyN(gz, rand.Reader, nRandBytes)
  1041  		}
  1042  		gz.Close()
  1043  	}))
  1044  	defer ts.Close()
  1045  	c := ts.Client()
  1046  
  1047  	for _, chunked := range []string{"1", "0"} {
  1048  		// First fetch something large, but only read some of it.
  1049  		res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
  1050  		if err != nil {
  1051  			t.Fatalf("large get: %v", err)
  1052  		}
  1053  		buf := make([]byte, len(testString))
  1054  		n, err := io.ReadFull(res.Body, buf)
  1055  		if err != nil {
  1056  			t.Fatalf("partial read of large response: size=%d, %v", n, err)
  1057  		}
  1058  		if e, g := testString, string(buf); e != g {
  1059  			t.Errorf("partial read got %q, expected %q", g, e)
  1060  		}
  1061  		res.Body.Close()
  1062  		// Read on the body, even though it's closed
  1063  		n, err = res.Body.Read(buf)
  1064  		if n != 0 || err == nil {
  1065  			t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
  1066  		}
  1067  
  1068  		// Then something small.
  1069  		res, err = c.Get(ts.URL + "/?chunked=" + chunked)
  1070  		if err != nil {
  1071  			t.Fatal(err)
  1072  		}
  1073  		body, err := ioutil.ReadAll(res.Body)
  1074  		if err != nil {
  1075  			t.Fatal(err)
  1076  		}
  1077  		if g, e := string(body), testString; g != e {
  1078  			t.Fatalf("body = %q; want %q", g, e)
  1079  		}
  1080  		if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
  1081  			t.Fatalf("Content-Encoding = %q; want %q", g, e)
  1082  		}
  1083  
  1084  		// Read on the body after it's been fully read:
  1085  		n, err = res.Body.Read(buf)
  1086  		if n != 0 || err == nil {
  1087  			t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
  1088  		}
  1089  		res.Body.Close()
  1090  		n, err = res.Body.Read(buf)
  1091  		if n != 0 || err == nil {
  1092  			t.Errorf("expected Read error after Close; got %d, %v", n, err)
  1093  		}
  1094  	}
  1095  
  1096  	// And a HEAD request too, because they're always weird.
  1097  	res, err := c.Head(ts.URL)
  1098  	if err != nil {
  1099  		t.Fatalf("Head: %v", err)
  1100  	}
  1101  	if res.StatusCode != 200 {
  1102  		t.Errorf("Head status=%d; want=200", res.StatusCode)
  1103  	}
  1104  }
  1105  
  1106  // If a request has Expect:100-continue header, the request blocks sending body until the first response.
  1107  // Premature consumption of the request body should not be occurred.
  1108  func TestTransportExpect100Continue(t *testing.T) {
  1109  	setParallel(t)
  1110  	defer afterTest(t)
  1111  
  1112  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
  1113  		switch req.URL.Path {
  1114  		case "/100":
  1115  			// This endpoint implicitly responds 100 Continue and reads body.
  1116  			if _, err := io.Copy(ioutil.Discard, req.Body); err != nil {
  1117  				t.Error("Failed to read Body", err)
  1118  			}
  1119  			rw.WriteHeader(StatusOK)
  1120  		case "/200":
  1121  			// Go 1.5 adds Connection: close header if the client expect
  1122  			// continue but not entire request body is consumed.
  1123  			rw.WriteHeader(StatusOK)
  1124  		case "/500":
  1125  			rw.WriteHeader(StatusInternalServerError)
  1126  		case "/keepalive":
  1127  			// This hijacked endpoint responds error without Connection:close.
  1128  			_, bufrw, err := rw.(Hijacker).Hijack()
  1129  			if err != nil {
  1130  				log.Fatal(err)
  1131  			}
  1132  			bufrw.WriteString("HTTP/1.1 500 Internal Server Error\r\n")
  1133  			bufrw.WriteString("Content-Length: 0\r\n\r\n")
  1134  			bufrw.Flush()
  1135  		case "/timeout":
  1136  			// This endpoint tries to read body without 100 (Continue) response.
  1137  			// After ExpectContinueTimeout, the reading will be started.
  1138  			conn, bufrw, err := rw.(Hijacker).Hijack()
  1139  			if err != nil {
  1140  				log.Fatal(err)
  1141  			}
  1142  			if _, err := io.CopyN(ioutil.Discard, bufrw, req.ContentLength); err != nil {
  1143  				t.Error("Failed to read Body", err)
  1144  			}
  1145  			bufrw.WriteString("HTTP/1.1 200 OK\r\n\r\n")
  1146  			bufrw.Flush()
  1147  			conn.Close()
  1148  		}
  1149  
  1150  	}))
  1151  	defer ts.Close()
  1152  
  1153  	tests := []struct {
  1154  		path   string
  1155  		body   []byte
  1156  		sent   int
  1157  		status int
  1158  	}{
  1159  		{path: "/100", body: []byte("hello"), sent: 5, status: 200},       // Got 100 followed by 200, entire body is sent.
  1160  		{path: "/200", body: []byte("hello"), sent: 0, status: 200},       // Got 200 without 100. body isn't sent.
  1161  		{path: "/500", body: []byte("hello"), sent: 0, status: 500},       // Got 500 without 100. body isn't sent.
  1162  		{path: "/keepalive", body: []byte("hello"), sent: 0, status: 500}, // Although without Connection:close, body isn't sent.
  1163  		{path: "/timeout", body: []byte("hello"), sent: 5, status: 200},   // Timeout exceeded and entire body is sent.
  1164  	}
  1165  
  1166  	c := ts.Client()
  1167  	for i, v := range tests {
  1168  		tr := &Transport{
  1169  			ExpectContinueTimeout: 2 * time.Second,
  1170  		}
  1171  		defer tr.CloseIdleConnections()
  1172  		c.Transport = tr
  1173  		body := bytes.NewReader(v.body)
  1174  		req, err := NewRequest("PUT", ts.URL+v.path, body)
  1175  		if err != nil {
  1176  			t.Fatal(err)
  1177  		}
  1178  		req.Header.Set("Expect", "100-continue")
  1179  		req.ContentLength = int64(len(v.body))
  1180  
  1181  		resp, err := c.Do(req)
  1182  		if err != nil {
  1183  			t.Fatal(err)
  1184  		}
  1185  		resp.Body.Close()
  1186  
  1187  		sent := len(v.body) - body.Len()
  1188  		if v.status != resp.StatusCode {
  1189  			t.Errorf("test %d: status code should be %d but got %d. (%s)", i, v.status, resp.StatusCode, v.path)
  1190  		}
  1191  		if v.sent != sent {
  1192  			t.Errorf("test %d: sent body should be %d but sent %d. (%s)", i, v.sent, sent, v.path)
  1193  		}
  1194  	}
  1195  }
  1196  
  1197  func TestSOCKS5Proxy(t *testing.T) {
  1198  	defer afterTest(t)
  1199  	ch := make(chan string, 1)
  1200  	l := newLocalListener(t)
  1201  	defer l.Close()
  1202  	defer close(ch)
  1203  	proxy := func(t *testing.T) {
  1204  		s, err := l.Accept()
  1205  		if err != nil {
  1206  			t.Errorf("socks5 proxy Accept(): %v", err)
  1207  			return
  1208  		}
  1209  		defer s.Close()
  1210  		var buf [22]byte
  1211  		if _, err := io.ReadFull(s, buf[:3]); err != nil {
  1212  			t.Errorf("socks5 proxy initial read: %v", err)
  1213  			return
  1214  		}
  1215  		if want := []byte{5, 1, 0}; !bytes.Equal(buf[:3], want) {
  1216  			t.Errorf("socks5 proxy initial read: got %v, want %v", buf[:3], want)
  1217  			return
  1218  		}
  1219  		if _, err := s.Write([]byte{5, 0}); err != nil {
  1220  			t.Errorf("socks5 proxy initial write: %v", err)
  1221  			return
  1222  		}
  1223  		if _, err := io.ReadFull(s, buf[:4]); err != nil {
  1224  			t.Errorf("socks5 proxy second read: %v", err)
  1225  			return
  1226  		}
  1227  		if want := []byte{5, 1, 0}; !bytes.Equal(buf[:3], want) {
  1228  			t.Errorf("socks5 proxy second read: got %v, want %v", buf[:3], want)
  1229  			return
  1230  		}
  1231  		var ipLen int
  1232  		switch buf[3] {
  1233  		case 1:
  1234  			ipLen = net.IPv4len
  1235  		case 4:
  1236  			ipLen = net.IPv6len
  1237  		default:
  1238  			t.Errorf("socks5 proxy second read: unexpected address type %v", buf[4])
  1239  			return
  1240  		}
  1241  		if _, err := io.ReadFull(s, buf[4:ipLen+6]); err != nil {
  1242  			t.Errorf("socks5 proxy address read: %v", err)
  1243  			return
  1244  		}
  1245  		ip := net.IP(buf[4 : ipLen+4])
  1246  		port := binary.BigEndian.Uint16(buf[ipLen+4 : ipLen+6])
  1247  		copy(buf[:3], []byte{5, 0, 0})
  1248  		if _, err := s.Write(buf[:ipLen+6]); err != nil {
  1249  			t.Errorf("socks5 proxy connect write: %v", err)
  1250  			return
  1251  		}
  1252  		ch <- fmt.Sprintf("proxy for %s:%d", ip, port)
  1253  
  1254  		// Implement proxying.
  1255  		targetHost := net.JoinHostPort(ip.String(), strconv.Itoa(int(port)))
  1256  		targetConn, err := net.Dial("tcp", targetHost)
  1257  		if err != nil {
  1258  			t.Errorf("net.Dial failed")
  1259  			return
  1260  		}
  1261  		go io.Copy(targetConn, s)
  1262  		io.Copy(s, targetConn) // Wait for the client to close the socket.
  1263  		targetConn.Close()
  1264  	}
  1265  
  1266  	pu, err := url.Parse("socks5://" + l.Addr().String())
  1267  	if err != nil {
  1268  		t.Fatal(err)
  1269  	}
  1270  
  1271  	sentinelHeader := "X-Sentinel"
  1272  	sentinelValue := "12345"
  1273  	h := HandlerFunc(func(w ResponseWriter, r *Request) {
  1274  		w.Header().Set(sentinelHeader, sentinelValue)
  1275  	})
  1276  	for _, useTLS := range []bool{false, true} {
  1277  		t.Run(fmt.Sprintf("useTLS=%v", useTLS), func(t *testing.T) {
  1278  			var ts *httptest.Server
  1279  			if useTLS {
  1280  				ts = httptest.NewTLSServer(h)
  1281  			} else {
  1282  				ts = httptest.NewServer(h)
  1283  			}
  1284  			go proxy(t)
  1285  			c := ts.Client()
  1286  			c.Transport.(*Transport).Proxy = ProxyURL(pu)
  1287  			r, err := c.Head(ts.URL)
  1288  			if err != nil {
  1289  				t.Fatal(err)
  1290  			}
  1291  			if r.Header.Get(sentinelHeader) != sentinelValue {
  1292  				t.Errorf("Failed to retrieve sentinel value")
  1293  			}
  1294  			var got string
  1295  			select {
  1296  			case got = <-ch:
  1297  			case <-time.After(5 * time.Second):
  1298  				t.Fatal("timeout connecting to socks5 proxy")
  1299  			}
  1300  			ts.Close()
  1301  			tsu, err := url.Parse(ts.URL)
  1302  			if err != nil {
  1303  				t.Fatal(err)
  1304  			}
  1305  			want := "proxy for " + tsu.Host
  1306  			if got != want {
  1307  				t.Errorf("got %q, want %q", got, want)
  1308  			}
  1309  		})
  1310  	}
  1311  }
  1312  
  1313  func TestTransportProxy(t *testing.T) {
  1314  	defer afterTest(t)
  1315  	testCases := []struct{ httpsSite, httpsProxy bool }{
  1316  		{false, false},
  1317  		{false, true},
  1318  		{true, false},
  1319  		{true, true},
  1320  	}
  1321  	for _, testCase := range testCases {
  1322  		httpsSite := testCase.httpsSite
  1323  		httpsProxy := testCase.httpsProxy
  1324  		t.Run(fmt.Sprintf("httpsSite=%v, httpsProxy=%v", httpsSite, httpsProxy), func(t *testing.T) {
  1325  			siteCh := make(chan *Request, 1)
  1326  			h1 := HandlerFunc(func(w ResponseWriter, r *Request) {
  1327  				siteCh <- r
  1328  			})
  1329  			proxyCh := make(chan *Request, 1)
  1330  			h2 := HandlerFunc(func(w ResponseWriter, r *Request) {
  1331  				proxyCh <- r
  1332  				// Implement an entire CONNECT proxy
  1333  				if r.Method == "CONNECT" {
  1334  					hijacker, ok := w.(Hijacker)
  1335  					if !ok {
  1336  						t.Errorf("hijack not allowed")
  1337  						return
  1338  					}
  1339  					clientConn, _, err := hijacker.Hijack()
  1340  					if err != nil {
  1341  						t.Errorf("hijacking failed")
  1342  						return
  1343  					}
  1344  					res := &Response{
  1345  						StatusCode: StatusOK,
  1346  						Proto:      "HTTP/1.1",
  1347  						ProtoMajor: 1,
  1348  						ProtoMinor: 1,
  1349  						Header:     make(Header),
  1350  					}
  1351  
  1352  					targetConn, err := net.Dial("tcp", r.URL.Host)
  1353  					if err != nil {
  1354  						t.Errorf("net.Dial(%q) failed: %v", r.URL.Host, err)
  1355  						return
  1356  					}
  1357  
  1358  					if err := res.Write(clientConn); err != nil {
  1359  						t.Errorf("Writing 200 OK failed: %v", err)
  1360  						return
  1361  					}
  1362  
  1363  					go io.Copy(targetConn, clientConn)
  1364  					go func() {
  1365  						io.Copy(clientConn, targetConn)
  1366  						targetConn.Close()
  1367  					}()
  1368  				}
  1369  			})
  1370  			var ts *httptest.Server
  1371  			if httpsSite {
  1372  				ts = httptest.NewTLSServer(h1)
  1373  			} else {
  1374  				ts = httptest.NewServer(h1)
  1375  			}
  1376  			var proxy *httptest.Server
  1377  			if httpsProxy {
  1378  				proxy = httptest.NewTLSServer(h2)
  1379  			} else {
  1380  				proxy = httptest.NewServer(h2)
  1381  			}
  1382  
  1383  			pu, err := url.Parse(proxy.URL)
  1384  			if err != nil {
  1385  				t.Fatal(err)
  1386  			}
  1387  
  1388  			// If neither server is HTTPS or both are, then c may be derived from either.
  1389  			// If only one server is HTTPS, c must be derived from that server in order
  1390  			// to ensure that it is configured to use the fake root CA from testcert.go.
  1391  			c := proxy.Client()
  1392  			if httpsSite {
  1393  				c = ts.Client()
  1394  			}
  1395  
  1396  			c.Transport.(*Transport).Proxy = ProxyURL(pu)
  1397  			if _, err := c.Head(ts.URL); err != nil {
  1398  				t.Error(err)
  1399  			}
  1400  			var got *Request
  1401  			select {
  1402  			case got = <-proxyCh:
  1403  			case <-time.After(5 * time.Second):
  1404  				t.Fatal("timeout connecting to http proxy")
  1405  			}
  1406  			c.Transport.(*Transport).CloseIdleConnections()
  1407  			ts.Close()
  1408  			proxy.Close()
  1409  			if httpsSite {
  1410  				// First message should be a CONNECT, asking for a socket to the real server,
  1411  				if got.Method != "CONNECT" {
  1412  					t.Errorf("Wrong method for secure proxying: %q", got.Method)
  1413  				}
  1414  				gotHost := got.URL.Host
  1415  				pu, err := url.Parse(ts.URL)
  1416  				if err != nil {
  1417  					t.Fatal("Invalid site URL")
  1418  				}
  1419  				if wantHost := pu.Host; gotHost != wantHost {
  1420  					t.Errorf("Got CONNECT host %q, want %q", gotHost, wantHost)
  1421  				}
  1422  
  1423  				// The next message on the channel should be from the site's server.
  1424  				next := <-siteCh
  1425  				if next.Method != "HEAD" {
  1426  					t.Errorf("Wrong method at destination: %s", next.Method)
  1427  				}
  1428  				if nextURL := next.URL.String(); nextURL != "/" {
  1429  					t.Errorf("Wrong URL at destination: %s", nextURL)
  1430  				}
  1431  			} else {
  1432  				if got.Method != "HEAD" {
  1433  					t.Errorf("Wrong method for destination: %q", got.Method)
  1434  				}
  1435  				gotURL := got.URL.String()
  1436  				wantURL := ts.URL + "/"
  1437  				if gotURL != wantURL {
  1438  					t.Errorf("Got URL %q, want %q", gotURL, wantURL)
  1439  				}
  1440  			}
  1441  		})
  1442  	}
  1443  }
  1444  
  1445  // Issue 28012: verify that the Transport closes its TCP connection to http proxies
  1446  // when they're slow to reply to HTTPS CONNECT responses.
  1447  func TestTransportProxyHTTPSConnectLeak(t *testing.T) {
  1448  	setParallel(t)
  1449  	defer afterTest(t)
  1450  
  1451  	ctx, cancel := context.WithCancel(context.Background())
  1452  	defer cancel()
  1453  
  1454  	ln := newLocalListener(t)
  1455  	defer ln.Close()
  1456  	listenerDone := make(chan struct{})
  1457  	go func() {
  1458  		defer close(listenerDone)
  1459  		c, err := ln.Accept()
  1460  		if err != nil {
  1461  			t.Errorf("Accept: %v", err)
  1462  			return
  1463  		}
  1464  		defer c.Close()
  1465  		// Read the CONNECT request
  1466  		br := bufio.NewReader(c)
  1467  		cr, err := ReadRequest(br)
  1468  		if err != nil {
  1469  			t.Errorf("proxy server failed to read CONNECT request")
  1470  			return
  1471  		}
  1472  		if cr.Method != "CONNECT" {
  1473  			t.Errorf("unexpected method %q", cr.Method)
  1474  			return
  1475  		}
  1476  
  1477  		// Now hang and never write a response; instead, cancel the request and wait
  1478  		// for the client to close.
  1479  		// (Prior to Issue 28012 being fixed, we never closed.)
  1480  		cancel()
  1481  		var buf [1]byte
  1482  		_, err = br.Read(buf[:])
  1483  		if err != io.EOF {
  1484  			t.Errorf("proxy server Read err = %v; want EOF", err)
  1485  		}
  1486  		return
  1487  	}()
  1488  
  1489  	c := &Client{
  1490  		Transport: &Transport{
  1491  			Proxy: func(*Request) (*url.URL, error) {
  1492  				return url.Parse("http://" + ln.Addr().String())
  1493  			},
  1494  		},
  1495  	}
  1496  	req, err := NewRequestWithContext(ctx, "GET", "https://golang.fake.tld/", nil)
  1497  	if err != nil {
  1498  		t.Fatal(err)
  1499  	}
  1500  	_, err = c.Do(req)
  1501  	if err == nil {
  1502  		t.Errorf("unexpected Get success")
  1503  	}
  1504  
  1505  	// Wait unconditionally for the listener goroutine to exit: this should never
  1506  	// hang, so if it does we want a full goroutine dump — and that's exactly what
  1507  	// the testing package will give us when the test run times out.
  1508  	<-listenerDone
  1509  }
  1510  
  1511  // Issue 16997: test transport dial preserves typed errors
  1512  func TestTransportDialPreservesNetOpProxyError(t *testing.T) {
  1513  	defer afterTest(t)
  1514  
  1515  	var errDial = errors.New("some dial error")
  1516  
  1517  	tr := &Transport{
  1518  		Proxy: func(*Request) (*url.URL, error) {
  1519  			return url.Parse("http://proxy.fake.tld/")
  1520  		},
  1521  		Dial: func(string, string) (net.Conn, error) {
  1522  			return nil, errDial
  1523  		},
  1524  	}
  1525  	defer tr.CloseIdleConnections()
  1526  
  1527  	c := &Client{Transport: tr}
  1528  	req, _ := NewRequest("GET", "http://fake.tld", nil)
  1529  	res, err := c.Do(req)
  1530  	if err == nil {
  1531  		res.Body.Close()
  1532  		t.Fatal("wanted a non-nil error")
  1533  	}
  1534  
  1535  	uerr, ok := err.(*url.Error)
  1536  	if !ok {
  1537  		t.Fatalf("got %T, want *url.Error", err)
  1538  	}
  1539  	oe, ok := uerr.Err.(*net.OpError)
  1540  	if !ok {
  1541  		t.Fatalf("url.Error.Err =  %T; want *net.OpError", uerr.Err)
  1542  	}
  1543  	want := &net.OpError{
  1544  		Op:  "proxyconnect",
  1545  		Net: "tcp",
  1546  		Err: errDial, // original error, unwrapped.
  1547  	}
  1548  	if !reflect.DeepEqual(oe, want) {
  1549  		t.Errorf("Got error %#v; want %#v", oe, want)
  1550  	}
  1551  }
  1552  
  1553  // Issue 36431: calls to RoundTrip should not mutate t.ProxyConnectHeader.
  1554  //
  1555  // (A bug caused dialConn to instead write the per-request Proxy-Authorization
  1556  // header through to the shared Header instance, introducing a data race.)
  1557  func TestTransportProxyDialDoesNotMutateProxyConnectHeader(t *testing.T) {
  1558  	setParallel(t)
  1559  	defer afterTest(t)
  1560  
  1561  	proxy := httptest.NewTLSServer(NotFoundHandler())
  1562  	defer proxy.Close()
  1563  	c := proxy.Client()
  1564  
  1565  	tr := c.Transport.(*Transport)
  1566  	tr.Proxy = func(*Request) (*url.URL, error) {
  1567  		u, _ := url.Parse(proxy.URL)
  1568  		u.User = url.UserPassword("aladdin", "opensesame")
  1569  		return u, nil
  1570  	}
  1571  	h := tr.ProxyConnectHeader
  1572  	if h == nil {
  1573  		h = make(Header)
  1574  	}
  1575  	tr.ProxyConnectHeader = h.Clone()
  1576  
  1577  	req, err := NewRequest("GET", "https://golang.fake.tld/", nil)
  1578  	if err != nil {
  1579  		t.Fatal(err)
  1580  	}
  1581  	_, err = c.Do(req)
  1582  	if err == nil {
  1583  		t.Errorf("unexpected Get success")
  1584  	}
  1585  
  1586  	if !reflect.DeepEqual(tr.ProxyConnectHeader, h) {
  1587  		t.Errorf("tr.ProxyConnectHeader = %v; want %v", tr.ProxyConnectHeader, h)
  1588  	}
  1589  }
  1590  
  1591  // TestTransportGzipRecursive sends a gzip quine and checks that the
  1592  // client gets the same value back. This is more cute than anything,
  1593  // but checks that we don't recurse forever, and checks that
  1594  // Content-Encoding is removed.
  1595  func TestTransportGzipRecursive(t *testing.T) {
  1596  	defer afterTest(t)
  1597  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1598  		w.Header().Set("Content-Encoding", "gzip")
  1599  		w.Write(rgz)
  1600  	}))
  1601  	defer ts.Close()
  1602  
  1603  	c := ts.Client()
  1604  	res, err := c.Get(ts.URL)
  1605  	if err != nil {
  1606  		t.Fatal(err)
  1607  	}
  1608  	body, err := ioutil.ReadAll(res.Body)
  1609  	if err != nil {
  1610  		t.Fatal(err)
  1611  	}
  1612  	if !bytes.Equal(body, rgz) {
  1613  		t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
  1614  			body, rgz)
  1615  	}
  1616  	if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
  1617  		t.Fatalf("Content-Encoding = %q; want %q", g, e)
  1618  	}
  1619  }
  1620  
  1621  // golang.org/issue/7750: request fails when server replies with
  1622  // a short gzip body
  1623  func TestTransportGzipShort(t *testing.T) {
  1624  	defer afterTest(t)
  1625  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1626  		w.Header().Set("Content-Encoding", "gzip")
  1627  		w.Write([]byte{0x1f, 0x8b})
  1628  	}))
  1629  	defer ts.Close()
  1630  
  1631  	c := ts.Client()
  1632  	res, err := c.Get(ts.URL)
  1633  	if err != nil {
  1634  		t.Fatal(err)
  1635  	}
  1636  	defer res.Body.Close()
  1637  	_, err = ioutil.ReadAll(res.Body)
  1638  	if err == nil {
  1639  		t.Fatal("Expect an error from reading a body.")
  1640  	}
  1641  	if err != io.ErrUnexpectedEOF {
  1642  		t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err)
  1643  	}
  1644  }
  1645  
  1646  // Wait until number of goroutines is no greater than nmax, or time out.
  1647  func waitNumGoroutine(nmax int) int {
  1648  	nfinal := runtime.NumGoroutine()
  1649  	for ntries := 10; ntries > 0 && nfinal > nmax; ntries-- {
  1650  		time.Sleep(50 * time.Millisecond)
  1651  		runtime.GC()
  1652  		nfinal = runtime.NumGoroutine()
  1653  	}
  1654  	return nfinal
  1655  }
  1656  
  1657  // tests that persistent goroutine connections shut down when no longer desired.
  1658  func TestTransportPersistConnLeak(t *testing.T) {
  1659  	// Not parallel: counts goroutines
  1660  	defer afterTest(t)
  1661  
  1662  	const numReq = 25
  1663  	gotReqCh := make(chan bool, numReq)
  1664  	unblockCh := make(chan bool, numReq)
  1665  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1666  		gotReqCh <- true
  1667  		<-unblockCh
  1668  		w.Header().Set("Content-Length", "0")
  1669  		w.WriteHeader(204)
  1670  	}))
  1671  	defer ts.Close()
  1672  	c := ts.Client()
  1673  	tr := c.Transport.(*Transport)
  1674  
  1675  	n0 := runtime.NumGoroutine()
  1676  
  1677  	didReqCh := make(chan bool, numReq)
  1678  	failed := make(chan bool, numReq)
  1679  	for i := 0; i < numReq; i++ {
  1680  		go func() {
  1681  			res, err := c.Get(ts.URL)
  1682  			didReqCh <- true
  1683  			if err != nil {
  1684  				t.Errorf("client fetch error: %v", err)
  1685  				failed <- true
  1686  				return
  1687  			}
  1688  			res.Body.Close()
  1689  		}()
  1690  	}
  1691  
  1692  	// Wait for all goroutines to be stuck in the Handler.
  1693  	for i := 0; i < numReq; i++ {
  1694  		select {
  1695  		case <-gotReqCh:
  1696  			// ok
  1697  		case <-failed:
  1698  			close(unblockCh)
  1699  			return
  1700  		}
  1701  	}
  1702  
  1703  	nhigh := runtime.NumGoroutine()
  1704  
  1705  	// Tell all handlers to unblock and reply.
  1706  	for i := 0; i < numReq; i++ {
  1707  		unblockCh <- true
  1708  	}
  1709  
  1710  	// Wait for all HTTP clients to be done.
  1711  	for i := 0; i < numReq; i++ {
  1712  		<-didReqCh
  1713  	}
  1714  
  1715  	tr.CloseIdleConnections()
  1716  	nfinal := waitNumGoroutine(n0 + 5)
  1717  
  1718  	growth := nfinal - n0
  1719  
  1720  	// We expect 0 or 1 extra goroutine, empirically. Allow up to 5.
  1721  	// Previously we were leaking one per numReq.
  1722  	if int(growth) > 5 {
  1723  		t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
  1724  		t.Error("too many new goroutines")
  1725  	}
  1726  }
  1727  
  1728  // golang.org/issue/4531: Transport leaks goroutines when
  1729  // request.ContentLength is explicitly short
  1730  func TestTransportPersistConnLeakShortBody(t *testing.T) {
  1731  	// Not parallel: measures goroutines.
  1732  	defer afterTest(t)
  1733  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1734  	}))
  1735  	defer ts.Close()
  1736  	c := ts.Client()
  1737  	tr := c.Transport.(*Transport)
  1738  
  1739  	n0 := runtime.NumGoroutine()
  1740  	body := []byte("Hello")
  1741  	for i := 0; i < 20; i++ {
  1742  		req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
  1743  		if err != nil {
  1744  			t.Fatal(err)
  1745  		}
  1746  		req.ContentLength = int64(len(body) - 2) // explicitly short
  1747  		_, err = c.Do(req)
  1748  		if err == nil {
  1749  			t.Fatal("Expect an error from writing too long of a body.")
  1750  		}
  1751  	}
  1752  	nhigh := runtime.NumGoroutine()
  1753  	tr.CloseIdleConnections()
  1754  	nfinal := waitNumGoroutine(n0 + 5)
  1755  
  1756  	growth := nfinal - n0
  1757  
  1758  	// We expect 0 or 1 extra goroutine, empirically. Allow up to 5.
  1759  	// Previously we were leaking one per numReq.
  1760  	t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
  1761  	if int(growth) > 5 {
  1762  		t.Error("too many new goroutines")
  1763  	}
  1764  }
  1765  
  1766  // A countedConn is a net.Conn that decrements an atomic counter when finalized.
  1767  type countedConn struct {
  1768  	net.Conn
  1769  }
  1770  
  1771  // A countingDialer dials connections and counts the number that remain reachable.
  1772  type countingDialer struct {
  1773  	dialer      net.Dialer
  1774  	mu          sync.Mutex
  1775  	total, live int64
  1776  }
  1777  
  1778  func (d *countingDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
  1779  	conn, err := d.dialer.DialContext(ctx, network, address)
  1780  	if err != nil {
  1781  		return nil, err
  1782  	}
  1783  
  1784  	counted := new(countedConn)
  1785  	counted.Conn = conn
  1786  
  1787  	d.mu.Lock()
  1788  	defer d.mu.Unlock()
  1789  	d.total++
  1790  	d.live++
  1791  
  1792  	runtime.SetFinalizer(counted, d.decrement)
  1793  	return counted, nil
  1794  }
  1795  
  1796  func (d *countingDialer) decrement(*countedConn) {
  1797  	d.mu.Lock()
  1798  	defer d.mu.Unlock()
  1799  	d.live--
  1800  }
  1801  
  1802  func (d *countingDialer) Read() (total, live int64) {
  1803  	d.mu.Lock()
  1804  	defer d.mu.Unlock()
  1805  	return d.total, d.live
  1806  }
  1807  
  1808  func TestTransportPersistConnLeakNeverIdle(t *testing.T) {
  1809  	defer afterTest(t)
  1810  
  1811  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1812  		// Close every connection so that it cannot be kept alive.
  1813  		conn, _, err := w.(Hijacker).Hijack()
  1814  		if err != nil {
  1815  			t.Errorf("Hijack failed unexpectedly: %v", err)
  1816  			return
  1817  		}
  1818  		conn.Close()
  1819  	}))
  1820  	defer ts.Close()
  1821  
  1822  	var d countingDialer
  1823  	c := ts.Client()
  1824  	c.Transport.(*Transport).DialContext = d.DialContext
  1825  
  1826  	body := []byte("Hello")
  1827  	for i := 0; ; i++ {
  1828  		total, live := d.Read()
  1829  		if live < total {
  1830  			break
  1831  		}
  1832  		if i >= 1<<12 {
  1833  			t.Fatalf("Count of live client net.Conns (%d) not lower than total (%d) after %d Do / GC iterations.", live, total, i)
  1834  		}
  1835  
  1836  		req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
  1837  		if err != nil {
  1838  			t.Fatal(err)
  1839  		}
  1840  		_, err = c.Do(req)
  1841  		if err == nil {
  1842  			t.Fatal("expected broken connection")
  1843  		}
  1844  
  1845  		runtime.GC()
  1846  	}
  1847  }
  1848  
  1849  type countedContext struct {
  1850  	context.Context
  1851  }
  1852  
  1853  type contextCounter struct {
  1854  	mu   sync.Mutex
  1855  	live int64
  1856  }
  1857  
  1858  func (cc *contextCounter) Track(ctx context.Context) context.Context {
  1859  	counted := new(countedContext)
  1860  	counted.Context = ctx
  1861  	cc.mu.Lock()
  1862  	defer cc.mu.Unlock()
  1863  	cc.live++
  1864  	runtime.SetFinalizer(counted, cc.decrement)
  1865  	return counted
  1866  }
  1867  
  1868  func (cc *contextCounter) decrement(*countedContext) {
  1869  	cc.mu.Lock()
  1870  	defer cc.mu.Unlock()
  1871  	cc.live--
  1872  }
  1873  
  1874  func (cc *contextCounter) Read() (live int64) {
  1875  	cc.mu.Lock()
  1876  	defer cc.mu.Unlock()
  1877  	return cc.live
  1878  }
  1879  
  1880  func TestTransportPersistConnContextLeakMaxConnsPerHost(t *testing.T) {
  1881  	if runtime.Compiler == "gccgo" {
  1882  		t.Skip("fails with conservative stack GC")
  1883  	}
  1884  
  1885  	defer afterTest(t)
  1886  
  1887  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1888  		runtime.Gosched()
  1889  		w.WriteHeader(StatusOK)
  1890  	}))
  1891  	defer ts.Close()
  1892  
  1893  	c := ts.Client()
  1894  	c.Transport.(*Transport).MaxConnsPerHost = 1
  1895  
  1896  	ctx := context.Background()
  1897  	body := []byte("Hello")
  1898  	doPosts := func(cc *contextCounter) {
  1899  		var wg sync.WaitGroup
  1900  		for n := 64; n > 0; n-- {
  1901  			wg.Add(1)
  1902  			go func() {
  1903  				defer wg.Done()
  1904  
  1905  				ctx := cc.Track(ctx)
  1906  				req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
  1907  				if err != nil {
  1908  					t.Error(err)
  1909  				}
  1910  
  1911  				_, err = c.Do(req.WithContext(ctx))
  1912  				if err != nil {
  1913  					t.Errorf("Do failed with error: %v", err)
  1914  				}
  1915  			}()
  1916  		}
  1917  		wg.Wait()
  1918  	}
  1919  
  1920  	var initialCC contextCounter
  1921  	doPosts(&initialCC)
  1922  
  1923  	// flushCC exists only to put pressure on the GC to finalize the initialCC
  1924  	// contexts: the flushCC allocations should eventually displace the initialCC
  1925  	// allocations.
  1926  	var flushCC contextCounter
  1927  	for i := 0; ; i++ {
  1928  		live := initialCC.Read()
  1929  		if live == 0 {
  1930  			break
  1931  		}
  1932  		if i >= 100 {
  1933  			t.Fatalf("%d Contexts still not finalized after %d GC cycles.", live, i)
  1934  		}
  1935  		doPosts(&flushCC)
  1936  		runtime.GC()
  1937  	}
  1938  }
  1939  
  1940  // This used to crash; https://golang.org/issue/3266
  1941  func TestTransportIdleConnCrash(t *testing.T) {
  1942  	defer afterTest(t)
  1943  	var tr *Transport
  1944  
  1945  	unblockCh := make(chan bool, 1)
  1946  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1947  		<-unblockCh
  1948  		tr.CloseIdleConnections()
  1949  	}))
  1950  	defer ts.Close()
  1951  	c := ts.Client()
  1952  	tr = c.Transport.(*Transport)
  1953  
  1954  	didreq := make(chan bool)
  1955  	go func() {
  1956  		res, err := c.Get(ts.URL)
  1957  		if err != nil {
  1958  			t.Error(err)
  1959  		} else {
  1960  			res.Body.Close() // returns idle conn
  1961  		}
  1962  		didreq <- true
  1963  	}()
  1964  	unblockCh <- true
  1965  	<-didreq
  1966  }
  1967  
  1968  // Test that the transport doesn't close the TCP connection early,
  1969  // before the response body has been read. This was a regression
  1970  // which sadly lacked a triggering test. The large response body made
  1971  // the old race easier to trigger.
  1972  func TestIssue3644(t *testing.T) {
  1973  	defer afterTest(t)
  1974  	const numFoos = 5000
  1975  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1976  		w.Header().Set("Connection", "close")
  1977  		for i := 0; i < numFoos; i++ {
  1978  			w.Write([]byte("foo "))
  1979  		}
  1980  	}))
  1981  	defer ts.Close()
  1982  	c := ts.Client()
  1983  	res, err := c.Get(ts.URL)
  1984  	if err != nil {
  1985  		t.Fatal(err)
  1986  	}
  1987  	defer res.Body.Close()
  1988  	bs, err := ioutil.ReadAll(res.Body)
  1989  	if err != nil {
  1990  		t.Fatal(err)
  1991  	}
  1992  	if len(bs) != numFoos*len("foo ") {
  1993  		t.Errorf("unexpected response length")
  1994  	}
  1995  }
  1996  
  1997  // Test that a client receives a server's reply, even if the server doesn't read
  1998  // the entire request body.
  1999  func TestIssue3595(t *testing.T) {
  2000  	setParallel(t)
  2001  	defer afterTest(t)
  2002  	const deniedMsg = "sorry, denied."
  2003  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2004  		Error(w, deniedMsg, StatusUnauthorized)
  2005  	}))
  2006  	defer ts.Close()
  2007  	c := ts.Client()
  2008  	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
  2009  	if err != nil {
  2010  		t.Errorf("Post: %v", err)
  2011  		return
  2012  	}
  2013  	got, err := ioutil.ReadAll(res.Body)
  2014  	if err != nil {
  2015  		t.Fatalf("Body ReadAll: %v", err)
  2016  	}
  2017  	if !strings.Contains(string(got), deniedMsg) {
  2018  		t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
  2019  	}
  2020  }
  2021  
  2022  // From https://golang.org/issue/4454 ,
  2023  // "client fails to handle requests with no body and chunked encoding"
  2024  func TestChunkedNoContent(t *testing.T) {
  2025  	defer afterTest(t)
  2026  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2027  		w.WriteHeader(StatusNoContent)
  2028  	}))
  2029  	defer ts.Close()
  2030  
  2031  	c := ts.Client()
  2032  	for _, closeBody := range []bool{true, false} {
  2033  		const n = 4
  2034  		for i := 1; i <= n; i++ {
  2035  			res, err := c.Get(ts.URL)
  2036  			if err != nil {
  2037  				t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
  2038  			} else {
  2039  				if closeBody {
  2040  					res.Body.Close()
  2041  				}
  2042  			}
  2043  		}
  2044  	}
  2045  }
  2046  
  2047  func TestTransportConcurrency(t *testing.T) {
  2048  	// Not parallel: uses global test hooks.
  2049  	defer afterTest(t)
  2050  	maxProcs, numReqs := 16, 500
  2051  	if testing.Short() {
  2052  		maxProcs, numReqs = 4, 50
  2053  	}
  2054  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
  2055  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2056  		fmt.Fprintf(w, "%v", r.FormValue("echo"))
  2057  	}))
  2058  	defer ts.Close()
  2059  
  2060  	var wg sync.WaitGroup
  2061  	wg.Add(numReqs)
  2062  
  2063  	// Due to the Transport's "socket late binding" (see
  2064  	// idleConnCh in transport.go), the numReqs HTTP requests
  2065  	// below can finish with a dial still outstanding. To keep
  2066  	// the leak checker happy, keep track of pending dials and
  2067  	// wait for them to finish (and be closed or returned to the
  2068  	// idle pool) before we close idle connections.
  2069  	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  2070  	defer SetPendingDialHooks(nil, nil)
  2071  
  2072  	c := ts.Client()
  2073  	reqs := make(chan string)
  2074  	defer close(reqs)
  2075  
  2076  	for i := 0; i < maxProcs*2; i++ {
  2077  		go func() {
  2078  			for req := range reqs {
  2079  				res, err := c.Get(ts.URL + "/?echo=" + req)
  2080  				if err != nil {
  2081  					t.Errorf("error on req %s: %v", req, err)
  2082  					wg.Done()
  2083  					continue
  2084  				}
  2085  				all, err := ioutil.ReadAll(res.Body)
  2086  				if err != nil {
  2087  					t.Errorf("read error on req %s: %v", req, err)
  2088  					wg.Done()
  2089  					continue
  2090  				}
  2091  				if string(all) != req {
  2092  					t.Errorf("body of req %s = %q; want %q", req, all, req)
  2093  				}
  2094  				res.Body.Close()
  2095  				wg.Done()
  2096  			}
  2097  		}()
  2098  	}
  2099  	for i := 0; i < numReqs; i++ {
  2100  		reqs <- fmt.Sprintf("request-%d", i)
  2101  	}
  2102  	wg.Wait()
  2103  }
  2104  
  2105  func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
  2106  	setParallel(t)
  2107  	defer afterTest(t)
  2108  	const debug = false
  2109  	mux := NewServeMux()
  2110  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  2111  		io.Copy(w, neverEnding('a'))
  2112  	})
  2113  	ts := httptest.NewServer(mux)
  2114  	defer ts.Close()
  2115  	timeout := 100 * time.Millisecond
  2116  
  2117  	c := ts.Client()
  2118  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  2119  		conn, err := net.Dial(n, addr)
  2120  		if err != nil {
  2121  			return nil, err
  2122  		}
  2123  		conn.SetDeadline(time.Now().Add(timeout))
  2124  		if debug {
  2125  			conn = NewLoggingConn("client", conn)
  2126  		}
  2127  		return conn, nil
  2128  	}
  2129  
  2130  	getFailed := false
  2131  	nRuns := 5
  2132  	if testing.Short() {
  2133  		nRuns = 1
  2134  	}
  2135  	for i := 0; i < nRuns; i++ {
  2136  		if debug {
  2137  			println("run", i+1, "of", nRuns)
  2138  		}
  2139  		sres, err := c.Get(ts.URL + "/get")
  2140  		if err != nil {
  2141  			if !getFailed {
  2142  				// Make the timeout longer, once.
  2143  				getFailed = true
  2144  				t.Logf("increasing timeout")
  2145  				i--
  2146  				timeout *= 10
  2147  				continue
  2148  			}
  2149  			t.Errorf("Error issuing GET: %v", err)
  2150  			break
  2151  		}
  2152  		_, err = io.Copy(ioutil.Discard, sres.Body)
  2153  		if err == nil {
  2154  			t.Errorf("Unexpected successful copy")
  2155  			break
  2156  		}
  2157  	}
  2158  	if debug {
  2159  		println("tests complete; waiting for handlers to finish")
  2160  	}
  2161  }
  2162  
  2163  func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
  2164  	setParallel(t)
  2165  	defer afterTest(t)
  2166  	const debug = false
  2167  	mux := NewServeMux()
  2168  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  2169  		io.Copy(w, neverEnding('a'))
  2170  	})
  2171  	mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
  2172  		defer r.Body.Close()
  2173  		io.Copy(ioutil.Discard, r.Body)
  2174  	})
  2175  	ts := httptest.NewServer(mux)
  2176  	timeout := 100 * time.Millisecond
  2177  
  2178  	c := ts.Client()
  2179  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  2180  		conn, err := net.Dial(n, addr)
  2181  		if err != nil {
  2182  			return nil, err
  2183  		}
  2184  		conn.SetDeadline(time.Now().Add(timeout))
  2185  		if debug {
  2186  			conn = NewLoggingConn("client", conn)
  2187  		}
  2188  		return conn, nil
  2189  	}
  2190  
  2191  	getFailed := false
  2192  	nRuns := 5
  2193  	if testing.Short() {
  2194  		nRuns = 1
  2195  	}
  2196  	for i := 0; i < nRuns; i++ {
  2197  		if debug {
  2198  			println("run", i+1, "of", nRuns)
  2199  		}
  2200  		sres, err := c.Get(ts.URL + "/get")
  2201  		if err != nil {
  2202  			if !getFailed {
  2203  				// Make the timeout longer, once.
  2204  				getFailed = true
  2205  				t.Logf("increasing timeout")
  2206  				i--
  2207  				timeout *= 10
  2208  				continue
  2209  			}
  2210  			t.Errorf("Error issuing GET: %v", err)
  2211  			break
  2212  		}
  2213  		req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
  2214  		_, err = c.Do(req)
  2215  		if err == nil {
  2216  			sres.Body.Close()
  2217  			t.Errorf("Unexpected successful PUT")
  2218  			break
  2219  		}
  2220  		sres.Body.Close()
  2221  	}
  2222  	if debug {
  2223  		println("tests complete; waiting for handlers to finish")
  2224  	}
  2225  	ts.Close()
  2226  }
  2227  
  2228  func TestTransportResponseHeaderTimeout(t *testing.T) {
  2229  	setParallel(t)
  2230  	defer afterTest(t)
  2231  	if testing.Short() {
  2232  		t.Skip("skipping timeout test in -short mode")
  2233  	}
  2234  	inHandler := make(chan bool, 1)
  2235  	mux := NewServeMux()
  2236  	mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {
  2237  		inHandler <- true
  2238  	})
  2239  	mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
  2240  		inHandler <- true
  2241  		time.Sleep(2 * time.Second)
  2242  	})
  2243  	ts := httptest.NewServer(mux)
  2244  	defer ts.Close()
  2245  
  2246  	c := ts.Client()
  2247  	c.Transport.(*Transport).ResponseHeaderTimeout = 500 * time.Millisecond
  2248  
  2249  	tests := []struct {
  2250  		path    string
  2251  		want    int
  2252  		wantErr string
  2253  	}{
  2254  		{path: "/fast", want: 200},
  2255  		{path: "/slow", wantErr: "timeout awaiting response headers"},
  2256  		{path: "/fast", want: 200},
  2257  	}
  2258  	for i, tt := range tests {
  2259  		req, _ := NewRequest("GET", ts.URL+tt.path, nil)
  2260  		req = req.WithT(t)
  2261  		res, err := c.Do(req)
  2262  		select {
  2263  		case <-inHandler:
  2264  		case <-time.After(5 * time.Second):
  2265  			t.Errorf("never entered handler for test index %d, %s", i, tt.path)
  2266  			continue
  2267  		}
  2268  		if err != nil {
  2269  			uerr, ok := err.(*url.Error)
  2270  			if !ok {
  2271  				t.Errorf("error is not an url.Error; got: %#v", err)
  2272  				continue
  2273  			}
  2274  			nerr, ok := uerr.Err.(net.Error)
  2275  			if !ok {
  2276  				t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
  2277  				continue
  2278  			}
  2279  			if !nerr.Timeout() {
  2280  				t.Errorf("want timeout error; got: %q", nerr)
  2281  				continue
  2282  			}
  2283  			if strings.Contains(err.Error(), tt.wantErr) {
  2284  				continue
  2285  			}
  2286  			t.Errorf("%d. unexpected error: %v", i, err)
  2287  			continue
  2288  		}
  2289  		if tt.wantErr != "" {
  2290  			t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
  2291  			continue
  2292  		}
  2293  		if res.StatusCode != tt.want {
  2294  			t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
  2295  		}
  2296  	}
  2297  }
  2298  
  2299  func TestTransportCancelRequest(t *testing.T) {
  2300  	setParallel(t)
  2301  	defer afterTest(t)
  2302  	if testing.Short() {
  2303  		t.Skip("skipping test in -short mode")
  2304  	}
  2305  	unblockc := make(chan bool)
  2306  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2307  		fmt.Fprintf(w, "Hello")
  2308  		w.(Flusher).Flush() // send headers and some body
  2309  		<-unblockc
  2310  	}))
  2311  	defer ts.Close()
  2312  	defer close(unblockc)
  2313  
  2314  	c := ts.Client()
  2315  	tr := c.Transport.(*Transport)
  2316  
  2317  	req, _ := NewRequest("GET", ts.URL, nil)
  2318  	res, err := c.Do(req)
  2319  	if err != nil {
  2320  		t.Fatal(err)
  2321  	}
  2322  	go func() {
  2323  		time.Sleep(1 * time.Second)
  2324  		tr.CancelRequest(req)
  2325  	}()
  2326  	t0 := time.Now()
  2327  	body, err := ioutil.ReadAll(res.Body)
  2328  	d := time.Since(t0)
  2329  
  2330  	if err != ExportErrRequestCanceled {
  2331  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  2332  	}
  2333  	if string(body) != "Hello" {
  2334  		t.Errorf("Body = %q; want Hello", body)
  2335  	}
  2336  	if d < 500*time.Millisecond {
  2337  		t.Errorf("expected ~1 second delay; got %v", d)
  2338  	}
  2339  	// Verify no outstanding requests after readLoop/writeLoop
  2340  	// goroutines shut down.
  2341  	for tries := 5; tries > 0; tries-- {
  2342  		n := tr.NumPendingRequestsForTesting()
  2343  		if n == 0 {
  2344  			break
  2345  		}
  2346  		time.Sleep(100 * time.Millisecond)
  2347  		if tries == 1 {
  2348  			t.Errorf("pending requests = %d; want 0", n)
  2349  		}
  2350  	}
  2351  }
  2352  
  2353  func TestTransportCancelRequestInDial(t *testing.T) {
  2354  	defer afterTest(t)
  2355  	if testing.Short() {
  2356  		t.Skip("skipping test in -short mode")
  2357  	}
  2358  	var logbuf bytes.Buffer
  2359  	eventLog := log.New(&logbuf, "", 0)
  2360  
  2361  	unblockDial := make(chan bool)
  2362  	defer close(unblockDial)
  2363  
  2364  	inDial := make(chan bool)
  2365  	tr := &Transport{
  2366  		Dial: func(network, addr string) (net.Conn, error) {
  2367  			eventLog.Println("dial: blocking")
  2368  			inDial <- true
  2369  			<-unblockDial
  2370  			return nil, errors.New("nope")
  2371  		},
  2372  	}
  2373  	cl := &Client{Transport: tr}
  2374  	gotres := make(chan bool)
  2375  	req, _ := NewRequest("GET", "http://something.no-network.tld/", nil)
  2376  	go func() {
  2377  		_, err := cl.Do(req)
  2378  		eventLog.Printf("Get = %v", err)
  2379  		gotres <- true
  2380  	}()
  2381  
  2382  	select {
  2383  	case <-inDial:
  2384  	case <-time.After(5 * time.Second):
  2385  		t.Fatal("timeout; never saw blocking dial")
  2386  	}
  2387  
  2388  	eventLog.Printf("canceling")
  2389  	tr.CancelRequest(req)
  2390  	tr.CancelRequest(req) // used to panic on second call
  2391  
  2392  	select {
  2393  	case <-gotres:
  2394  	case <-time.After(5 * time.Second):
  2395  		panic("hang. events are: " + logbuf.String())
  2396  	}
  2397  
  2398  	got := logbuf.String()
  2399  	want := `dial: blocking
  2400  canceling
  2401  Get = Get "http://something.no-network.tld/": net/http: request canceled while waiting for connection
  2402  `
  2403  	if got != want {
  2404  		t.Errorf("Got events:\n%s\nWant:\n%s", got, want)
  2405  	}
  2406  }
  2407  
  2408  func TestCancelRequestWithChannel(t *testing.T) {
  2409  	setParallel(t)
  2410  	defer afterTest(t)
  2411  	if testing.Short() {
  2412  		t.Skip("skipping test in -short mode")
  2413  	}
  2414  	unblockc := make(chan bool)
  2415  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2416  		fmt.Fprintf(w, "Hello")
  2417  		w.(Flusher).Flush() // send headers and some body
  2418  		<-unblockc
  2419  	}))
  2420  	defer ts.Close()
  2421  	defer close(unblockc)
  2422  
  2423  	c := ts.Client()
  2424  	tr := c.Transport.(*Transport)
  2425  
  2426  	req, _ := NewRequest("GET", ts.URL, nil)
  2427  	ch := make(chan struct{})
  2428  	req.Cancel = ch
  2429  
  2430  	res, err := c.Do(req)
  2431  	if err != nil {
  2432  		t.Fatal(err)
  2433  	}
  2434  	go func() {
  2435  		time.Sleep(1 * time.Second)
  2436  		close(ch)
  2437  	}()
  2438  	t0 := time.Now()
  2439  	body, err := ioutil.ReadAll(res.Body)
  2440  	d := time.Since(t0)
  2441  
  2442  	if err != ExportErrRequestCanceled {
  2443  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  2444  	}
  2445  	if string(body) != "Hello" {
  2446  		t.Errorf("Body = %q; want Hello", body)
  2447  	}
  2448  	if d < 500*time.Millisecond {
  2449  		t.Errorf("expected ~1 second delay; got %v", d)
  2450  	}
  2451  	// Verify no outstanding requests after readLoop/writeLoop
  2452  	// goroutines shut down.
  2453  	for tries := 5; tries > 0; tries-- {
  2454  		n := tr.NumPendingRequestsForTesting()
  2455  		if n == 0 {
  2456  			break
  2457  		}
  2458  		time.Sleep(100 * time.Millisecond)
  2459  		if tries == 1 {
  2460  			t.Errorf("pending requests = %d; want 0", n)
  2461  		}
  2462  	}
  2463  }
  2464  
  2465  func TestCancelRequestWithChannelBeforeDo_Cancel(t *testing.T) {
  2466  	testCancelRequestWithChannelBeforeDo(t, false)
  2467  }
  2468  func TestCancelRequestWithChannelBeforeDo_Context(t *testing.T) {
  2469  	testCancelRequestWithChannelBeforeDo(t, true)
  2470  }
  2471  func testCancelRequestWithChannelBeforeDo(t *testing.T, withCtx bool) {
  2472  	setParallel(t)
  2473  	defer afterTest(t)
  2474  	unblockc := make(chan bool)
  2475  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2476  		<-unblockc
  2477  	}))
  2478  	defer ts.Close()
  2479  	defer close(unblockc)
  2480  
  2481  	c := ts.Client()
  2482  
  2483  	req, _ := NewRequest("GET", ts.URL, nil)
  2484  	if withCtx {
  2485  		ctx, cancel := context.WithCancel(context.Background())
  2486  		cancel()
  2487  		req = req.WithContext(ctx)
  2488  	} else {
  2489  		ch := make(chan struct{})
  2490  		req.Cancel = ch
  2491  		close(ch)
  2492  	}
  2493  
  2494  	_, err := c.Do(req)
  2495  	if ue, ok := err.(*url.Error); ok {
  2496  		err = ue.Err
  2497  	}
  2498  	if withCtx {
  2499  		if err != context.Canceled {
  2500  			t.Errorf("Do error = %v; want %v", err, context.Canceled)
  2501  		}
  2502  	} else {
  2503  		if err == nil || !strings.Contains(err.Error(), "canceled") {
  2504  			t.Errorf("Do error = %v; want cancellation", err)
  2505  		}
  2506  	}
  2507  }
  2508  
  2509  // Issue 11020. The returned error message should be errRequestCanceled
  2510  func TestTransportCancelBeforeResponseHeaders(t *testing.T) {
  2511  	defer afterTest(t)
  2512  
  2513  	serverConnCh := make(chan net.Conn, 1)
  2514  	tr := &Transport{
  2515  		Dial: func(network, addr string) (net.Conn, error) {
  2516  			cc, sc := net.Pipe()
  2517  			serverConnCh <- sc
  2518  			return cc, nil
  2519  		},
  2520  	}
  2521  	defer tr.CloseIdleConnections()
  2522  	errc := make(chan error, 1)
  2523  	req, _ := NewRequest("GET", "http://example.com/", nil)
  2524  	go func() {
  2525  		_, err := tr.RoundTrip(req)
  2526  		errc <- err
  2527  	}()
  2528  
  2529  	sc := <-serverConnCh
  2530  	verb := make([]byte, 3)
  2531  	if _, err := io.ReadFull(sc, verb); err != nil {
  2532  		t.Errorf("Error reading HTTP verb from server: %v", err)
  2533  	}
  2534  	if string(verb) != "GET" {
  2535  		t.Errorf("server received %q; want GET", verb)
  2536  	}
  2537  	defer sc.Close()
  2538  
  2539  	tr.CancelRequest(req)
  2540  
  2541  	err := <-errc
  2542  	if err == nil {
  2543  		t.Fatalf("unexpected success from RoundTrip")
  2544  	}
  2545  	if err != ExportErrRequestCanceled {
  2546  		t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err)
  2547  	}
  2548  }
  2549  
  2550  // golang.org/issue/3672 -- Client can't close HTTP stream
  2551  // Calling Close on a Response.Body used to just read until EOF.
  2552  // Now it actually closes the TCP connection.
  2553  func TestTransportCloseResponseBody(t *testing.T) {
  2554  	defer afterTest(t)
  2555  	writeErr := make(chan error, 1)
  2556  	msg := []byte("young\n")
  2557  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2558  		for {
  2559  			_, err := w.Write(msg)
  2560  			if err != nil {
  2561  				writeErr <- err
  2562  				return
  2563  			}
  2564  			w.(Flusher).Flush()
  2565  		}
  2566  	}))
  2567  	defer ts.Close()
  2568  
  2569  	c := ts.Client()
  2570  	tr := c.Transport.(*Transport)
  2571  
  2572  	req, _ := NewRequest("GET", ts.URL, nil)
  2573  	defer tr.CancelRequest(req)
  2574  
  2575  	res, err := c.Do(req)
  2576  	if err != nil {
  2577  		t.Fatal(err)
  2578  	}
  2579  
  2580  	const repeats = 3
  2581  	buf := make([]byte, len(msg)*repeats)
  2582  	want := bytes.Repeat(msg, repeats)
  2583  
  2584  	_, err = io.ReadFull(res.Body, buf)
  2585  	if err != nil {
  2586  		t.Fatal(err)
  2587  	}
  2588  	if !bytes.Equal(buf, want) {
  2589  		t.Fatalf("read %q; want %q", buf, want)
  2590  	}
  2591  	didClose := make(chan error, 1)
  2592  	go func() {
  2593  		didClose <- res.Body.Close()
  2594  	}()
  2595  	select {
  2596  	case err := <-didClose:
  2597  		if err != nil {
  2598  			t.Errorf("Close = %v", err)
  2599  		}
  2600  	case <-time.After(10 * time.Second):
  2601  		t.Fatal("too long waiting for close")
  2602  	}
  2603  	select {
  2604  	case err := <-writeErr:
  2605  		if err == nil {
  2606  			t.Errorf("expected non-nil write error")
  2607  		}
  2608  	case <-time.After(10 * time.Second):
  2609  		t.Fatal("too long waiting for write error")
  2610  	}
  2611  }
  2612  
  2613  type fooProto struct{}
  2614  
  2615  func (fooProto) RoundTrip(req *Request) (*Response, error) {
  2616  	res := &Response{
  2617  		Status:     "200 OK",
  2618  		StatusCode: 200,
  2619  		Header:     make(Header),
  2620  		Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
  2621  	}
  2622  	return res, nil
  2623  }
  2624  
  2625  func TestTransportAltProto(t *testing.T) {
  2626  	defer afterTest(t)
  2627  	tr := &Transport{}
  2628  	c := &Client{Transport: tr}
  2629  	tr.RegisterProtocol("foo", fooProto{})
  2630  	res, err := c.Get("foo://bar.com/path")
  2631  	if err != nil {
  2632  		t.Fatal(err)
  2633  	}
  2634  	bodyb, err := ioutil.ReadAll(res.Body)
  2635  	if err != nil {
  2636  		t.Fatal(err)
  2637  	}
  2638  	body := string(bodyb)
  2639  	if e := "You wanted foo://bar.com/path"; body != e {
  2640  		t.Errorf("got response %q, want %q", body, e)
  2641  	}
  2642  }
  2643  
  2644  func TestTransportNoHost(t *testing.T) {
  2645  	defer afterTest(t)
  2646  	tr := &Transport{}
  2647  	_, err := tr.RoundTrip(&Request{
  2648  		Header: make(Header),
  2649  		URL: &url.URL{
  2650  			Scheme: "http",
  2651  		},
  2652  	})
  2653  	want := "http: no Host in request URL"
  2654  	if got := fmt.Sprint(err); got != want {
  2655  		t.Errorf("error = %v; want %q", err, want)
  2656  	}
  2657  }
  2658  
  2659  // Issue 13311
  2660  func TestTransportEmptyMethod(t *testing.T) {
  2661  	req, _ := NewRequest("GET", "http://foo.com/", nil)
  2662  	req.Method = ""                                 // docs say "For client requests an empty string means GET"
  2663  	got, err := httputil.DumpRequestOut(req, false) // DumpRequestOut uses Transport
  2664  	if err != nil {
  2665  		t.Fatal(err)
  2666  	}
  2667  	if !strings.Contains(string(got), "GET ") {
  2668  		t.Fatalf("expected substring 'GET '; got: %s", got)
  2669  	}
  2670  }
  2671  
  2672  func TestTransportSocketLateBinding(t *testing.T) {
  2673  	setParallel(t)
  2674  	defer afterTest(t)
  2675  
  2676  	mux := NewServeMux()
  2677  	fooGate := make(chan bool, 1)
  2678  	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
  2679  		w.Header().Set("foo-ipport", r.RemoteAddr)
  2680  		w.(Flusher).Flush()
  2681  		<-fooGate
  2682  	})
  2683  	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
  2684  		w.Header().Set("bar-ipport", r.RemoteAddr)
  2685  	})
  2686  	ts := httptest.NewServer(mux)
  2687  	defer ts.Close()
  2688  
  2689  	dialGate := make(chan bool, 1)
  2690  	c := ts.Client()
  2691  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  2692  		if <-dialGate {
  2693  			return net.Dial(n, addr)
  2694  		}
  2695  		return nil, errors.New("manually closed")
  2696  	}
  2697  
  2698  	dialGate <- true // only allow one dial
  2699  	fooRes, err := c.Get(ts.URL + "/foo")
  2700  	if err != nil {
  2701  		t.Fatal(err)
  2702  	}
  2703  	fooAddr := fooRes.Header.Get("foo-ipport")
  2704  	if fooAddr == "" {
  2705  		t.Fatal("No addr on /foo request")
  2706  	}
  2707  	time.AfterFunc(200*time.Millisecond, func() {
  2708  		// let the foo response finish so we can use its
  2709  		// connection for /bar
  2710  		fooGate <- true
  2711  		io.Copy(ioutil.Discard, fooRes.Body)
  2712  		fooRes.Body.Close()
  2713  	})
  2714  
  2715  	barRes, err := c.Get(ts.URL + "/bar")
  2716  	if err != nil {
  2717  		t.Fatal(err)
  2718  	}
  2719  	barAddr := barRes.Header.Get("bar-ipport")
  2720  	if barAddr != fooAddr {
  2721  		t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
  2722  	}
  2723  	barRes.Body.Close()
  2724  	dialGate <- false
  2725  }
  2726  
  2727  // Issue 2184
  2728  func TestTransportReading100Continue(t *testing.T) {
  2729  	defer afterTest(t)
  2730  
  2731  	const numReqs = 5
  2732  	reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
  2733  	reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
  2734  
  2735  	send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
  2736  		defer w.Close()
  2737  		defer r.Close()
  2738  		br := bufio.NewReader(r)
  2739  		n := 0
  2740  		for {
  2741  			n++
  2742  			req, err := ReadRequest(br)
  2743  			if err == io.EOF {
  2744  				return
  2745  			}
  2746  			if err != nil {
  2747  				t.Error(err)
  2748  				return
  2749  			}
  2750  			slurp, err := ioutil.ReadAll(req.Body)
  2751  			if err != nil {
  2752  				t.Errorf("Server request body slurp: %v", err)
  2753  				return
  2754  			}
  2755  			id := req.Header.Get("Request-Id")
  2756  			resCode := req.Header.Get("X-Want-Response-Code")
  2757  			if resCode == "" {
  2758  				resCode = "100 Continue"
  2759  				if string(slurp) != reqBody(n) {
  2760  					t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
  2761  				}
  2762  			}
  2763  			body := fmt.Sprintf("Response number %d", n)
  2764  			v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
  2765  Date: Thu, 28 Feb 2013 17:55:41 GMT
  2766  
  2767  HTTP/1.1 200 OK
  2768  Content-Type: text/html
  2769  Echo-Request-Id: %s
  2770  Content-Length: %d
  2771  
  2772  %s`, resCode, id, len(body), body), "\n", "\r\n", -1))
  2773  			w.Write(v)
  2774  			if id == reqID(numReqs) {
  2775  				return
  2776  			}
  2777  		}
  2778  
  2779  	}
  2780  
  2781  	tr := &Transport{
  2782  		Dial: func(n, addr string) (net.Conn, error) {
  2783  			sr, sw := io.Pipe() // server read/write
  2784  			cr, cw := io.Pipe() // client read/write
  2785  			conn := &rwTestConn{
  2786  				Reader: cr,
  2787  				Writer: sw,
  2788  				closeFunc: func() error {
  2789  					sw.Close()
  2790  					cw.Close()
  2791  					return nil
  2792  				},
  2793  			}
  2794  			go send100Response(cw, sr)
  2795  			return conn, nil
  2796  		},
  2797  		DisableKeepAlives: false,
  2798  	}
  2799  	defer tr.CloseIdleConnections()
  2800  	c := &Client{Transport: tr}
  2801  
  2802  	testResponse := func(req *Request, name string, wantCode int) {
  2803  		t.Helper()
  2804  		res, err := c.Do(req)
  2805  		if err != nil {
  2806  			t.Fatalf("%s: Do: %v", name, err)
  2807  		}
  2808  		if res.StatusCode != wantCode {
  2809  			t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
  2810  		}
  2811  		if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
  2812  			t.Errorf("%s: response id %q != request id %q", name, idBack, id)
  2813  		}
  2814  		_, err = ioutil.ReadAll(res.Body)
  2815  		if err != nil {
  2816  			t.Fatalf("%s: Slurp error: %v", name, err)
  2817  		}
  2818  	}
  2819  
  2820  	// Few 100 responses, making sure we're not off-by-one.
  2821  	for i := 1; i <= numReqs; i++ {
  2822  		req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
  2823  		req.Header.Set("Request-Id", reqID(i))
  2824  		testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
  2825  	}
  2826  }
  2827  
  2828  // Issue 17739: the HTTP client must ignore any unknown 1xx
  2829  // informational responses before the actual response.
  2830  func TestTransportIgnore1xxResponses(t *testing.T) {
  2831  	setParallel(t)
  2832  	defer afterTest(t)
  2833  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  2834  		conn, buf, _ := w.(Hijacker).Hijack()
  2835  		buf.Write([]byte("HTTP/1.1 123 OneTwoThree\r\nFoo: bar\r\n\r\nHTTP/1.1 200 OK\r\nBar: baz\r\nContent-Length: 5\r\n\r\nHello"))
  2836  		buf.Flush()
  2837  		conn.Close()
  2838  	}))
  2839  	defer cst.close()
  2840  	cst.tr.DisableKeepAlives = true // prevent log spam; our test server is hanging up anyway
  2841  
  2842  	var got bytes.Buffer
  2843  
  2844  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  2845  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  2846  		Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
  2847  			fmt.Fprintf(&got, "1xx: code=%v, header=%v\n", code, header)
  2848  			return nil
  2849  		},
  2850  	}))
  2851  	res, err := cst.c.Do(req)
  2852  	if err != nil {
  2853  		t.Fatal(err)
  2854  	}
  2855  	defer res.Body.Close()
  2856  
  2857  	res.Write(&got)
  2858  	want := "1xx: code=123, header=map[Foo:[bar]]\nHTTP/1.1 200 OK\r\nContent-Length: 5\r\nBar: baz\r\n\r\nHello"
  2859  	if got.String() != want {
  2860  		t.Errorf(" got: %q\nwant: %q\n", got.Bytes(), want)
  2861  	}
  2862  }
  2863  
  2864  func TestTransportLimits1xxResponses(t *testing.T) {
  2865  	setParallel(t)
  2866  	defer afterTest(t)
  2867  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  2868  		conn, buf, _ := w.(Hijacker).Hijack()
  2869  		for i := 0; i < 10; i++ {
  2870  			buf.Write([]byte("HTTP/1.1 123 OneTwoThree\r\n\r\n"))
  2871  		}
  2872  		buf.Write([]byte("HTTP/1.1 204 No Content\r\n\r\n"))
  2873  		buf.Flush()
  2874  		conn.Close()
  2875  	}))
  2876  	defer cst.close()
  2877  	cst.tr.DisableKeepAlives = true // prevent log spam; our test server is hanging up anyway
  2878  
  2879  	res, err := cst.c.Get(cst.ts.URL)
  2880  	if res != nil {
  2881  		defer res.Body.Close()
  2882  	}
  2883  	got := fmt.Sprint(err)
  2884  	wantSub := "too many 1xx informational responses"
  2885  	if !strings.Contains(got, wantSub) {
  2886  		t.Errorf("Get error = %v; want substring %q", err, wantSub)
  2887  	}
  2888  }
  2889  
  2890  // Issue 26161: the HTTP client must treat 101 responses
  2891  // as the final response.
  2892  func TestTransportTreat101Terminal(t *testing.T) {
  2893  	setParallel(t)
  2894  	defer afterTest(t)
  2895  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  2896  		conn, buf, _ := w.(Hijacker).Hijack()
  2897  		buf.Write([]byte("HTTP/1.1 101 Switching Protocols\r\n\r\n"))
  2898  		buf.Write([]byte("HTTP/1.1 204 No Content\r\n\r\n"))
  2899  		buf.Flush()
  2900  		conn.Close()
  2901  	}))
  2902  	defer cst.close()
  2903  	res, err := cst.c.Get(cst.ts.URL)
  2904  	if err != nil {
  2905  		t.Fatal(err)
  2906  	}
  2907  	defer res.Body.Close()
  2908  	if res.StatusCode != StatusSwitchingProtocols {
  2909  		t.Errorf("StatusCode = %v; want 101 Switching Protocols", res.StatusCode)
  2910  	}
  2911  }
  2912  
  2913  type proxyFromEnvTest struct {
  2914  	req string // URL to fetch; blank means "http://example.com"
  2915  
  2916  	env      string // HTTP_PROXY
  2917  	httpsenv string // HTTPS_PROXY
  2918  	noenv    string // NO_PROXY
  2919  	reqmeth  string // REQUEST_METHOD
  2920  
  2921  	want    string
  2922  	wanterr error
  2923  }
  2924  
  2925  func (t proxyFromEnvTest) String() string {
  2926  	var buf bytes.Buffer
  2927  	space := func() {
  2928  		if buf.Len() > 0 {
  2929  			buf.WriteByte(' ')
  2930  		}
  2931  	}
  2932  	if t.env != "" {
  2933  		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
  2934  	}
  2935  	if t.httpsenv != "" {
  2936  		space()
  2937  		fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv)
  2938  	}
  2939  	if t.noenv != "" {
  2940  		space()
  2941  		fmt.Fprintf(&buf, "no_proxy=%q", t.noenv)
  2942  	}
  2943  	if t.reqmeth != "" {
  2944  		space()
  2945  		fmt.Fprintf(&buf, "request_method=%q", t.reqmeth)
  2946  	}
  2947  	req := "http://example.com"
  2948  	if t.req != "" {
  2949  		req = t.req
  2950  	}
  2951  	space()
  2952  	fmt.Fprintf(&buf, "req=%q", req)
  2953  	return strings.TrimSpace(buf.String())
  2954  }
  2955  
  2956  var proxyFromEnvTests = []proxyFromEnvTest{
  2957  	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2958  	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
  2959  	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
  2960  	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
  2961  	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2962  	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
  2963  	{env: "socks5://127.0.0.1", want: "socks5://127.0.0.1"},
  2964  
  2965  	// Don't use secure for http
  2966  	{req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"},
  2967  	// Use secure for https.
  2968  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"},
  2969  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"},
  2970  
  2971  	// Issue 16405: don't use HTTP_PROXY in a CGI environment,
  2972  	// where HTTP_PROXY can be attacker-controlled.
  2973  	{env: "http://10.1.2.3:8080", reqmeth: "POST",
  2974  		want:    "<nil>",
  2975  		wanterr: errors.New("refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxy")},
  2976  
  2977  	{want: "<nil>"},
  2978  
  2979  	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  2980  	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2981  	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2982  	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
  2983  	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2984  }
  2985  
  2986  func testProxyForRequest(t *testing.T, tt proxyFromEnvTest, proxyForRequest func(req *Request) (*url.URL, error)) {
  2987  	t.Helper()
  2988  	reqURL := tt.req
  2989  	if reqURL == "" {
  2990  		reqURL = "http://example.com"
  2991  	}
  2992  	req, _ := NewRequest("GET", reqURL, nil)
  2993  	url, err := proxyForRequest(req)
  2994  	if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
  2995  		t.Errorf("%v: got error = %q, want %q", tt, g, e)
  2996  		return
  2997  	}
  2998  	if got := fmt.Sprintf("%s", url); got != tt.want {
  2999  		t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
  3000  	}
  3001  }
  3002  
  3003  func TestProxyFromEnvironment(t *testing.T) {
  3004  	ResetProxyEnv()
  3005  	defer ResetProxyEnv()
  3006  	for _, tt := range proxyFromEnvTests {
  3007  		testProxyForRequest(t, tt, func(req *Request) (*url.URL, error) {
  3008  			os.Setenv("HTTP_PROXY", tt.env)
  3009  			os.Setenv("HTTPS_PROXY", tt.httpsenv)
  3010  			os.Setenv("NO_PROXY", tt.noenv)
  3011  			os.Setenv("REQUEST_METHOD", tt.reqmeth)
  3012  			ResetCachedEnvironment()
  3013  			return ProxyFromEnvironment(req)
  3014  		})
  3015  	}
  3016  }
  3017  
  3018  func TestProxyFromEnvironmentLowerCase(t *testing.T) {
  3019  	ResetProxyEnv()
  3020  	defer ResetProxyEnv()
  3021  	for _, tt := range proxyFromEnvTests {
  3022  		testProxyForRequest(t, tt, func(req *Request) (*url.URL, error) {
  3023  			os.Setenv("http_proxy", tt.env)
  3024  			os.Setenv("https_proxy", tt.httpsenv)
  3025  			os.Setenv("no_proxy", tt.noenv)
  3026  			os.Setenv("REQUEST_METHOD", tt.reqmeth)
  3027  			ResetCachedEnvironment()
  3028  			return ProxyFromEnvironment(req)
  3029  		})
  3030  	}
  3031  }
  3032  
  3033  func TestIdleConnChannelLeak(t *testing.T) {
  3034  	// Not parallel: uses global test hooks.
  3035  	var mu sync.Mutex
  3036  	var n int
  3037  
  3038  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3039  		mu.Lock()
  3040  		n++
  3041  		mu.Unlock()
  3042  	}))
  3043  	defer ts.Close()
  3044  
  3045  	const nReqs = 5
  3046  	didRead := make(chan bool, nReqs)
  3047  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
  3048  	defer SetReadLoopBeforeNextReadHook(nil)
  3049  
  3050  	c := ts.Client()
  3051  	tr := c.Transport.(*Transport)
  3052  	tr.Dial = func(netw, addr string) (net.Conn, error) {
  3053  		return net.Dial(netw, ts.Listener.Addr().String())
  3054  	}
  3055  
  3056  	// First, without keep-alives.
  3057  	for _, disableKeep := range []bool{true, false} {
  3058  		tr.DisableKeepAlives = disableKeep
  3059  		for i := 0; i < nReqs; i++ {
  3060  			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
  3061  			if err != nil {
  3062  				t.Fatal(err)
  3063  			}
  3064  			// Note: no res.Body.Close is needed here, since the
  3065  			// response Content-Length is zero. Perhaps the test
  3066  			// should be more explicit and use a HEAD, but tests
  3067  			// elsewhere guarantee that zero byte responses generate
  3068  			// a "Content-Length: 0" instead of chunking.
  3069  		}
  3070  
  3071  		// At this point, each of the 5 Transport.readLoop goroutines
  3072  		// are scheduling noting that there are no response bodies (see
  3073  		// earlier comment), and are then calling putIdleConn, which
  3074  		// decrements this count. Usually that happens quickly, which is
  3075  		// why this test has seemed to work for ages. But it's still
  3076  		// racey: we have wait for them to finish first. See Issue 10427
  3077  		for i := 0; i < nReqs; i++ {
  3078  			<-didRead
  3079  		}
  3080  
  3081  		if got := tr.IdleConnWaitMapSizeForTesting(); got != 0 {
  3082  			t.Fatalf("for DisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
  3083  		}
  3084  	}
  3085  }
  3086  
  3087  // Verify the status quo: that the Client.Post function coerces its
  3088  // body into a ReadCloser if it's a Closer, and that the Transport
  3089  // then closes it.
  3090  func TestTransportClosesRequestBody(t *testing.T) {
  3091  	defer afterTest(t)
  3092  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3093  		io.Copy(ioutil.Discard, r.Body)
  3094  	}))
  3095  	defer ts.Close()
  3096  
  3097  	c := ts.Client()
  3098  
  3099  	closes := 0
  3100  
  3101  	res, err := c.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
  3102  	if err != nil {
  3103  		t.Fatal(err)
  3104  	}
  3105  	res.Body.Close()
  3106  	if closes != 1 {
  3107  		t.Errorf("closes = %d; want 1", closes)
  3108  	}
  3109  }
  3110  
  3111  func TestTransportTLSHandshakeTimeout(t *testing.T) {
  3112  	defer afterTest(t)
  3113  	if testing.Short() {
  3114  		t.Skip("skipping in short mode")
  3115  	}
  3116  	ln := newLocalListener(t)
  3117  	defer ln.Close()
  3118  	testdonec := make(chan struct{})
  3119  	defer close(testdonec)
  3120  
  3121  	go func() {
  3122  		c, err := ln.Accept()
  3123  		if err != nil {
  3124  			t.Error(err)
  3125  			return
  3126  		}
  3127  		<-testdonec
  3128  		c.Close()
  3129  	}()
  3130  
  3131  	getdonec := make(chan struct{})
  3132  	go func() {
  3133  		defer close(getdonec)
  3134  		tr := &Transport{
  3135  			Dial: func(_, _ string) (net.Conn, error) {
  3136  				return net.Dial("tcp", ln.Addr().String())
  3137  			},
  3138  			TLSHandshakeTimeout: 250 * time.Millisecond,
  3139  		}
  3140  		cl := &Client{Transport: tr}
  3141  		_, err := cl.Get("https://dummy.tld/")
  3142  		if err == nil {
  3143  			t.Error("expected error")
  3144  			return
  3145  		}
  3146  		ue, ok := err.(*url.Error)
  3147  		if !ok {
  3148  			t.Errorf("expected url.Error; got %#v", err)
  3149  			return
  3150  		}
  3151  		ne, ok := ue.Err.(net.Error)
  3152  		if !ok {
  3153  			t.Errorf("expected net.Error; got %#v", err)
  3154  			return
  3155  		}
  3156  		if !ne.Timeout() {
  3157  			t.Errorf("expected timeout error; got %v", err)
  3158  		}
  3159  		if !strings.Contains(err.Error(), "handshake timeout") {
  3160  			t.Errorf("expected 'handshake timeout' in error; got %v", err)
  3161  		}
  3162  	}()
  3163  	select {
  3164  	case <-getdonec:
  3165  	case <-time.After(5 * time.Second):
  3166  		t.Error("test timeout; TLS handshake hung?")
  3167  	}
  3168  }
  3169  
  3170  // Trying to repro golang.org/issue/3514
  3171  func TestTLSServerClosesConnection(t *testing.T) {
  3172  	defer afterTest(t)
  3173  
  3174  	closedc := make(chan bool, 1)
  3175  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3176  		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
  3177  			conn, _, _ := w.(Hijacker).Hijack()
  3178  			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
  3179  			conn.Close()
  3180  			closedc <- true
  3181  			return
  3182  		}
  3183  		fmt.Fprintf(w, "hello")
  3184  	}))
  3185  	defer ts.Close()
  3186  
  3187  	c := ts.Client()
  3188  	tr := c.Transport.(*Transport)
  3189  
  3190  	var nSuccess = 0
  3191  	var errs []error
  3192  	const trials = 20
  3193  	for i := 0; i < trials; i++ {
  3194  		tr.CloseIdleConnections()
  3195  		res, err := c.Get(ts.URL + "/keep-alive-then-die")
  3196  		if err != nil {
  3197  			t.Fatal(err)
  3198  		}
  3199  		<-closedc
  3200  		slurp, err := ioutil.ReadAll(res.Body)
  3201  		if err != nil {
  3202  			t.Fatal(err)
  3203  		}
  3204  		if string(slurp) != "foo" {
  3205  			t.Errorf("Got %q, want foo", slurp)
  3206  		}
  3207  
  3208  		// Now try again and see if we successfully
  3209  		// pick a new connection.
  3210  		res, err = c.Get(ts.URL + "/")
  3211  		if err != nil {
  3212  			errs = append(errs, err)
  3213  			continue
  3214  		}
  3215  		slurp, err = ioutil.ReadAll(res.Body)
  3216  		if err != nil {
  3217  			errs = append(errs, err)
  3218  			continue
  3219  		}
  3220  		nSuccess++
  3221  	}
  3222  	if nSuccess > 0 {
  3223  		t.Logf("successes = %d of %d", nSuccess, trials)
  3224  	} else {
  3225  		t.Errorf("All runs failed:")
  3226  	}
  3227  	for _, err := range errs {
  3228  		t.Logf("  err: %v", err)
  3229  	}
  3230  }
  3231  
  3232  // byteFromChanReader is an io.Reader that reads a single byte at a
  3233  // time from the channel. When the channel is closed, the reader
  3234  // returns io.EOF.
  3235  type byteFromChanReader chan byte
  3236  
  3237  func (c byteFromChanReader) Read(p []byte) (n int, err error) {
  3238  	if len(p) == 0 {
  3239  		return
  3240  	}
  3241  	b, ok := <-c
  3242  	if !ok {
  3243  		return 0, io.EOF
  3244  	}
  3245  	p[0] = b
  3246  	return 1, nil
  3247  }
  3248  
  3249  // Verifies that the Transport doesn't reuse a connection in the case
  3250  // where the server replies before the request has been fully
  3251  // written. We still honor that reply (see TestIssue3595), but don't
  3252  // send future requests on the connection because it's then in a
  3253  // questionable state.
  3254  // golang.org/issue/7569
  3255  func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
  3256  	setParallel(t)
  3257  	defer afterTest(t)
  3258  	var sconn struct {
  3259  		sync.Mutex
  3260  		c net.Conn
  3261  	}
  3262  	var getOkay bool
  3263  	closeConn := func() {
  3264  		sconn.Lock()
  3265  		defer sconn.Unlock()
  3266  		if sconn.c != nil {
  3267  			sconn.c.Close()
  3268  			sconn.c = nil
  3269  			if !getOkay {
  3270  				t.Logf("Closed server connection")
  3271  			}
  3272  		}
  3273  	}
  3274  	defer closeConn()
  3275  
  3276  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3277  		if r.Method == "GET" {
  3278  			io.WriteString(w, "bar")
  3279  			return
  3280  		}
  3281  		conn, _, _ := w.(Hijacker).Hijack()
  3282  		sconn.Lock()
  3283  		sconn.c = conn
  3284  		sconn.Unlock()
  3285  		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
  3286  		go io.Copy(ioutil.Discard, conn)
  3287  	}))
  3288  	defer ts.Close()
  3289  	c := ts.Client()
  3290  
  3291  	const bodySize = 256 << 10
  3292  	finalBit := make(byteFromChanReader, 1)
  3293  	req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
  3294  	req.ContentLength = bodySize
  3295  	res, err := c.Do(req)
  3296  	if err := wantBody(res, err, "foo"); err != nil {
  3297  		t.Errorf("POST response: %v", err)
  3298  	}
  3299  	donec := make(chan bool)
  3300  	go func() {
  3301  		defer close(donec)
  3302  		res, err = c.Get(ts.URL)
  3303  		if err := wantBody(res, err, "bar"); err != nil {
  3304  			t.Errorf("GET response: %v", err)
  3305  			return
  3306  		}
  3307  		getOkay = true // suppress test noise
  3308  	}()
  3309  	time.AfterFunc(5*time.Second, closeConn)
  3310  	select {
  3311  	case <-donec:
  3312  		finalBit <- 'x' // unblock the writeloop of the first Post
  3313  		close(finalBit)
  3314  	case <-time.After(7 * time.Second):
  3315  		t.Fatal("timeout waiting for GET request to finish")
  3316  	}
  3317  }
  3318  
  3319  // Tests that we don't leak Transport persistConn.readLoop goroutines
  3320  // when a server hangs up immediately after saying it would keep-alive.
  3321  func TestTransportIssue10457(t *testing.T) {
  3322  	defer afterTest(t) // used to fail in goroutine leak check
  3323  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3324  		// Send a response with no body, keep-alive
  3325  		// (implicit), and then lie and immediately close the
  3326  		// connection. This forces the Transport's readLoop to
  3327  		// immediately Peek an io.EOF and get to the point
  3328  		// that used to hang.
  3329  		conn, _, _ := w.(Hijacker).Hijack()
  3330  		conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
  3331  		conn.Close()
  3332  	}))
  3333  	defer ts.Close()
  3334  	c := ts.Client()
  3335  
  3336  	res, err := c.Get(ts.URL)
  3337  	if err != nil {
  3338  		t.Fatalf("Get: %v", err)
  3339  	}
  3340  	defer res.Body.Close()
  3341  
  3342  	// Just a sanity check that we at least get the response. The real
  3343  	// test here is that the "defer afterTest" above doesn't find any
  3344  	// leaked goroutines.
  3345  	if got, want := res.Header.Get("Foo"), "Bar"; got != want {
  3346  		t.Errorf("Foo header = %q; want %q", got, want)
  3347  	}
  3348  }
  3349  
  3350  type errorReader struct {
  3351  	err error
  3352  }
  3353  
  3354  func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
  3355  
  3356  type closerFunc func() error
  3357  
  3358  func (f closerFunc) Close() error { return f() }
  3359  
  3360  type writerFuncConn struct {
  3361  	net.Conn
  3362  	write func(p []byte) (n int, err error)
  3363  }
  3364  
  3365  func (c writerFuncConn) Write(p []byte) (n int, err error) { return c.write(p) }
  3366  
  3367  // Issues 4677, 18241, and 17844. If we try to reuse a connection that the
  3368  // server is in the process of closing, we may end up successfully writing out
  3369  // our request (or a portion of our request) only to find a connection error
  3370  // when we try to read from (or finish writing to) the socket.
  3371  //
  3372  // NOTE: we resend a request only if:
  3373  //   - we reused a keep-alive connection
  3374  //   - we haven't yet received any header data
  3375  //   - either we wrote no bytes to the server, or the request is idempotent
  3376  // This automatically prevents an infinite resend loop because we'll run out of
  3377  // the cached keep-alive connections eventually.
  3378  func TestRetryRequestsOnError(t *testing.T) {
  3379  	newRequest := func(method, urlStr string, body io.Reader) *Request {
  3380  		req, err := NewRequest(method, urlStr, body)
  3381  		if err != nil {
  3382  			t.Fatal(err)
  3383  		}
  3384  		return req
  3385  	}
  3386  
  3387  	testCases := []struct {
  3388  		name       string
  3389  		failureN   int
  3390  		failureErr error
  3391  		// Note that we can't just re-use the Request object across calls to c.Do
  3392  		// because we need to rewind Body between calls.  (GetBody is only used to
  3393  		// rewind Body on failure and redirects, not just because it's done.)
  3394  		req       func() *Request
  3395  		reqString string
  3396  	}{
  3397  		{
  3398  			name: "IdempotentNoBodySomeWritten",
  3399  			// Believe that we've written some bytes to the server, so we know we're
  3400  			// not just in the "retry when no bytes sent" case".
  3401  			failureN: 1,
  3402  			// Use the specific error that shouldRetryRequest looks for with idempotent requests.
  3403  			failureErr: ExportErrServerClosedIdle,
  3404  			req: func() *Request {
  3405  				return newRequest("GET", "http://fake.golang", nil)
  3406  			},
  3407  			reqString: `GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n`,
  3408  		},
  3409  		{
  3410  			name: "IdempotentGetBodySomeWritten",
  3411  			// Believe that we've written some bytes to the server, so we know we're
  3412  			// not just in the "retry when no bytes sent" case".
  3413  			failureN: 1,
  3414  			// Use the specific error that shouldRetryRequest looks for with idempotent requests.
  3415  			failureErr: ExportErrServerClosedIdle,
  3416  			req: func() *Request {
  3417  				return newRequest("GET", "http://fake.golang", strings.NewReader("foo\n"))
  3418  			},
  3419  			reqString: `GET / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nContent-Length: 4\r\nAccept-Encoding: gzip\r\n\r\nfoo\n`,
  3420  		},
  3421  		{
  3422  			name: "NothingWrittenNoBody",
  3423  			// It's key that we return 0 here -- that's what enables Transport to know
  3424  			// that nothing was written, even though this is a non-idempotent request.
  3425  			failureN:   0,
  3426  			failureErr: errors.New("second write fails"),
  3427  			req: func() *Request {
  3428  				return newRequest("DELETE", "http://fake.golang", nil)
  3429  			},
  3430  			reqString: `DELETE / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip\r\n\r\n`,
  3431  		},
  3432  		{
  3433  			name: "NothingWrittenGetBody",
  3434  			// It's key that we return 0 here -- that's what enables Transport to know
  3435  			// that nothing was written, even though this is a non-idempotent request.
  3436  			failureN:   0,
  3437  			failureErr: errors.New("second write fails"),
  3438  			// Note that NewRequest will set up GetBody for strings.Reader, which is
  3439  			// required for the retry to occur
  3440  			req: func() *Request {
  3441  				return newRequest("POST", "http://fake.golang", strings.NewReader("foo\n"))
  3442  			},
  3443  			reqString: `POST / HTTP/1.1\r\nHost: fake.golang\r\nUser-Agent: Go-http-client/1.1\r\nContent-Length: 4\r\nAccept-Encoding: gzip\r\n\r\nfoo\n`,
  3444  		},
  3445  	}
  3446  
  3447  	for _, tc := range testCases {
  3448  		t.Run(tc.name, func(t *testing.T) {
  3449  			defer afterTest(t)
  3450  
  3451  			var (
  3452  				mu     sync.Mutex
  3453  				logbuf bytes.Buffer
  3454  			)
  3455  			logf := func(format string, args ...interface{}) {
  3456  				mu.Lock()
  3457  				defer mu.Unlock()
  3458  				fmt.Fprintf(&logbuf, format, args...)
  3459  				logbuf.WriteByte('\n')
  3460  			}
  3461  
  3462  			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3463  				logf("Handler")
  3464  				w.Header().Set("X-Status", "ok")
  3465  			}))
  3466  			defer ts.Close()
  3467  
  3468  			var writeNumAtomic int32
  3469  			c := ts.Client()
  3470  			c.Transport.(*Transport).Dial = func(network, addr string) (net.Conn, error) {
  3471  				logf("Dial")
  3472  				c, err := net.Dial(network, ts.Listener.Addr().String())
  3473  				if err != nil {
  3474  					logf("Dial error: %v", err)
  3475  					return nil, err
  3476  				}
  3477  				return &writerFuncConn{
  3478  					Conn: c,
  3479  					write: func(p []byte) (n int, err error) {
  3480  						if atomic.AddInt32(&writeNumAtomic, 1) == 2 {
  3481  							logf("intentional write failure")
  3482  							return tc.failureN, tc.failureErr
  3483  						}
  3484  						logf("Write(%q)", p)
  3485  						return c.Write(p)
  3486  					},
  3487  				}, nil
  3488  			}
  3489  
  3490  			SetRoundTripRetried(func() {
  3491  				logf("Retried.")
  3492  			})
  3493  			defer SetRoundTripRetried(nil)
  3494  
  3495  			for i := 0; i < 3; i++ {
  3496  				t0 := time.Now()
  3497  				res, err := c.Do(tc.req())
  3498  				if err != nil {
  3499  					if time.Since(t0) < MaxWriteWaitBeforeConnReuse/2 {
  3500  						mu.Lock()
  3501  						got := logbuf.String()
  3502  						mu.Unlock()
  3503  						t.Fatalf("i=%d: Do = %v; log:\n%s", i, err, got)
  3504  					}
  3505  					t.Skipf("connection likely wasn't recycled within %d, interfering with actual test; skipping", MaxWriteWaitBeforeConnReuse)
  3506  				}
  3507  				res.Body.Close()
  3508  			}
  3509  
  3510  			mu.Lock()
  3511  			got := logbuf.String()
  3512  			mu.Unlock()
  3513  			want := fmt.Sprintf(`Dial
  3514  Write("%s")
  3515  Handler
  3516  intentional write failure
  3517  Retried.
  3518  Dial
  3519  Write("%s")
  3520  Handler
  3521  Write("%s")
  3522  Handler
  3523  `, tc.reqString, tc.reqString, tc.reqString)
  3524  			if got != want {
  3525  				t.Errorf("Log of events differs. Got:\n%s\nWant:\n%s", got, want)
  3526  			}
  3527  		})
  3528  	}
  3529  }
  3530  
  3531  // Issue 6981
  3532  func TestTransportClosesBodyOnError(t *testing.T) {
  3533  	setParallel(t)
  3534  	defer afterTest(t)
  3535  	readBody := make(chan error, 1)
  3536  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3537  		_, err := ioutil.ReadAll(r.Body)
  3538  		readBody <- err
  3539  	}))
  3540  	defer ts.Close()
  3541  	c := ts.Client()
  3542  	fakeErr := errors.New("fake error")
  3543  	didClose := make(chan bool, 1)
  3544  	req, _ := NewRequest("POST", ts.URL, struct {
  3545  		io.Reader
  3546  		io.Closer
  3547  	}{
  3548  		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}),
  3549  		closerFunc(func() error {
  3550  			select {
  3551  			case didClose <- true:
  3552  			default:
  3553  			}
  3554  			return nil
  3555  		}),
  3556  	})
  3557  	res, err := c.Do(req)
  3558  	if res != nil {
  3559  		defer res.Body.Close()
  3560  	}
  3561  	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
  3562  		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
  3563  	}
  3564  	select {
  3565  	case err := <-readBody:
  3566  		if err == nil {
  3567  			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
  3568  		}
  3569  	case <-time.After(5 * time.Second):
  3570  		t.Error("timeout waiting for server handler to complete")
  3571  	}
  3572  	select {
  3573  	case <-didClose:
  3574  	default:
  3575  		t.Errorf("didn't see Body.Close")
  3576  	}
  3577  }
  3578  
  3579  func TestTransportDialTLS(t *testing.T) {
  3580  	setParallel(t)
  3581  	defer afterTest(t)
  3582  	var mu sync.Mutex // guards following
  3583  	var gotReq, didDial bool
  3584  
  3585  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3586  		mu.Lock()
  3587  		gotReq = true
  3588  		mu.Unlock()
  3589  	}))
  3590  	defer ts.Close()
  3591  	c := ts.Client()
  3592  	c.Transport.(*Transport).DialTLS = func(netw, addr string) (net.Conn, error) {
  3593  		mu.Lock()
  3594  		didDial = true
  3595  		mu.Unlock()
  3596  		c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig)
  3597  		if err != nil {
  3598  			return nil, err
  3599  		}
  3600  		return c, c.Handshake()
  3601  	}
  3602  
  3603  	res, err := c.Get(ts.URL)
  3604  	if err != nil {
  3605  		t.Fatal(err)
  3606  	}
  3607  	res.Body.Close()
  3608  	mu.Lock()
  3609  	if !gotReq {
  3610  		t.Error("didn't get request")
  3611  	}
  3612  	if !didDial {
  3613  		t.Error("didn't use dial hook")
  3614  	}
  3615  }
  3616  
  3617  func TestTransportDialContext(t *testing.T) {
  3618  	setParallel(t)
  3619  	defer afterTest(t)
  3620  	var mu sync.Mutex // guards following
  3621  	var gotReq bool
  3622  	var receivedContext context.Context
  3623  
  3624  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3625  		mu.Lock()
  3626  		gotReq = true
  3627  		mu.Unlock()
  3628  	}))
  3629  	defer ts.Close()
  3630  	c := ts.Client()
  3631  	c.Transport.(*Transport).DialContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
  3632  		mu.Lock()
  3633  		receivedContext = ctx
  3634  		mu.Unlock()
  3635  		return net.Dial(netw, addr)
  3636  	}
  3637  
  3638  	req, err := NewRequest("GET", ts.URL, nil)
  3639  	if err != nil {
  3640  		t.Fatal(err)
  3641  	}
  3642  	ctx := context.WithValue(context.Background(), "some-key", "some-value")
  3643  	res, err := c.Do(req.WithContext(ctx))
  3644  	if err != nil {
  3645  		t.Fatal(err)
  3646  	}
  3647  	res.Body.Close()
  3648  	mu.Lock()
  3649  	if !gotReq {
  3650  		t.Error("didn't get request")
  3651  	}
  3652  	if receivedContext != ctx {
  3653  		t.Error("didn't receive correct context")
  3654  	}
  3655  }
  3656  
  3657  func TestTransportDialTLSContext(t *testing.T) {
  3658  	setParallel(t)
  3659  	defer afterTest(t)
  3660  	var mu sync.Mutex // guards following
  3661  	var gotReq bool
  3662  	var receivedContext context.Context
  3663  
  3664  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3665  		mu.Lock()
  3666  		gotReq = true
  3667  		mu.Unlock()
  3668  	}))
  3669  	defer ts.Close()
  3670  	c := ts.Client()
  3671  	c.Transport.(*Transport).DialTLSContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
  3672  		mu.Lock()
  3673  		receivedContext = ctx
  3674  		mu.Unlock()
  3675  		c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig)
  3676  		if err != nil {
  3677  			return nil, err
  3678  		}
  3679  		return c, c.Handshake()
  3680  	}
  3681  
  3682  	req, err := NewRequest("GET", ts.URL, nil)
  3683  	if err != nil {
  3684  		t.Fatal(err)
  3685  	}
  3686  	ctx := context.WithValue(context.Background(), "some-key", "some-value")
  3687  	res, err := c.Do(req.WithContext(ctx))
  3688  	if err != nil {
  3689  		t.Fatal(err)
  3690  	}
  3691  	res.Body.Close()
  3692  	mu.Lock()
  3693  	if !gotReq {
  3694  		t.Error("didn't get request")
  3695  	}
  3696  	if receivedContext != ctx {
  3697  		t.Error("didn't receive correct context")
  3698  	}
  3699  }
  3700  
  3701  // Test for issue 8755
  3702  // Ensure that if a proxy returns an error, it is exposed by RoundTrip
  3703  func TestRoundTripReturnsProxyError(t *testing.T) {
  3704  	badProxy := func(*Request) (*url.URL, error) {
  3705  		return nil, errors.New("errorMessage")
  3706  	}
  3707  
  3708  	tr := &Transport{Proxy: badProxy}
  3709  
  3710  	req, _ := NewRequest("GET", "http://example.com", nil)
  3711  
  3712  	_, err := tr.RoundTrip(req)
  3713  
  3714  	if err == nil {
  3715  		t.Error("Expected proxy error to be returned by RoundTrip")
  3716  	}
  3717  }
  3718  
  3719  // tests that putting an idle conn after a call to CloseIdleConns does return it
  3720  func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
  3721  	tr := &Transport{}
  3722  	wantIdle := func(when string, n int) bool {
  3723  		got := tr.IdleConnCountForTesting("http", "example.com") // key used by PutIdleTestConn
  3724  		if got == n {
  3725  			return true
  3726  		}
  3727  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  3728  		return false
  3729  	}
  3730  	wantIdle("start", 0)
  3731  	if !tr.PutIdleTestConn("http", "example.com") {
  3732  		t.Fatal("put failed")
  3733  	}
  3734  	if !tr.PutIdleTestConn("http", "example.com") {
  3735  		t.Fatal("second put failed")
  3736  	}
  3737  	wantIdle("after put", 2)
  3738  	tr.CloseIdleConnections()
  3739  	if !tr.IsIdleForTesting() {
  3740  		t.Error("should be idle after CloseIdleConnections")
  3741  	}
  3742  	wantIdle("after close idle", 0)
  3743  	if tr.PutIdleTestConn("http", "example.com") {
  3744  		t.Fatal("put didn't fail")
  3745  	}
  3746  	wantIdle("after second put", 0)
  3747  
  3748  	tr.QueueForIdleConnForTesting() // should toggle the transport out of idle mode
  3749  	if tr.IsIdleForTesting() {
  3750  		t.Error("shouldn't be idle after QueueForIdleConnForTesting")
  3751  	}
  3752  	if !tr.PutIdleTestConn("http", "example.com") {
  3753  		t.Fatal("after re-activation")
  3754  	}
  3755  	wantIdle("after final put", 1)
  3756  }
  3757  
  3758  // Test for issue 34282
  3759  // Ensure that getConn doesn't call the GotConn trace hook on a HTTP/2 idle conn
  3760  func TestTransportTraceGotConnH2IdleConns(t *testing.T) {
  3761  	tr := &Transport{}
  3762  	wantIdle := func(when string, n int) bool {
  3763  		got := tr.IdleConnCountForTesting("https", "example.com:443") // key used by PutIdleTestConnH2
  3764  		if got == n {
  3765  			return true
  3766  		}
  3767  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  3768  		return false
  3769  	}
  3770  	wantIdle("start", 0)
  3771  	alt := funcRoundTripper(func() {})
  3772  	if !tr.PutIdleTestConnH2("https", "example.com:443", alt) {
  3773  		t.Fatal("put failed")
  3774  	}
  3775  	wantIdle("after put", 1)
  3776  	ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  3777  		GotConn: func(httptrace.GotConnInfo) {
  3778  			// tr.getConn should leave it for the HTTP/2 alt to call GotConn.
  3779  			t.Error("GotConn called")
  3780  		},
  3781  	})
  3782  	req, _ := NewRequestWithContext(ctx, MethodGet, "https://example.com", nil)
  3783  	_, err := tr.RoundTrip(req)
  3784  	if err != errFakeRoundTrip {
  3785  		t.Errorf("got error: %v; want %q", err, errFakeRoundTrip)
  3786  	}
  3787  	wantIdle("after round trip", 1)
  3788  }
  3789  
  3790  func TestTransportRemovesH2ConnsAfterIdle(t *testing.T) {
  3791  	if testing.Short() {
  3792  		t.Skip("skipping in short mode")
  3793  	}
  3794  
  3795  	trFunc := func(tr *Transport) {
  3796  		tr.MaxConnsPerHost = 1
  3797  		tr.MaxIdleConnsPerHost = 1
  3798  		tr.IdleConnTimeout = 10 * time.Millisecond
  3799  	}
  3800  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), trFunc)
  3801  	defer cst.close()
  3802  
  3803  	if _, err := cst.c.Get(cst.ts.URL); err != nil {
  3804  		t.Fatalf("got error: %s", err)
  3805  	}
  3806  
  3807  	time.Sleep(100 * time.Millisecond)
  3808  	got := make(chan error)
  3809  	go func() {
  3810  		if _, err := cst.c.Get(cst.ts.URL); err != nil {
  3811  			got <- err
  3812  		}
  3813  		close(got)
  3814  	}()
  3815  
  3816  	timeout := time.NewTimer(5 * time.Second)
  3817  	defer timeout.Stop()
  3818  	select {
  3819  	case err := <-got:
  3820  		if err != nil {
  3821  			t.Fatalf("got error: %s", err)
  3822  		}
  3823  	case <-timeout.C:
  3824  		t.Fatal("request never completed")
  3825  	}
  3826  }
  3827  
  3828  // This tests that a client requesting a content range won't also
  3829  // implicitly ask for gzip support. If they want that, they need to do it
  3830  // on their own.
  3831  // golang.org/issue/8923
  3832  func TestTransportRangeAndGzip(t *testing.T) {
  3833  	defer afterTest(t)
  3834  	reqc := make(chan *Request, 1)
  3835  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3836  		reqc <- r
  3837  	}))
  3838  	defer ts.Close()
  3839  	c := ts.Client()
  3840  
  3841  	req, _ := NewRequest("GET", ts.URL, nil)
  3842  	req.Header.Set("Range", "bytes=7-11")
  3843  	res, err := c.Do(req)
  3844  	if err != nil {
  3845  		t.Fatal(err)
  3846  	}
  3847  
  3848  	select {
  3849  	case r := <-reqc:
  3850  		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  3851  			t.Error("Transport advertised gzip support in the Accept header")
  3852  		}
  3853  		if r.Header.Get("Range") == "" {
  3854  			t.Error("no Range in request")
  3855  		}
  3856  	case <-time.After(10 * time.Second):
  3857  		t.Fatal("timeout")
  3858  	}
  3859  	res.Body.Close()
  3860  }
  3861  
  3862  // Test for issue 10474
  3863  func TestTransportResponseCancelRace(t *testing.T) {
  3864  	defer afterTest(t)
  3865  
  3866  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3867  		// important that this response has a body.
  3868  		var b [1024]byte
  3869  		w.Write(b[:])
  3870  	}))
  3871  	defer ts.Close()
  3872  	tr := ts.Client().Transport.(*Transport)
  3873  
  3874  	req, err := NewRequest("GET", ts.URL, nil)
  3875  	if err != nil {
  3876  		t.Fatal(err)
  3877  	}
  3878  	res, err := tr.RoundTrip(req)
  3879  	if err != nil {
  3880  		t.Fatal(err)
  3881  	}
  3882  	// If we do an early close, Transport just throws the connection away and
  3883  	// doesn't reuse it. In order to trigger the bug, it has to reuse the connection
  3884  	// so read the body
  3885  	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
  3886  		t.Fatal(err)
  3887  	}
  3888  
  3889  	req2, err := NewRequest("GET", ts.URL, nil)
  3890  	if err != nil {
  3891  		t.Fatal(err)
  3892  	}
  3893  	tr.CancelRequest(req)
  3894  	res, err = tr.RoundTrip(req2)
  3895  	if err != nil {
  3896  		t.Fatal(err)
  3897  	}
  3898  	res.Body.Close()
  3899  }
  3900  
  3901  // Test for issue 19248: Content-Encoding's value is case insensitive.
  3902  func TestTransportContentEncodingCaseInsensitive(t *testing.T) {
  3903  	setParallel(t)
  3904  	defer afterTest(t)
  3905  	for _, ce := range []string{"gzip", "GZIP"} {
  3906  		ce := ce
  3907  		t.Run(ce, func(t *testing.T) {
  3908  			const encodedString = "Hello Gopher"
  3909  			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3910  				w.Header().Set("Content-Encoding", ce)
  3911  				gz := gzip.NewWriter(w)
  3912  				gz.Write([]byte(encodedString))
  3913  				gz.Close()
  3914  			}))
  3915  			defer ts.Close()
  3916  
  3917  			res, err := ts.Client().Get(ts.URL)
  3918  			if err != nil {
  3919  				t.Fatal(err)
  3920  			}
  3921  
  3922  			body, err := ioutil.ReadAll(res.Body)
  3923  			res.Body.Close()
  3924  			if err != nil {
  3925  				t.Fatal(err)
  3926  			}
  3927  
  3928  			if string(body) != encodedString {
  3929  				t.Fatalf("Expected body %q, got: %q\n", encodedString, string(body))
  3930  			}
  3931  		})
  3932  	}
  3933  }
  3934  
  3935  func TestTransportDialCancelRace(t *testing.T) {
  3936  	defer afterTest(t)
  3937  
  3938  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  3939  	defer ts.Close()
  3940  	tr := ts.Client().Transport.(*Transport)
  3941  
  3942  	req, err := NewRequest("GET", ts.URL, nil)
  3943  	if err != nil {
  3944  		t.Fatal(err)
  3945  	}
  3946  	SetEnterRoundTripHook(func() {
  3947  		tr.CancelRequest(req)
  3948  	})
  3949  	defer SetEnterRoundTripHook(nil)
  3950  	res, err := tr.RoundTrip(req)
  3951  	if err != ExportErrRequestCanceled {
  3952  		t.Errorf("expected canceled request error; got %v", err)
  3953  		if err == nil {
  3954  			res.Body.Close()
  3955  		}
  3956  	}
  3957  }
  3958  
  3959  // logWritesConn is a net.Conn that logs each Write call to writes
  3960  // and then proxies to w.
  3961  // It proxies Read calls to a reader it receives from rch.
  3962  type logWritesConn struct {
  3963  	net.Conn // nil. crash on use.
  3964  
  3965  	w io.Writer
  3966  
  3967  	rch <-chan io.Reader
  3968  	r   io.Reader // nil until received by rch
  3969  
  3970  	mu     sync.Mutex
  3971  	writes []string
  3972  }
  3973  
  3974  func (c *logWritesConn) Write(p []byte) (n int, err error) {
  3975  	c.mu.Lock()
  3976  	defer c.mu.Unlock()
  3977  	c.writes = append(c.writes, string(p))
  3978  	return c.w.Write(p)
  3979  }
  3980  
  3981  func (c *logWritesConn) Read(p []byte) (n int, err error) {
  3982  	if c.r == nil {
  3983  		c.r = <-c.rch
  3984  	}
  3985  	return c.r.Read(p)
  3986  }
  3987  
  3988  func (c *logWritesConn) Close() error { return nil }
  3989  
  3990  // Issue 6574
  3991  func TestTransportFlushesBodyChunks(t *testing.T) {
  3992  	defer afterTest(t)
  3993  	resBody := make(chan io.Reader, 1)
  3994  	connr, connw := io.Pipe() // connection pipe pair
  3995  	lw := &logWritesConn{
  3996  		rch: resBody,
  3997  		w:   connw,
  3998  	}
  3999  	tr := &Transport{
  4000  		Dial: func(network, addr string) (net.Conn, error) {
  4001  			return lw, nil
  4002  		},
  4003  	}
  4004  	bodyr, bodyw := io.Pipe() // body pipe pair
  4005  	go func() {
  4006  		defer bodyw.Close()
  4007  		for i := 0; i < 3; i++ {
  4008  			fmt.Fprintf(bodyw, "num%d\n", i)
  4009  		}
  4010  	}()
  4011  	resc := make(chan *Response)
  4012  	go func() {
  4013  		req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
  4014  		req.Header.Set("User-Agent", "x") // known value for test
  4015  		res, err := tr.RoundTrip(req)
  4016  		if err != nil {
  4017  			t.Errorf("RoundTrip: %v", err)
  4018  			close(resc)
  4019  			return
  4020  		}
  4021  		resc <- res
  4022  
  4023  	}()
  4024  	// Fully consume the request before checking the Write log vs. want.
  4025  	req, err := ReadRequest(bufio.NewReader(connr))
  4026  	if err != nil {
  4027  		t.Fatal(err)
  4028  	}
  4029  	io.Copy(ioutil.Discard, req.Body)
  4030  
  4031  	// Unblock the transport's roundTrip goroutine.
  4032  	resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
  4033  	res, ok := <-resc
  4034  	if !ok {
  4035  		return
  4036  	}
  4037  	defer res.Body.Close()
  4038  
  4039  	want := []string{
  4040  		"POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n",
  4041  		"5\r\nnum0\n\r\n",
  4042  		"5\r\nnum1\n\r\n",
  4043  		"5\r\nnum2\n\r\n",
  4044  		"0\r\n\r\n",
  4045  	}
  4046  	if !reflect.DeepEqual(lw.writes, want) {
  4047  		t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
  4048  	}
  4049  }
  4050  
  4051  // Issue 22088: flush Transport request headers if we're not sure the body won't block on read.
  4052  func TestTransportFlushesRequestHeader(t *testing.T) {
  4053  	defer afterTest(t)
  4054  	gotReq := make(chan struct{})
  4055  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4056  		close(gotReq)
  4057  	}))
  4058  	defer cst.close()
  4059  
  4060  	pr, pw := io.Pipe()
  4061  	req, err := NewRequest("POST", cst.ts.URL, pr)
  4062  	if err != nil {
  4063  		t.Fatal(err)
  4064  	}
  4065  	gotRes := make(chan struct{})
  4066  	go func() {
  4067  		defer close(gotRes)
  4068  		res, err := cst.tr.RoundTrip(req)
  4069  		if err != nil {
  4070  			t.Error(err)
  4071  			return
  4072  		}
  4073  		res.Body.Close()
  4074  	}()
  4075  
  4076  	select {
  4077  	case <-gotReq:
  4078  		pw.Close()
  4079  	case <-time.After(5 * time.Second):
  4080  		t.Fatal("timeout waiting for handler to get request")
  4081  	}
  4082  	<-gotRes
  4083  }
  4084  
  4085  // Issue 11745.
  4086  func TestTransportPrefersResponseOverWriteError(t *testing.T) {
  4087  	if testing.Short() {
  4088  		t.Skip("skipping in short mode")
  4089  	}
  4090  	defer afterTest(t)
  4091  	const contentLengthLimit = 1024 * 1024 // 1MB
  4092  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4093  		if r.ContentLength >= contentLengthLimit {
  4094  			w.WriteHeader(StatusBadRequest)
  4095  			r.Body.Close()
  4096  			return
  4097  		}
  4098  		w.WriteHeader(StatusOK)
  4099  	}))
  4100  	defer ts.Close()
  4101  	c := ts.Client()
  4102  
  4103  	fail := 0
  4104  	count := 100
  4105  	bigBody := strings.Repeat("a", contentLengthLimit*2)
  4106  	for i := 0; i < count; i++ {
  4107  		req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
  4108  		if err != nil {
  4109  			t.Fatal(err)
  4110  		}
  4111  		resp, err := c.Do(req)
  4112  		if err != nil {
  4113  			fail++
  4114  			t.Logf("%d = %#v", i, err)
  4115  			if ue, ok := err.(*url.Error); ok {
  4116  				t.Logf("urlErr = %#v", ue.Err)
  4117  				if ne, ok := ue.Err.(*net.OpError); ok {
  4118  					t.Logf("netOpError = %#v", ne.Err)
  4119  				}
  4120  			}
  4121  		} else {
  4122  			resp.Body.Close()
  4123  			if resp.StatusCode != 400 {
  4124  				t.Errorf("Expected status code 400, got %v", resp.Status)
  4125  			}
  4126  		}
  4127  	}
  4128  	if fail > 0 {
  4129  		t.Errorf("Failed %v out of %v\n", fail, count)
  4130  	}
  4131  }
  4132  
  4133  func TestTransportAutomaticHTTP2(t *testing.T) {
  4134  	testTransportAutoHTTP(t, &Transport{}, true)
  4135  }
  4136  
  4137  func TestTransportAutomaticHTTP2_DialerAndTLSConfigSupportsHTTP2AndTLSConfig(t *testing.T) {
  4138  	testTransportAutoHTTP(t, &Transport{
  4139  		ForceAttemptHTTP2: true,
  4140  		TLSClientConfig:   new(tls.Config),
  4141  	}, true)
  4142  }
  4143  
  4144  // golang.org/issue/14391: also check DefaultTransport
  4145  func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
  4146  	testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
  4147  }
  4148  
  4149  func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
  4150  	testTransportAutoHTTP(t, &Transport{
  4151  		TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
  4152  	}, false)
  4153  }
  4154  
  4155  func TestTransportAutomaticHTTP2_TLSConfig(t *testing.T) {
  4156  	testTransportAutoHTTP(t, &Transport{
  4157  		TLSClientConfig: new(tls.Config),
  4158  	}, false)
  4159  }
  4160  
  4161  func TestTransportAutomaticHTTP2_ExpectContinueTimeout(t *testing.T) {
  4162  	testTransportAutoHTTP(t, &Transport{
  4163  		ExpectContinueTimeout: 1 * time.Second,
  4164  	}, true)
  4165  }
  4166  
  4167  func TestTransportAutomaticHTTP2_Dial(t *testing.T) {
  4168  	var d net.Dialer
  4169  	testTransportAutoHTTP(t, &Transport{
  4170  		Dial: d.Dial,
  4171  	}, false)
  4172  }
  4173  
  4174  func TestTransportAutomaticHTTP2_DialContext(t *testing.T) {
  4175  	var d net.Dialer
  4176  	testTransportAutoHTTP(t, &Transport{
  4177  		DialContext: d.DialContext,
  4178  	}, false)
  4179  }
  4180  
  4181  func TestTransportAutomaticHTTP2_DialTLS(t *testing.T) {
  4182  	testTransportAutoHTTP(t, &Transport{
  4183  		DialTLS: func(network, addr string) (net.Conn, error) {
  4184  			panic("unused")
  4185  		},
  4186  	}, false)
  4187  }
  4188  
  4189  func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) {
  4190  	CondSkipHTTP2(t)
  4191  	_, err := tr.RoundTrip(new(Request))
  4192  	if err == nil {
  4193  		t.Error("expected error from RoundTrip")
  4194  	}
  4195  	if reg := tr.TLSNextProto["h2"] != nil; reg != wantH2 {
  4196  		t.Errorf("HTTP/2 registered = %v; want %v", reg, wantH2)
  4197  	}
  4198  }
  4199  
  4200  // Issue 13633: there was a race where we returned bodyless responses
  4201  // to callers before recycling the persistent connection, which meant
  4202  // a client doing two subsequent requests could end up on different
  4203  // connections. It's somewhat harmless but enough tests assume it's
  4204  // not true in order to test other things that it's worth fixing.
  4205  // Plus it's nice to be consistent and not have timing-dependent
  4206  // behavior.
  4207  func TestTransportReuseConnEmptyResponseBody(t *testing.T) {
  4208  	defer afterTest(t)
  4209  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4210  		w.Header().Set("X-Addr", r.RemoteAddr)
  4211  		// Empty response body.
  4212  	}))
  4213  	defer cst.close()
  4214  	n := 100
  4215  	if testing.Short() {
  4216  		n = 10
  4217  	}
  4218  	var firstAddr string
  4219  	for i := 0; i < n; i++ {
  4220  		res, err := cst.c.Get(cst.ts.URL)
  4221  		if err != nil {
  4222  			log.Fatal(err)
  4223  		}
  4224  		addr := res.Header.Get("X-Addr")
  4225  		if i == 0 {
  4226  			firstAddr = addr
  4227  		} else if addr != firstAddr {
  4228  			t.Fatalf("On request %d, addr %q != original addr %q", i+1, addr, firstAddr)
  4229  		}
  4230  		res.Body.Close()
  4231  	}
  4232  }
  4233  
  4234  // Issue 13839
  4235  func TestNoCrashReturningTransportAltConn(t *testing.T) {
  4236  	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
  4237  	if err != nil {
  4238  		t.Fatal(err)
  4239  	}
  4240  	ln := newLocalListener(t)
  4241  	defer ln.Close()
  4242  
  4243  	var wg sync.WaitGroup
  4244  	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  4245  	defer SetPendingDialHooks(nil, nil)
  4246  
  4247  	testDone := make(chan struct{})
  4248  	defer close(testDone)
  4249  	go func() {
  4250  		tln := tls.NewListener(ln, &tls.Config{
  4251  			NextProtos:   []string{"foo"},
  4252  			Certificates: []tls.Certificate{cert},
  4253  		})
  4254  		sc, err := tln.Accept()
  4255  		if err != nil {
  4256  			t.Error(err)
  4257  			return
  4258  		}
  4259  		if err := sc.(*tls.Conn).Handshake(); err != nil {
  4260  			t.Error(err)
  4261  			return
  4262  		}
  4263  		<-testDone
  4264  		sc.Close()
  4265  	}()
  4266  
  4267  	addr := ln.Addr().String()
  4268  
  4269  	req, _ := NewRequest("GET", "https://fake.tld/", nil)
  4270  	cancel := make(chan struct{})
  4271  	req.Cancel = cancel
  4272  
  4273  	doReturned := make(chan bool, 1)
  4274  	madeRoundTripper := make(chan bool, 1)
  4275  
  4276  	tr := &Transport{
  4277  		DisableKeepAlives: true,
  4278  		TLSNextProto: map[string]func(string, *tls.Conn) RoundTripper{
  4279  			"foo": func(authority string, c *tls.Conn) RoundTripper {
  4280  				madeRoundTripper <- true
  4281  				return funcRoundTripper(func() {
  4282  					t.Error("foo RoundTripper should not be called")
  4283  				})
  4284  			},
  4285  		},
  4286  		Dial: func(_, _ string) (net.Conn, error) {
  4287  			panic("shouldn't be called")
  4288  		},
  4289  		DialTLS: func(_, _ string) (net.Conn, error) {
  4290  			tc, err := tls.Dial("tcp", addr, &tls.Config{
  4291  				InsecureSkipVerify: true,
  4292  				NextProtos:         []string{"foo"},
  4293  			})
  4294  			if err != nil {
  4295  				return nil, err
  4296  			}
  4297  			if err := tc.Handshake(); err != nil {
  4298  				return nil, err
  4299  			}
  4300  			close(cancel)
  4301  			<-doReturned
  4302  			return tc, nil
  4303  		},
  4304  	}
  4305  	c := &Client{Transport: tr}
  4306  
  4307  	_, err = c.Do(req)
  4308  	if ue, ok := err.(*url.Error); !ok || ue.Err != ExportErrRequestCanceledConn {
  4309  		t.Fatalf("Do error = %v; want url.Error with errRequestCanceledConn", err)
  4310  	}
  4311  
  4312  	doReturned <- true
  4313  	<-madeRoundTripper
  4314  	wg.Wait()
  4315  }
  4316  
  4317  func TestTransportReuseConnection_Gzip_Chunked(t *testing.T) {
  4318  	testTransportReuseConnection_Gzip(t, true)
  4319  }
  4320  
  4321  func TestTransportReuseConnection_Gzip_ContentLength(t *testing.T) {
  4322  	testTransportReuseConnection_Gzip(t, false)
  4323  }
  4324  
  4325  // Make sure we re-use underlying TCP connection for gzipped responses too.
  4326  func testTransportReuseConnection_Gzip(t *testing.T, chunked bool) {
  4327  	setParallel(t)
  4328  	defer afterTest(t)
  4329  	addr := make(chan string, 2)
  4330  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4331  		addr <- r.RemoteAddr
  4332  		w.Header().Set("Content-Encoding", "gzip")
  4333  		if chunked {
  4334  			w.(Flusher).Flush()
  4335  		}
  4336  		w.Write(rgz) // arbitrary gzip response
  4337  	}))
  4338  	defer ts.Close()
  4339  	c := ts.Client()
  4340  
  4341  	for i := 0; i < 2; i++ {
  4342  		res, err := c.Get(ts.URL)
  4343  		if err != nil {
  4344  			t.Fatal(err)
  4345  		}
  4346  		buf := make([]byte, len(rgz))
  4347  		if n, err := io.ReadFull(res.Body, buf); err != nil {
  4348  			t.Errorf("%d. ReadFull = %v, %v", i, n, err)
  4349  		}
  4350  		// Note: no res.Body.Close call. It should work without it,
  4351  		// since the flate.Reader's internal buffering will hit EOF
  4352  		// and that should be sufficient.
  4353  	}
  4354  	a1, a2 := <-addr, <-addr
  4355  	if a1 != a2 {
  4356  		t.Fatalf("didn't reuse connection")
  4357  	}
  4358  }
  4359  
  4360  func TestTransportResponseHeaderLength(t *testing.T) {
  4361  	setParallel(t)
  4362  	defer afterTest(t)
  4363  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4364  		if r.URL.Path == "/long" {
  4365  			w.Header().Set("Long", strings.Repeat("a", 1<<20))
  4366  		}
  4367  	}))
  4368  	defer ts.Close()
  4369  	c := ts.Client()
  4370  	c.Transport.(*Transport).MaxResponseHeaderBytes = 512 << 10
  4371  
  4372  	if res, err := c.Get(ts.URL); err != nil {
  4373  		t.Fatal(err)
  4374  	} else {
  4375  		res.Body.Close()
  4376  	}
  4377  
  4378  	res, err := c.Get(ts.URL + "/long")
  4379  	if err == nil {
  4380  		defer res.Body.Close()
  4381  		var n int64
  4382  		for k, vv := range res.Header {
  4383  			for _, v := range vv {
  4384  				n += int64(len(k)) + int64(len(v))
  4385  			}
  4386  		}
  4387  		t.Fatalf("Unexpected success. Got %v and %d bytes of response headers", res.Status, n)
  4388  	}
  4389  	if want := "server response headers exceeded 524288 bytes"; !strings.Contains(err.Error(), want) {
  4390  		t.Errorf("got error: %v; want %q", err, want)
  4391  	}
  4392  }
  4393  
  4394  func TestTransportEventTrace(t *testing.T)    { testTransportEventTrace(t, h1Mode, false) }
  4395  func TestTransportEventTrace_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, false) }
  4396  
  4397  // test a non-nil httptrace.ClientTrace but with all hooks set to zero.
  4398  func TestTransportEventTrace_NoHooks(t *testing.T)    { testTransportEventTrace(t, h1Mode, true) }
  4399  func TestTransportEventTrace_NoHooks_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, true) }
  4400  
  4401  func testTransportEventTrace(t *testing.T, h2 bool, noHooks bool) {
  4402  	defer afterTest(t)
  4403  	const resBody = "some body"
  4404  	gotWroteReqEvent := make(chan struct{}, 500)
  4405  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  4406  		if r.Method == "GET" {
  4407  			// Do nothing for the second request.
  4408  			return
  4409  		}
  4410  		if _, err := ioutil.ReadAll(r.Body); err != nil {
  4411  			t.Error(err)
  4412  		}
  4413  		if !noHooks {
  4414  			select {
  4415  			case <-gotWroteReqEvent:
  4416  			case <-time.After(5 * time.Second):
  4417  				t.Error("timeout waiting for WroteRequest event")
  4418  			}
  4419  		}
  4420  		io.WriteString(w, resBody)
  4421  	}))
  4422  	defer cst.close()
  4423  
  4424  	cst.tr.ExpectContinueTimeout = 1 * time.Second
  4425  
  4426  	var mu sync.Mutex // guards buf
  4427  	var buf bytes.Buffer
  4428  	logf := func(format string, args ...interface{}) {
  4429  		mu.Lock()
  4430  		defer mu.Unlock()
  4431  		fmt.Fprintf(&buf, format, args...)
  4432  		buf.WriteByte('\n')
  4433  	}
  4434  
  4435  	addrStr := cst.ts.Listener.Addr().String()
  4436  	ip, port, err := net.SplitHostPort(addrStr)
  4437  	if err != nil {
  4438  		t.Fatal(err)
  4439  	}
  4440  
  4441  	// Install a fake DNS server.
  4442  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, network, host string) ([]net.IPAddr, error) {
  4443  		if host != "dns-is-faked.golang" {
  4444  			t.Errorf("unexpected DNS host lookup for %q/%q", network, host)
  4445  			return nil, nil
  4446  		}
  4447  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  4448  	})
  4449  
  4450  	body := "some body"
  4451  	req, _ := NewRequest("POST", cst.scheme()+"://dns-is-faked.golang:"+port, strings.NewReader(body))
  4452  	req.Header["X-Foo-Multiple-Vals"] = []string{"bar", "baz"}
  4453  	trace := &httptrace.ClientTrace{
  4454  		GetConn:              func(hostPort string) { logf("Getting conn for %v ...", hostPort) },
  4455  		GotConn:              func(ci httptrace.GotConnInfo) { logf("got conn: %+v", ci) },
  4456  		GotFirstResponseByte: func() { logf("first response byte") },
  4457  		PutIdleConn:          func(err error) { logf("PutIdleConn = %v", err) },
  4458  		DNSStart:             func(e httptrace.DNSStartInfo) { logf("DNS start: %+v", e) },
  4459  		DNSDone:              func(e httptrace.DNSDoneInfo) { logf("DNS done: %+v", e) },
  4460  		ConnectStart:         func(network, addr string) { logf("ConnectStart: Connecting to %s %s ...", network, addr) },
  4461  		ConnectDone: func(network, addr string, err error) {
  4462  			if err != nil {
  4463  				t.Errorf("ConnectDone: %v", err)
  4464  			}
  4465  			logf("ConnectDone: connected to %s %s = %v", network, addr, err)
  4466  		},
  4467  		WroteHeaderField: func(key string, value []string) {
  4468  			logf("WroteHeaderField: %s: %v", key, value)
  4469  		},
  4470  		WroteHeaders: func() {
  4471  			logf("WroteHeaders")
  4472  		},
  4473  		Wait100Continue: func() { logf("Wait100Continue") },
  4474  		Got100Continue:  func() { logf("Got100Continue") },
  4475  		WroteRequest: func(e httptrace.WroteRequestInfo) {
  4476  			logf("WroteRequest: %+v", e)
  4477  			gotWroteReqEvent <- struct{}{}
  4478  		},
  4479  	}
  4480  	if h2 {
  4481  		trace.TLSHandshakeStart = func() { logf("tls handshake start") }
  4482  		trace.TLSHandshakeDone = func(s tls.ConnectionState, err error) {
  4483  			logf("tls handshake done. ConnectionState = %v \n err = %v", s, err)
  4484  		}
  4485  	}
  4486  	if noHooks {
  4487  		// zero out all func pointers, trying to get some path to crash
  4488  		*trace = httptrace.ClientTrace{}
  4489  	}
  4490  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  4491  
  4492  	req.Header.Set("Expect", "100-continue")
  4493  	res, err := cst.c.Do(req)
  4494  	if err != nil {
  4495  		t.Fatal(err)
  4496  	}
  4497  	logf("got roundtrip.response")
  4498  	slurp, err := ioutil.ReadAll(res.Body)
  4499  	if err != nil {
  4500  		t.Fatal(err)
  4501  	}
  4502  	logf("consumed body")
  4503  	if string(slurp) != resBody || res.StatusCode != 200 {
  4504  		t.Fatalf("Got %q, %v; want %q, 200 OK", slurp, res.Status, resBody)
  4505  	}
  4506  	res.Body.Close()
  4507  
  4508  	if noHooks {
  4509  		// Done at this point. Just testing a full HTTP
  4510  		// requests can happen with a trace pointing to a zero
  4511  		// ClientTrace, full of nil func pointers.
  4512  		return
  4513  	}
  4514  
  4515  	mu.Lock()
  4516  	got := buf.String()
  4517  	mu.Unlock()
  4518  
  4519  	wantOnce := func(sub string) {
  4520  		if strings.Count(got, sub) != 1 {
  4521  			t.Errorf("expected substring %q exactly once in output.", sub)
  4522  		}
  4523  	}
  4524  	wantOnceOrMore := func(sub string) {
  4525  		if strings.Count(got, sub) == 0 {
  4526  			t.Errorf("expected substring %q at least once in output.", sub)
  4527  		}
  4528  	}
  4529  	wantOnce("Getting conn for dns-is-faked.golang:" + port)
  4530  	wantOnce("DNS start: {Host:dns-is-faked.golang}")
  4531  	wantOnce("DNS done: {Addrs:[{IP:" + ip + " Zone:}] Err:<nil> Coalesced:false}")
  4532  	wantOnce("got conn: {")
  4533  	wantOnceOrMore("Connecting to tcp " + addrStr)
  4534  	wantOnceOrMore("connected to tcp " + addrStr + " = <nil>")
  4535  	wantOnce("Reused:false WasIdle:false IdleTime:0s")
  4536  	wantOnce("first response byte")
  4537  	if h2 {
  4538  		wantOnce("tls handshake start")
  4539  		wantOnce("tls handshake done")
  4540  	} else {
  4541  		wantOnce("PutIdleConn = <nil>")
  4542  		wantOnce("WroteHeaderField: User-Agent: [Go-http-client/1.1]")
  4543  		// TODO(meirf): issue 19761. Make these agnostic to h1/h2. (These are not h1 specific, but the
  4544  		// WroteHeaderField hook is not yet implemented in h2.)
  4545  		wantOnce(fmt.Sprintf("WroteHeaderField: Host: [dns-is-faked.golang:%s]", port))
  4546  		wantOnce(fmt.Sprintf("WroteHeaderField: Content-Length: [%d]", len(body)))
  4547  		wantOnce("WroteHeaderField: X-Foo-Multiple-Vals: [bar baz]")
  4548  		wantOnce("WroteHeaderField: Accept-Encoding: [gzip]")
  4549  	}
  4550  	wantOnce("WroteHeaders")
  4551  	wantOnce("Wait100Continue")
  4552  	wantOnce("Got100Continue")
  4553  	wantOnce("WroteRequest: {Err:<nil>}")
  4554  	if strings.Contains(got, " to udp ") {
  4555  		t.Errorf("should not see UDP (DNS) connections")
  4556  	}
  4557  	if t.Failed() {
  4558  		t.Errorf("Output:\n%s", got)
  4559  	}
  4560  
  4561  	// And do a second request:
  4562  	req, _ = NewRequest("GET", cst.scheme()+"://dns-is-faked.golang:"+port, nil)
  4563  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  4564  	res, err = cst.c.Do(req)
  4565  	if err != nil {
  4566  		t.Fatal(err)
  4567  	}
  4568  	if res.StatusCode != 200 {
  4569  		t.Fatal(res.Status)
  4570  	}
  4571  	res.Body.Close()
  4572  
  4573  	mu.Lock()
  4574  	got = buf.String()
  4575  	mu.Unlock()
  4576  
  4577  	sub := "Getting conn for dns-is-faked.golang:"
  4578  	if gotn, want := strings.Count(got, sub), 2; gotn != want {
  4579  		t.Errorf("substring %q appeared %d times; want %d. Log:\n%s", sub, gotn, want, got)
  4580  	}
  4581  
  4582  }
  4583  
  4584  func TestTransportEventTraceTLSVerify(t *testing.T) {
  4585  	var mu sync.Mutex
  4586  	var buf bytes.Buffer
  4587  	logf := func(format string, args ...interface{}) {
  4588  		mu.Lock()
  4589  		defer mu.Unlock()
  4590  		fmt.Fprintf(&buf, format, args...)
  4591  		buf.WriteByte('\n')
  4592  	}
  4593  
  4594  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4595  		t.Error("Unexpected request")
  4596  	}))
  4597  	defer ts.Close()
  4598  	ts.Config.ErrorLog = log.New(funcWriter(func(p []byte) (int, error) {
  4599  		logf("%s", p)
  4600  		return len(p), nil
  4601  	}), "", 0)
  4602  
  4603  	certpool := x509.NewCertPool()
  4604  	certpool.AddCert(ts.Certificate())
  4605  
  4606  	c := &Client{Transport: &Transport{
  4607  		TLSClientConfig: &tls.Config{
  4608  			ServerName: "dns-is-faked.golang",
  4609  			RootCAs:    certpool,
  4610  		},
  4611  	}}
  4612  
  4613  	trace := &httptrace.ClientTrace{
  4614  		TLSHandshakeStart: func() { logf("TLSHandshakeStart") },
  4615  		TLSHandshakeDone: func(s tls.ConnectionState, err error) {
  4616  			logf("TLSHandshakeDone: ConnectionState = %v \n err = %v", s, err)
  4617  		},
  4618  	}
  4619  
  4620  	req, _ := NewRequest("GET", ts.URL, nil)
  4621  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  4622  	_, err := c.Do(req)
  4623  	if err == nil {
  4624  		t.Error("Expected request to fail TLS verification")
  4625  	}
  4626  
  4627  	mu.Lock()
  4628  	got := buf.String()
  4629  	mu.Unlock()
  4630  
  4631  	wantOnce := func(sub string) {
  4632  		if strings.Count(got, sub) != 1 {
  4633  			t.Errorf("expected substring %q exactly once in output.", sub)
  4634  		}
  4635  	}
  4636  
  4637  	wantOnce("TLSHandshakeStart")
  4638  	wantOnce("TLSHandshakeDone")
  4639  	wantOnce("err = x509: certificate is valid for example.com")
  4640  
  4641  	if t.Failed() {
  4642  		t.Errorf("Output:\n%s", got)
  4643  	}
  4644  }
  4645  
  4646  var (
  4647  	isDNSHijackedOnce sync.Once
  4648  	isDNSHijacked     bool
  4649  )
  4650  
  4651  func skipIfDNSHijacked(t *testing.T) {
  4652  	// Skip this test if the user is using a shady/ISP
  4653  	// DNS server hijacking queries.
  4654  	// See issues 16732, 16716.
  4655  	isDNSHijackedOnce.Do(func() {
  4656  		addrs, _ := net.LookupHost("dns-should-not-resolve.golang")
  4657  		isDNSHijacked = len(addrs) != 0
  4658  	})
  4659  	if isDNSHijacked {
  4660  		t.Skip("skipping; test requires non-hijacking DNS server")
  4661  	}
  4662  }
  4663  
  4664  func TestTransportEventTraceRealDNS(t *testing.T) {
  4665  	skipIfDNSHijacked(t)
  4666  	defer afterTest(t)
  4667  	tr := &Transport{}
  4668  	defer tr.CloseIdleConnections()
  4669  	c := &Client{Transport: tr}
  4670  
  4671  	var mu sync.Mutex // guards buf
  4672  	var buf bytes.Buffer
  4673  	logf := func(format string, args ...interface{}) {
  4674  		mu.Lock()
  4675  		defer mu.Unlock()
  4676  		fmt.Fprintf(&buf, format, args...)
  4677  		buf.WriteByte('\n')
  4678  	}
  4679  
  4680  	req, _ := NewRequest("GET", "http://dns-should-not-resolve.golang:80", nil)
  4681  	trace := &httptrace.ClientTrace{
  4682  		DNSStart:     func(e httptrace.DNSStartInfo) { logf("DNSStart: %+v", e) },
  4683  		DNSDone:      func(e httptrace.DNSDoneInfo) { logf("DNSDone: %+v", e) },
  4684  		ConnectStart: func(network, addr string) { logf("ConnectStart: %s %s", network, addr) },
  4685  		ConnectDone:  func(network, addr string, err error) { logf("ConnectDone: %s %s %v", network, addr, err) },
  4686  	}
  4687  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  4688  
  4689  	resp, err := c.Do(req)
  4690  	if err == nil {
  4691  		resp.Body.Close()
  4692  		t.Fatal("expected error during DNS lookup")
  4693  	}
  4694  
  4695  	mu.Lock()
  4696  	got := buf.String()
  4697  	mu.Unlock()
  4698  
  4699  	wantSub := func(sub string) {
  4700  		if !strings.Contains(got, sub) {
  4701  			t.Errorf("expected substring %q in output.", sub)
  4702  		}
  4703  	}
  4704  	wantSub("DNSStart: {Host:dns-should-not-resolve.golang}")
  4705  	wantSub("DNSDone: {Addrs:[] Err:")
  4706  	if strings.Contains(got, "ConnectStart") || strings.Contains(got, "ConnectDone") {
  4707  		t.Errorf("should not see Connect events")
  4708  	}
  4709  	if t.Failed() {
  4710  		t.Errorf("Output:\n%s", got)
  4711  	}
  4712  }
  4713  
  4714  // Issue 14353: port can only contain digits.
  4715  func TestTransportRejectsAlphaPort(t *testing.T) {
  4716  	res, err := Get("http://dummy.tld:123foo/bar")
  4717  	if err == nil {
  4718  		res.Body.Close()
  4719  		t.Fatal("unexpected success")
  4720  	}
  4721  	ue, ok := err.(*url.Error)
  4722  	if !ok {
  4723  		t.Fatalf("got %#v; want *url.Error", err)
  4724  	}
  4725  	got := ue.Err.Error()
  4726  	want := `invalid port ":123foo" after host`
  4727  	if got != want {
  4728  		t.Errorf("got error %q; want %q", got, want)
  4729  	}
  4730  }
  4731  
  4732  // Test the httptrace.TLSHandshake{Start,Done} hooks with a https http1
  4733  // connections. The http2 test is done in TestTransportEventTrace_h2
  4734  func TestTLSHandshakeTrace(t *testing.T) {
  4735  	defer afterTest(t)
  4736  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  4737  	defer ts.Close()
  4738  
  4739  	var mu sync.Mutex
  4740  	var start, done bool
  4741  	trace := &httptrace.ClientTrace{
  4742  		TLSHandshakeStart: func() {
  4743  			mu.Lock()
  4744  			defer mu.Unlock()
  4745  			start = true
  4746  		},
  4747  		TLSHandshakeDone: func(s tls.ConnectionState, err error) {
  4748  			mu.Lock()
  4749  			defer mu.Unlock()
  4750  			done = true
  4751  			if err != nil {
  4752  				t.Fatal("Expected error to be nil but was:", err)
  4753  			}
  4754  		},
  4755  	}
  4756  
  4757  	c := ts.Client()
  4758  	req, err := NewRequest("GET", ts.URL, nil)
  4759  	if err != nil {
  4760  		t.Fatal("Unable to construct test request:", err)
  4761  	}
  4762  	req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
  4763  
  4764  	r, err := c.Do(req)
  4765  	if err != nil {
  4766  		t.Fatal("Unexpected error making request:", err)
  4767  	}
  4768  	r.Body.Close()
  4769  	mu.Lock()
  4770  	defer mu.Unlock()
  4771  	if !start {
  4772  		t.Fatal("Expected TLSHandshakeStart to be called, but wasn't")
  4773  	}
  4774  	if !done {
  4775  		t.Fatal("Expected TLSHandshakeDone to be called, but wasnt't")
  4776  	}
  4777  }
  4778  
  4779  func TestTransportMaxIdleConns(t *testing.T) {
  4780  	defer afterTest(t)
  4781  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4782  		// No body for convenience.
  4783  	}))
  4784  	defer ts.Close()
  4785  	c := ts.Client()
  4786  	tr := c.Transport.(*Transport)
  4787  	tr.MaxIdleConns = 4
  4788  
  4789  	ip, port, err := net.SplitHostPort(ts.Listener.Addr().String())
  4790  	if err != nil {
  4791  		t.Fatal(err)
  4792  	}
  4793  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, _, host string) ([]net.IPAddr, error) {
  4794  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  4795  	})
  4796  
  4797  	hitHost := func(n int) {
  4798  		req, _ := NewRequest("GET", fmt.Sprintf("http://host-%d.dns-is-faked.golang:"+port, n), nil)
  4799  		req = req.WithContext(ctx)
  4800  		res, err := c.Do(req)
  4801  		if err != nil {
  4802  			t.Fatal(err)
  4803  		}
  4804  		res.Body.Close()
  4805  	}
  4806  	for i := 0; i < 4; i++ {
  4807  		hitHost(i)
  4808  	}
  4809  	want := []string{
  4810  		"|http|host-0.dns-is-faked.golang:" + port,
  4811  		"|http|host-1.dns-is-faked.golang:" + port,
  4812  		"|http|host-2.dns-is-faked.golang:" + port,
  4813  		"|http|host-3.dns-is-faked.golang:" + port,
  4814  	}
  4815  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  4816  		t.Fatalf("idle conn keys mismatch.\n got: %q\nwant: %q\n", got, want)
  4817  	}
  4818  
  4819  	// Now hitting the 5th host should kick out the first host:
  4820  	hitHost(4)
  4821  	want = []string{
  4822  		"|http|host-1.dns-is-faked.golang:" + port,
  4823  		"|http|host-2.dns-is-faked.golang:" + port,
  4824  		"|http|host-3.dns-is-faked.golang:" + port,
  4825  		"|http|host-4.dns-is-faked.golang:" + port,
  4826  	}
  4827  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  4828  		t.Fatalf("idle conn keys mismatch after 5th host.\n got: %q\nwant: %q\n", got, want)
  4829  	}
  4830  }
  4831  
  4832  func TestTransportIdleConnTimeout_h1(t *testing.T) { testTransportIdleConnTimeout(t, h1Mode) }
  4833  func TestTransportIdleConnTimeout_h2(t *testing.T) { testTransportIdleConnTimeout(t, h2Mode) }
  4834  func testTransportIdleConnTimeout(t *testing.T, h2 bool) {
  4835  	if testing.Short() {
  4836  		t.Skip("skipping in short mode")
  4837  	}
  4838  	defer afterTest(t)
  4839  
  4840  	const timeout = 1 * time.Second
  4841  
  4842  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  4843  		// No body for convenience.
  4844  	}))
  4845  	defer cst.close()
  4846  	tr := cst.tr
  4847  	tr.IdleConnTimeout = timeout
  4848  	defer tr.CloseIdleConnections()
  4849  	c := &Client{Transport: tr}
  4850  
  4851  	idleConns := func() []string {
  4852  		if h2 {
  4853  			return tr.IdleConnStrsForTesting_h2()
  4854  		} else {
  4855  			return tr.IdleConnStrsForTesting()
  4856  		}
  4857  	}
  4858  
  4859  	var conn string
  4860  	doReq := func(n int) {
  4861  		req, _ := NewRequest("GET", cst.ts.URL, nil)
  4862  		req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  4863  			PutIdleConn: func(err error) {
  4864  				if err != nil {
  4865  					t.Errorf("failed to keep idle conn: %v", err)
  4866  				}
  4867  			},
  4868  		}))
  4869  		res, err := c.Do(req)
  4870  		if err != nil {
  4871  			t.Fatal(err)
  4872  		}
  4873  		res.Body.Close()
  4874  		conns := idleConns()
  4875  		if len(conns) != 1 {
  4876  			t.Fatalf("req %v: unexpected number of idle conns: %q", n, conns)
  4877  		}
  4878  		if conn == "" {
  4879  			conn = conns[0]
  4880  		}
  4881  		if conn != conns[0] {
  4882  			t.Fatalf("req %v: cached connection changed; expected the same one throughout the test", n)
  4883  		}
  4884  	}
  4885  	for i := 0; i < 3; i++ {
  4886  		doReq(i)
  4887  		time.Sleep(timeout / 2)
  4888  	}
  4889  	time.Sleep(timeout * 3 / 2)
  4890  	if got := idleConns(); len(got) != 0 {
  4891  		t.Errorf("idle conns = %q; want none", got)
  4892  	}
  4893  }
  4894  
  4895  // Issue 16208: Go 1.7 crashed after Transport.IdleConnTimeout if an
  4896  // HTTP/2 connection was established but its caller no longer
  4897  // wanted it. (Assuming the connection cache was enabled, which it is
  4898  // by default)
  4899  //
  4900  // This test reproduced the crash by setting the IdleConnTimeout low
  4901  // (to make the test reasonable) and then making a request which is
  4902  // canceled by the DialTLS hook, which then also waits to return the
  4903  // real connection until after the RoundTrip saw the error.  Then we
  4904  // know the successful tls.Dial from DialTLS will need to go into the
  4905  // idle pool. Then we give it a of time to explode.
  4906  func TestIdleConnH2Crash(t *testing.T) {
  4907  	setParallel(t)
  4908  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4909  		// nothing
  4910  	}))
  4911  	defer cst.close()
  4912  
  4913  	ctx, cancel := context.WithCancel(context.Background())
  4914  	defer cancel()
  4915  
  4916  	sawDoErr := make(chan bool, 1)
  4917  	testDone := make(chan struct{})
  4918  	defer close(testDone)
  4919  
  4920  	cst.tr.IdleConnTimeout = 5 * time.Millisecond
  4921  	cst.tr.DialTLS = func(network, addr string) (net.Conn, error) {
  4922  		c, err := tls.Dial(network, addr, &tls.Config{
  4923  			InsecureSkipVerify: true,
  4924  			NextProtos:         []string{"h2"},
  4925  		})
  4926  		if err != nil {
  4927  			t.Error(err)
  4928  			return nil, err
  4929  		}
  4930  		if cs := c.ConnectionState(); cs.NegotiatedProtocol != "h2" {
  4931  			t.Errorf("protocol = %q; want %q", cs.NegotiatedProtocol, "h2")
  4932  			c.Close()
  4933  			return nil, errors.New("bogus")
  4934  		}
  4935  
  4936  		cancel()
  4937  
  4938  		failTimer := time.NewTimer(5 * time.Second)
  4939  		defer failTimer.Stop()
  4940  		select {
  4941  		case <-sawDoErr:
  4942  		case <-testDone:
  4943  		case <-failTimer.C:
  4944  			t.Error("timeout in DialTLS, waiting too long for cst.c.Do to fail")
  4945  		}
  4946  		return c, nil
  4947  	}
  4948  
  4949  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  4950  	req = req.WithContext(ctx)
  4951  	res, err := cst.c.Do(req)
  4952  	if err == nil {
  4953  		res.Body.Close()
  4954  		t.Fatal("unexpected success")
  4955  	}
  4956  	sawDoErr <- true
  4957  
  4958  	// Wait for the explosion.
  4959  	time.Sleep(cst.tr.IdleConnTimeout * 10)
  4960  }
  4961  
  4962  type funcConn struct {
  4963  	net.Conn
  4964  	read  func([]byte) (int, error)
  4965  	write func([]byte) (int, error)
  4966  }
  4967  
  4968  func (c funcConn) Read(p []byte) (int, error)  { return c.read(p) }
  4969  func (c funcConn) Write(p []byte) (int, error) { return c.write(p) }
  4970  func (c funcConn) Close() error                { return nil }
  4971  
  4972  // Issue 16465: Transport.RoundTrip should return the raw net.Conn.Read error from Peek
  4973  // back to the caller.
  4974  func TestTransportReturnsPeekError(t *testing.T) {
  4975  	errValue := errors.New("specific error value")
  4976  
  4977  	wrote := make(chan struct{})
  4978  	var wroteOnce sync.Once
  4979  
  4980  	tr := &Transport{
  4981  		Dial: func(network, addr string) (net.Conn, error) {
  4982  			c := funcConn{
  4983  				read: func([]byte) (int, error) {
  4984  					<-wrote
  4985  					return 0, errValue
  4986  				},
  4987  				write: func(p []byte) (int, error) {
  4988  					wroteOnce.Do(func() { close(wrote) })
  4989  					return len(p), nil
  4990  				},
  4991  			}
  4992  			return c, nil
  4993  		},
  4994  	}
  4995  	_, err := tr.RoundTrip(httptest.NewRequest("GET", "http://fake.tld/", nil))
  4996  	if err != errValue {
  4997  		t.Errorf("error = %#v; want %v", err, errValue)
  4998  	}
  4999  }
  5000  
  5001  // Issue 13835: international domain names should work
  5002  func TestTransportIDNA_h1(t *testing.T) { testTransportIDNA(t, h1Mode) }
  5003  func TestTransportIDNA_h2(t *testing.T) { testTransportIDNA(t, h2Mode) }
  5004  func testTransportIDNA(t *testing.T, h2 bool) {
  5005  	defer afterTest(t)
  5006  
  5007  	const uniDomain = "гофер.го"
  5008  	const punyDomain = "xn--c1ae0ajs.xn--c1aw"
  5009  
  5010  	var port string
  5011  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  5012  		want := punyDomain + ":" + port
  5013  		if r.Host != want {
  5014  			t.Errorf("Host header = %q; want %q", r.Host, want)
  5015  		}
  5016  		if h2 {
  5017  			if r.TLS == nil {
  5018  				t.Errorf("r.TLS == nil")
  5019  			} else if r.TLS.ServerName != punyDomain {
  5020  				t.Errorf("TLS.ServerName = %q; want %q", r.TLS.ServerName, punyDomain)
  5021  			}
  5022  		}
  5023  		w.Header().Set("Hit-Handler", "1")
  5024  	}))
  5025  	defer cst.close()
  5026  
  5027  	ip, port, err := net.SplitHostPort(cst.ts.Listener.Addr().String())
  5028  	if err != nil {
  5029  		t.Fatal(err)
  5030  	}
  5031  
  5032  	// Install a fake DNS server.
  5033  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, network, host string) ([]net.IPAddr, error) {
  5034  		if host != punyDomain {
  5035  			t.Errorf("got DNS host lookup for %q/%q; want %q", network, host, punyDomain)
  5036  			return nil, nil
  5037  		}
  5038  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  5039  	})
  5040  
  5041  	req, _ := NewRequest("GET", cst.scheme()+"://"+uniDomain+":"+port, nil)
  5042  	trace := &httptrace.ClientTrace{
  5043  		GetConn: func(hostPort string) {
  5044  			want := net.JoinHostPort(punyDomain, port)
  5045  			if hostPort != want {
  5046  				t.Errorf("getting conn for %q; want %q", hostPort, want)
  5047  			}
  5048  		},
  5049  		DNSStart: func(e httptrace.DNSStartInfo) {
  5050  			if e.Host != punyDomain {
  5051  				t.Errorf("DNSStart Host = %q; want %q", e.Host, punyDomain)
  5052  			}
  5053  		},
  5054  	}
  5055  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  5056  
  5057  	res, err := cst.tr.RoundTrip(req)
  5058  	if err != nil {
  5059  		t.Fatal(err)
  5060  	}
  5061  	defer res.Body.Close()
  5062  	if res.Header.Get("Hit-Handler") != "1" {
  5063  		out, err := httputil.DumpResponse(res, true)
  5064  		if err != nil {
  5065  			t.Fatal(err)
  5066  		}
  5067  		t.Errorf("Response body wasn't from Handler. Got:\n%s\n", out)
  5068  	}
  5069  }
  5070  
  5071  // Issue 13290: send User-Agent in proxy CONNECT
  5072  func TestTransportProxyConnectHeader(t *testing.T) {
  5073  	defer afterTest(t)
  5074  	reqc := make(chan *Request, 1)
  5075  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  5076  		if r.Method != "CONNECT" {
  5077  			t.Errorf("method = %q; want CONNECT", r.Method)
  5078  		}
  5079  		reqc <- r
  5080  		c, _, err := w.(Hijacker).Hijack()
  5081  		if err != nil {
  5082  			t.Errorf("Hijack: %v", err)
  5083  			return
  5084  		}
  5085  		c.Close()
  5086  	}))
  5087  	defer ts.Close()
  5088  
  5089  	c := ts.Client()
  5090  	c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) {
  5091  		return url.Parse(ts.URL)
  5092  	}
  5093  	c.Transport.(*Transport).ProxyConnectHeader = Header{
  5094  		"User-Agent": {"foo"},
  5095  		"Other":      {"bar"},
  5096  	}
  5097  
  5098  	res, err := c.Get("https://dummy.tld/") // https to force a CONNECT
  5099  	if err == nil {
  5100  		res.Body.Close()
  5101  		t.Errorf("unexpected success")
  5102  	}
  5103  	select {
  5104  	case <-time.After(3 * time.Second):
  5105  		t.Fatal("timeout")
  5106  	case r := <-reqc:
  5107  		if got, want := r.Header.Get("User-Agent"), "foo"; got != want {
  5108  			t.Errorf("CONNECT request User-Agent = %q; want %q", got, want)
  5109  		}
  5110  		if got, want := r.Header.Get("Other"), "bar"; got != want {
  5111  			t.Errorf("CONNECT request Other = %q; want %q", got, want)
  5112  		}
  5113  	}
  5114  }
  5115  
  5116  var errFakeRoundTrip = errors.New("fake roundtrip")
  5117  
  5118  type funcRoundTripper func()
  5119  
  5120  func (fn funcRoundTripper) RoundTrip(*Request) (*Response, error) {
  5121  	fn()
  5122  	return nil, errFakeRoundTrip
  5123  }
  5124  
  5125  func wantBody(res *Response, err error, want string) error {
  5126  	if err != nil {
  5127  		return err
  5128  	}
  5129  	slurp, err := ioutil.ReadAll(res.Body)
  5130  	if err != nil {
  5131  		return fmt.Errorf("error reading body: %v", err)
  5132  	}
  5133  	if string(slurp) != want {
  5134  		return fmt.Errorf("body = %q; want %q", slurp, want)
  5135  	}
  5136  	if err := res.Body.Close(); err != nil {
  5137  		return fmt.Errorf("body Close = %v", err)
  5138  	}
  5139  	return nil
  5140  }
  5141  
  5142  func newLocalListener(t *testing.T) net.Listener {
  5143  	ln, err := net.Listen("tcp", "127.0.0.1:0")
  5144  	if err != nil {
  5145  		ln, err = net.Listen("tcp6", "[::1]:0")
  5146  	}
  5147  	if err != nil {
  5148  		t.Fatal(err)
  5149  	}
  5150  	return ln
  5151  }
  5152  
  5153  type countCloseReader struct {
  5154  	n *int
  5155  	io.Reader
  5156  }
  5157  
  5158  func (cr countCloseReader) Close() error {
  5159  	(*cr.n)++
  5160  	return nil
  5161  }
  5162  
  5163  // rgz is a gzip quine that uncompresses to itself.
  5164  var rgz = []byte{
  5165  	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  5166  	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  5167  	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  5168  	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  5169  	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  5170  	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  5171  	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  5172  	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  5173  	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  5174  	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  5175  	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  5176  	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  5177  	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  5178  	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  5179  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  5180  	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  5181  	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  5182  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  5183  	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  5184  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  5185  	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  5186  	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  5187  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  5188  	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  5189  	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  5190  	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  5191  	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  5192  	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  5193  	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  5194  	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  5195  	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  5196  	0x00, 0x00,
  5197  }
  5198  
  5199  // Ensure that a missing status doesn't make the server panic
  5200  // See Issue https://golang.org/issues/21701
  5201  func TestMissingStatusNoPanic(t *testing.T) {
  5202  	t.Parallel()
  5203  
  5204  	const want = "unknown status code"
  5205  
  5206  	ln := newLocalListener(t)
  5207  	addr := ln.Addr().String()
  5208  	shutdown := make(chan bool, 1)
  5209  	done := make(chan bool)
  5210  	fullAddrURL := fmt.Sprintf("http://%s", addr)
  5211  	raw := "HTTP/1.1 400\r\n" +
  5212  		"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
  5213  		"Content-Type: text/html; charset=utf-8\r\n" +
  5214  		"Content-Length: 10\r\n" +
  5215  		"Last-Modified: Wed, 30 Aug 2017 19:02:02 GMT\r\n" +
  5216  		"Vary: Accept-Encoding\r\n\r\n" +
  5217  		"Aloha Olaa"
  5218  
  5219  	go func() {
  5220  		defer func() {
  5221  			ln.Close()
  5222  			close(done)
  5223  		}()
  5224  
  5225  		conn, _ := ln.Accept()
  5226  		if conn != nil {
  5227  			io.WriteString(conn, raw)
  5228  			ioutil.ReadAll(conn)
  5229  			conn.Close()
  5230  		}
  5231  	}()
  5232  
  5233  	proxyURL, err := url.Parse(fullAddrURL)
  5234  	if err != nil {
  5235  		t.Fatalf("proxyURL: %v", err)
  5236  	}
  5237  
  5238  	tr := &Transport{Proxy: ProxyURL(proxyURL)}
  5239  
  5240  	req, _ := NewRequest("GET", "https://golang.org/", nil)
  5241  	res, err, panicked := doFetchCheckPanic(tr, req)
  5242  	if panicked {
  5243  		t.Error("panicked, expecting an error")
  5244  	}
  5245  	if res != nil && res.Body != nil {
  5246  		io.Copy(ioutil.Discard, res.Body)
  5247  		res.Body.Close()
  5248  	}
  5249  
  5250  	if err == nil || !strings.Contains(err.Error(), want) {
  5251  		t.Errorf("got=%v want=%q", err, want)
  5252  	}
  5253  
  5254  	close(shutdown)
  5255  	<-done
  5256  }
  5257  
  5258  func doFetchCheckPanic(tr *Transport, req *Request) (res *Response, err error, panicked bool) {
  5259  	defer func() {
  5260  		if r := recover(); r != nil {
  5261  			panicked = true
  5262  		}
  5263  	}()
  5264  	res, err = tr.RoundTrip(req)
  5265  	return
  5266  }
  5267  
  5268  // Issue 22330: do not allow the response body to be read when the status code
  5269  // forbids a response body.
  5270  func TestNoBodyOnChunked304Response(t *testing.T) {
  5271  	defer afterTest(t)
  5272  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5273  		conn, buf, _ := w.(Hijacker).Hijack()
  5274  		buf.Write([]byte("HTTP/1.1 304 NOT MODIFIED\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"))
  5275  		buf.Flush()
  5276  		conn.Close()
  5277  	}))
  5278  	defer cst.close()
  5279  
  5280  	// Our test server above is sending back bogus data after the
  5281  	// response (the "0\r\n\r\n" part), which causes the Transport
  5282  	// code to log spam. Disable keep-alives so we never even try
  5283  	// to reuse the connection.
  5284  	cst.tr.DisableKeepAlives = true
  5285  
  5286  	res, err := cst.c.Get(cst.ts.URL)
  5287  	if err != nil {
  5288  		t.Fatal(err)
  5289  	}
  5290  
  5291  	if res.Body != NoBody {
  5292  		t.Errorf("Unexpected body on 304 response")
  5293  	}
  5294  }
  5295  
  5296  type funcWriter func([]byte) (int, error)
  5297  
  5298  func (f funcWriter) Write(p []byte) (int, error) { return f(p) }
  5299  
  5300  type doneContext struct {
  5301  	context.Context
  5302  	err error
  5303  }
  5304  
  5305  func (doneContext) Done() <-chan struct{} {
  5306  	c := make(chan struct{})
  5307  	close(c)
  5308  	return c
  5309  }
  5310  
  5311  func (d doneContext) Err() error { return d.err }
  5312  
  5313  // Issue 25852: Transport should check whether Context is done early.
  5314  func TestTransportCheckContextDoneEarly(t *testing.T) {
  5315  	tr := &Transport{}
  5316  	req, _ := NewRequest("GET", "http://fake.example/", nil)
  5317  	wantErr := errors.New("some error")
  5318  	req = req.WithContext(doneContext{context.Background(), wantErr})
  5319  	_, err := tr.RoundTrip(req)
  5320  	if err != wantErr {
  5321  		t.Errorf("error = %v; want %v", err, wantErr)
  5322  	}
  5323  }
  5324  
  5325  // Issue 23399: verify that if a client request times out, the Transport's
  5326  // conn is closed so that it's not reused.
  5327  //
  5328  // This is the test variant that times out before the server replies with
  5329  // any response headers.
  5330  func TestClientTimeoutKillsConn_BeforeHeaders(t *testing.T) {
  5331  	setParallel(t)
  5332  	defer afterTest(t)
  5333  	inHandler := make(chan net.Conn, 1)
  5334  	handlerReadReturned := make(chan bool, 1)
  5335  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5336  		conn, _, err := w.(Hijacker).Hijack()
  5337  		if err != nil {
  5338  			t.Error(err)
  5339  			return
  5340  		}
  5341  		inHandler <- conn
  5342  		n, err := conn.Read([]byte{0})
  5343  		if n != 0 || err != io.EOF {
  5344  			t.Errorf("unexpected Read result: %v, %v", n, err)
  5345  		}
  5346  		handlerReadReturned <- true
  5347  	}))
  5348  	defer cst.close()
  5349  
  5350  	const timeout = 50 * time.Millisecond
  5351  	cst.c.Timeout = timeout
  5352  
  5353  	_, err := cst.c.Get(cst.ts.URL)
  5354  	if err == nil {
  5355  		t.Fatal("unexpected Get succeess")
  5356  	}
  5357  
  5358  	select {
  5359  	case c := <-inHandler:
  5360  		select {
  5361  		case <-handlerReadReturned:
  5362  			// Success.
  5363  			return
  5364  		case <-time.After(5 * time.Second):
  5365  			t.Error("Handler's conn.Read seems to be stuck in Read")
  5366  			c.Close() // close it to unblock Handler
  5367  		}
  5368  	case <-time.After(timeout * 10):
  5369  		// If we didn't get into the Handler in 50ms, that probably means
  5370  		// the builder was just slow and the Get failed in that time
  5371  		// but never made it to the server. That's fine. We'll usually
  5372  		// test the part above on faster machines.
  5373  		t.Skip("skipping test on slow builder")
  5374  	}
  5375  }
  5376  
  5377  // Issue 23399: verify that if a client request times out, the Transport's
  5378  // conn is closed so that it's not reused.
  5379  //
  5380  // This is the test variant that has the server send response headers
  5381  // first, and time out during the write of the response body.
  5382  func TestClientTimeoutKillsConn_AfterHeaders(t *testing.T) {
  5383  	setParallel(t)
  5384  	defer afterTest(t)
  5385  	inHandler := make(chan net.Conn, 1)
  5386  	handlerResult := make(chan error, 1)
  5387  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5388  		w.Header().Set("Content-Length", "100")
  5389  		w.(Flusher).Flush()
  5390  		conn, _, err := w.(Hijacker).Hijack()
  5391  		if err != nil {
  5392  			t.Error(err)
  5393  			return
  5394  		}
  5395  		conn.Write([]byte("foo"))
  5396  		inHandler <- conn
  5397  		n, err := conn.Read([]byte{0})
  5398  		// The error should be io.EOF or "read tcp
  5399  		// 127.0.0.1:35827->127.0.0.1:40290: read: connection
  5400  		// reset by peer" depending on timing. Really we just
  5401  		// care that it returns at all. But if it returns with
  5402  		// data, that's weird.
  5403  		if n != 0 || err == nil {
  5404  			handlerResult <- fmt.Errorf("unexpected Read result: %v, %v", n, err)
  5405  			return
  5406  		}
  5407  		handlerResult <- nil
  5408  	}))
  5409  	defer cst.close()
  5410  
  5411  	// Set Timeout to something very long but non-zero to exercise
  5412  	// the codepaths that check for it. But rather than wait for it to fire
  5413  	// (which would make the test slow), we send on the req.Cancel channel instead,
  5414  	// which happens to exercise the same code paths.
  5415  	cst.c.Timeout = time.Minute // just to be non-zero, not to hit it.
  5416  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  5417  	cancel := make(chan struct{})
  5418  	req.Cancel = cancel
  5419  
  5420  	res, err := cst.c.Do(req)
  5421  	if err != nil {
  5422  		select {
  5423  		case <-inHandler:
  5424  			t.Fatalf("Get error: %v", err)
  5425  		default:
  5426  			// Failed before entering handler. Ignore result.
  5427  			t.Skip("skipping test on slow builder")
  5428  		}
  5429  	}
  5430  
  5431  	close(cancel)
  5432  	got, err := ioutil.ReadAll(res.Body)
  5433  	if err == nil {
  5434  		t.Fatalf("unexpected success; read %q, nil", got)
  5435  	}
  5436  
  5437  	select {
  5438  	case c := <-inHandler:
  5439  		select {
  5440  		case err := <-handlerResult:
  5441  			if err != nil {
  5442  				t.Errorf("handler: %v", err)
  5443  			}
  5444  			return
  5445  		case <-time.After(5 * time.Second):
  5446  			t.Error("Handler's conn.Read seems to be stuck in Read")
  5447  			c.Close() // close it to unblock Handler
  5448  		}
  5449  	case <-time.After(5 * time.Second):
  5450  		t.Fatal("timeout")
  5451  	}
  5452  }
  5453  
  5454  func TestTransportResponseBodyWritableOnProtocolSwitch(t *testing.T) {
  5455  	setParallel(t)
  5456  	defer afterTest(t)
  5457  	done := make(chan struct{})
  5458  	defer close(done)
  5459  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5460  		conn, _, err := w.(Hijacker).Hijack()
  5461  		if err != nil {
  5462  			t.Error(err)
  5463  			return
  5464  		}
  5465  		defer conn.Close()
  5466  		io.WriteString(conn, "HTTP/1.1 101 Switching Protocols Hi\r\nConnection: upgRADe\r\nUpgrade: foo\r\n\r\nSome buffered data\n")
  5467  		bs := bufio.NewScanner(conn)
  5468  		bs.Scan()
  5469  		fmt.Fprintf(conn, "%s\n", strings.ToUpper(bs.Text()))
  5470  		<-done
  5471  	}))
  5472  	defer cst.close()
  5473  
  5474  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  5475  	req.Header.Set("Upgrade", "foo")
  5476  	req.Header.Set("Connection", "upgrade")
  5477  	res, err := cst.c.Do(req)
  5478  	if err != nil {
  5479  		t.Fatal(err)
  5480  	}
  5481  	if res.StatusCode != 101 {
  5482  		t.Fatalf("expected 101 switching protocols; got %v, %v", res.Status, res.Header)
  5483  	}
  5484  	rwc, ok := res.Body.(io.ReadWriteCloser)
  5485  	if !ok {
  5486  		t.Fatalf("expected a ReadWriteCloser; got a %T", res.Body)
  5487  	}
  5488  	defer rwc.Close()
  5489  	bs := bufio.NewScanner(rwc)
  5490  	if !bs.Scan() {
  5491  		t.Fatalf("expected readable input")
  5492  	}
  5493  	if got, want := bs.Text(), "Some buffered data"; got != want {
  5494  		t.Errorf("read %q; want %q", got, want)
  5495  	}
  5496  	io.WriteString(rwc, "echo\n")
  5497  	if !bs.Scan() {
  5498  		t.Fatalf("expected another line")
  5499  	}
  5500  	if got, want := bs.Text(), "ECHO"; got != want {
  5501  		t.Errorf("read %q; want %q", got, want)
  5502  	}
  5503  }
  5504  
  5505  func TestTransportCONNECTBidi(t *testing.T) {
  5506  	defer afterTest(t)
  5507  	const target = "backend:443"
  5508  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5509  		if r.Method != "CONNECT" {
  5510  			t.Errorf("unexpected method %q", r.Method)
  5511  			w.WriteHeader(500)
  5512  			return
  5513  		}
  5514  		if r.RequestURI != target {
  5515  			t.Errorf("unexpected CONNECT target %q", r.RequestURI)
  5516  			w.WriteHeader(500)
  5517  			return
  5518  		}
  5519  		nc, brw, err := w.(Hijacker).Hijack()
  5520  		if err != nil {
  5521  			t.Error(err)
  5522  			return
  5523  		}
  5524  		defer nc.Close()
  5525  		nc.Write([]byte("HTTP/1.1 200 OK\r\n\r\n"))
  5526  		// Switch to a little protocol that capitalize its input lines:
  5527  		for {
  5528  			line, err := brw.ReadString('\n')
  5529  			if err != nil {
  5530  				if err != io.EOF {
  5531  					t.Error(err)
  5532  				}
  5533  				return
  5534  			}
  5535  			io.WriteString(brw, strings.ToUpper(line))
  5536  			brw.Flush()
  5537  		}
  5538  	}))
  5539  	defer cst.close()
  5540  	pr, pw := io.Pipe()
  5541  	defer pw.Close()
  5542  	req, err := NewRequest("CONNECT", cst.ts.URL, pr)
  5543  	if err != nil {
  5544  		t.Fatal(err)
  5545  	}
  5546  	req.URL.Opaque = target
  5547  	res, err := cst.c.Do(req)
  5548  	if err != nil {
  5549  		t.Fatal(err)
  5550  	}
  5551  	defer res.Body.Close()
  5552  	if res.StatusCode != 200 {
  5553  		t.Fatalf("status code = %d; want 200", res.StatusCode)
  5554  	}
  5555  	br := bufio.NewReader(res.Body)
  5556  	for _, str := range []string{"foo", "bar", "baz"} {
  5557  		fmt.Fprintf(pw, "%s\n", str)
  5558  		got, err := br.ReadString('\n')
  5559  		if err != nil {
  5560  			t.Fatal(err)
  5561  		}
  5562  		got = strings.TrimSpace(got)
  5563  		want := strings.ToUpper(str)
  5564  		if got != want {
  5565  			t.Fatalf("got %q; want %q", got, want)
  5566  		}
  5567  	}
  5568  }
  5569  
  5570  func TestTransportRequestReplayable(t *testing.T) {
  5571  	someBody := ioutil.NopCloser(strings.NewReader(""))
  5572  	tests := []struct {
  5573  		name string
  5574  		req  *Request
  5575  		want bool
  5576  	}{
  5577  		{
  5578  			name: "GET",
  5579  			req:  &Request{Method: "GET"},
  5580  			want: true,
  5581  		},
  5582  		{
  5583  			name: "GET_http.NoBody",
  5584  			req:  &Request{Method: "GET", Body: NoBody},
  5585  			want: true,
  5586  		},
  5587  		{
  5588  			name: "GET_body",
  5589  			req:  &Request{Method: "GET", Body: someBody},
  5590  			want: false,
  5591  		},
  5592  		{
  5593  			name: "POST",
  5594  			req:  &Request{Method: "POST"},
  5595  			want: false,
  5596  		},
  5597  		{
  5598  			name: "POST_idempotency-key",
  5599  			req:  &Request{Method: "POST", Header: Header{"Idempotency-Key": {"x"}}},
  5600  			want: true,
  5601  		},
  5602  		{
  5603  			name: "POST_x-idempotency-key",
  5604  			req:  &Request{Method: "POST", Header: Header{"X-Idempotency-Key": {"x"}}},
  5605  			want: true,
  5606  		},
  5607  		{
  5608  			name: "POST_body",
  5609  			req:  &Request{Method: "POST", Header: Header{"Idempotency-Key": {"x"}}, Body: someBody},
  5610  			want: false,
  5611  		},
  5612  	}
  5613  	for _, tt := range tests {
  5614  		t.Run(tt.name, func(t *testing.T) {
  5615  			got := tt.req.ExportIsReplayable()
  5616  			if got != tt.want {
  5617  				t.Errorf("replyable = %v; want %v", got, tt.want)
  5618  			}
  5619  		})
  5620  	}
  5621  }
  5622  
  5623  // testMockTCPConn is a mock TCP connection used to test that
  5624  // ReadFrom is called when sending the request body.
  5625  type testMockTCPConn struct {
  5626  	*net.TCPConn
  5627  
  5628  	ReadFromCalled bool
  5629  }
  5630  
  5631  func (c *testMockTCPConn) ReadFrom(r io.Reader) (int64, error) {
  5632  	c.ReadFromCalled = true
  5633  	return c.TCPConn.ReadFrom(r)
  5634  }
  5635  
  5636  func TestTransportRequestWriteRoundTrip(t *testing.T) {
  5637  	nBytes := int64(1 << 10)
  5638  	newFileFunc := func() (r io.Reader, done func(), err error) {
  5639  		f, err := ioutil.TempFile("", "net-http-newfilefunc")
  5640  		if err != nil {
  5641  			return nil, nil, err
  5642  		}
  5643  
  5644  		// Write some bytes to the file to enable reading.
  5645  		if _, err := io.CopyN(f, rand.Reader, nBytes); err != nil {
  5646  			return nil, nil, fmt.Errorf("failed to write data to file: %v", err)
  5647  		}
  5648  		if _, err := f.Seek(0, 0); err != nil {
  5649  			return nil, nil, fmt.Errorf("failed to seek to front: %v", err)
  5650  		}
  5651  
  5652  		done = func() {
  5653  			f.Close()
  5654  			os.Remove(f.Name())
  5655  		}
  5656  
  5657  		return f, done, nil
  5658  	}
  5659  
  5660  	newBufferFunc := func() (io.Reader, func(), error) {
  5661  		return bytes.NewBuffer(make([]byte, nBytes)), func() {}, nil
  5662  	}
  5663  
  5664  	cases := []struct {
  5665  		name             string
  5666  		readerFunc       func() (io.Reader, func(), error)
  5667  		contentLength    int64
  5668  		expectedReadFrom bool
  5669  	}{
  5670  		{
  5671  			name:             "file, length",
  5672  			readerFunc:       newFileFunc,
  5673  			contentLength:    nBytes,
  5674  			expectedReadFrom: true,
  5675  		},
  5676  		{
  5677  			name:       "file, no length",
  5678  			readerFunc: newFileFunc,
  5679  		},
  5680  		{
  5681  			name:          "file, negative length",
  5682  			readerFunc:    newFileFunc,
  5683  			contentLength: -1,
  5684  		},
  5685  		{
  5686  			name:          "buffer",
  5687  			contentLength: nBytes,
  5688  			readerFunc:    newBufferFunc,
  5689  		},
  5690  		{
  5691  			name:       "buffer, no length",
  5692  			readerFunc: newBufferFunc,
  5693  		},
  5694  		{
  5695  			name:          "buffer, length -1",
  5696  			contentLength: -1,
  5697  			readerFunc:    newBufferFunc,
  5698  		},
  5699  	}
  5700  
  5701  	for _, tc := range cases {
  5702  		t.Run(tc.name, func(t *testing.T) {
  5703  			r, cleanup, err := tc.readerFunc()
  5704  			if err != nil {
  5705  				t.Fatal(err)
  5706  			}
  5707  			defer cleanup()
  5708  
  5709  			tConn := &testMockTCPConn{}
  5710  			trFunc := func(tr *Transport) {
  5711  				tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
  5712  					var d net.Dialer
  5713  					conn, err := d.DialContext(ctx, network, addr)
  5714  					if err != nil {
  5715  						return nil, err
  5716  					}
  5717  
  5718  					tcpConn, ok := conn.(*net.TCPConn)
  5719  					if !ok {
  5720  						return nil, fmt.Errorf("%s/%s does not provide a *net.TCPConn", network, addr)
  5721  					}
  5722  
  5723  					tConn.TCPConn = tcpConn
  5724  					return tConn, nil
  5725  				}
  5726  			}
  5727  
  5728  			cst := newClientServerTest(
  5729  				t,
  5730  				h1Mode,
  5731  				HandlerFunc(func(w ResponseWriter, r *Request) {
  5732  					io.Copy(ioutil.Discard, r.Body)
  5733  					r.Body.Close()
  5734  					w.WriteHeader(200)
  5735  				}),
  5736  				trFunc,
  5737  			)
  5738  			defer cst.close()
  5739  
  5740  			req, err := NewRequest("PUT", cst.ts.URL, r)
  5741  			if err != nil {
  5742  				t.Fatal(err)
  5743  			}
  5744  			req.ContentLength = tc.contentLength
  5745  			req.Header.Set("Content-Type", "application/octet-stream")
  5746  			resp, err := cst.c.Do(req)
  5747  			if err != nil {
  5748  				t.Fatal(err)
  5749  			}
  5750  			defer resp.Body.Close()
  5751  			if resp.StatusCode != 200 {
  5752  				t.Fatalf("status code = %d; want 200", resp.StatusCode)
  5753  			}
  5754  
  5755  			if !tConn.ReadFromCalled && tc.expectedReadFrom {
  5756  				t.Fatalf("did not call ReadFrom")
  5757  			}
  5758  
  5759  			if tConn.ReadFromCalled && !tc.expectedReadFrom {
  5760  				t.Fatalf("ReadFrom was unexpectedly invoked")
  5761  			}
  5762  		})
  5763  	}
  5764  }
  5765  
  5766  func TestTransportClone(t *testing.T) {
  5767  	tr := &Transport{
  5768  		Proxy:                  func(*Request) (*url.URL, error) { panic("") },
  5769  		DialContext:            func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") },
  5770  		Dial:                   func(network, addr string) (net.Conn, error) { panic("") },
  5771  		DialTLS:                func(network, addr string) (net.Conn, error) { panic("") },
  5772  		DialTLSContext:         func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") },
  5773  		TLSClientConfig:        new(tls.Config),
  5774  		TLSHandshakeTimeout:    time.Second,
  5775  		DisableKeepAlives:      true,
  5776  		DisableCompression:     true,
  5777  		MaxIdleConns:           1,
  5778  		MaxIdleConnsPerHost:    1,
  5779  		MaxConnsPerHost:        1,
  5780  		IdleConnTimeout:        time.Second,
  5781  		ResponseHeaderTimeout:  time.Second,
  5782  		ExpectContinueTimeout:  time.Second,
  5783  		ProxyConnectHeader:     Header{},
  5784  		MaxResponseHeaderBytes: 1,
  5785  		ForceAttemptHTTP2:      true,
  5786  		TLSNextProto: map[string]func(authority string, c *tls.Conn) RoundTripper{
  5787  			"foo": func(authority string, c *tls.Conn) RoundTripper { panic("") },
  5788  		},
  5789  		ReadBufferSize:  1,
  5790  		WriteBufferSize: 1,
  5791  	}
  5792  	tr2 := tr.Clone()
  5793  	rv := reflect.ValueOf(tr2).Elem()
  5794  	rt := rv.Type()
  5795  	for i := 0; i < rt.NumField(); i++ {
  5796  		sf := rt.Field(i)
  5797  		if !token.IsExported(sf.Name) {
  5798  			continue
  5799  		}
  5800  		if rv.Field(i).IsZero() {
  5801  			t.Errorf("cloned field t2.%s is zero", sf.Name)
  5802  		}
  5803  	}
  5804  
  5805  	if _, ok := tr2.TLSNextProto["foo"]; !ok {
  5806  		t.Errorf("cloned Transport lacked TLSNextProto 'foo' key")
  5807  	}
  5808  
  5809  	// But test that a nil TLSNextProto is kept nil:
  5810  	tr = new(Transport)
  5811  	tr2 = tr.Clone()
  5812  	if tr2.TLSNextProto != nil {
  5813  		t.Errorf("Transport.TLSNextProto unexpected non-nil")
  5814  	}
  5815  }
  5816  
  5817  func TestIs408(t *testing.T) {
  5818  	tests := []struct {
  5819  		in   string
  5820  		want bool
  5821  	}{
  5822  		{"HTTP/1.0 408", true},
  5823  		{"HTTP/1.1 408", true},
  5824  		{"HTTP/1.8 408", true},
  5825  		{"HTTP/2.0 408", false}, // maybe h2c would do this? but false for now.
  5826  		{"HTTP/1.1 408 ", true},
  5827  		{"HTTP/1.1 40", false},
  5828  		{"http/1.0 408", false},
  5829  		{"HTTP/1-1 408", false},
  5830  	}
  5831  	for _, tt := range tests {
  5832  		if got := Export_is408Message([]byte(tt.in)); got != tt.want {
  5833  			t.Errorf("is408Message(%q) = %v; want %v", tt.in, got, tt.want)
  5834  		}
  5835  	}
  5836  }
  5837  
  5838  func TestTransportIgnores408(t *testing.T) {
  5839  	// Not parallel. Relies on mutating the log package's global Output.
  5840  	defer log.SetOutput(log.Writer())
  5841  
  5842  	var logout bytes.Buffer
  5843  	log.SetOutput(&logout)
  5844  
  5845  	defer afterTest(t)
  5846  	const target = "backend:443"
  5847  
  5848  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5849  		nc, _, err := w.(Hijacker).Hijack()
  5850  		if err != nil {
  5851  			t.Error(err)
  5852  			return
  5853  		}
  5854  		defer nc.Close()
  5855  		nc.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok"))
  5856  		nc.Write([]byte("HTTP/1.1 408 bye\r\n")) // changing 408 to 409 makes test fail
  5857  	}))
  5858  	defer cst.close()
  5859  	req, err := NewRequest("GET", cst.ts.URL, nil)
  5860  	if err != nil {
  5861  		t.Fatal(err)
  5862  	}
  5863  	res, err := cst.c.Do(req)
  5864  	if err != nil {
  5865  		t.Fatal(err)
  5866  	}
  5867  	slurp, err := ioutil.ReadAll(res.Body)
  5868  	if err != nil {
  5869  		t.Fatal(err)
  5870  	}
  5871  	if err != nil {
  5872  		t.Fatal(err)
  5873  	}
  5874  	if string(slurp) != "ok" {
  5875  		t.Fatalf("got %q; want ok", slurp)
  5876  	}
  5877  
  5878  	t0 := time.Now()
  5879  	for i := 0; i < 50; i++ {
  5880  		time.Sleep(time.Duration(i) * 5 * time.Millisecond)
  5881  		if cst.tr.IdleConnKeyCountForTesting() == 0 {
  5882  			if got := logout.String(); got != "" {
  5883  				t.Fatalf("expected no log output; got: %s", got)
  5884  			}
  5885  			return
  5886  		}
  5887  	}
  5888  	t.Fatalf("timeout after %v waiting for Transport connections to die off", time.Since(t0))
  5889  }
  5890  
  5891  func TestInvalidHeaderResponse(t *testing.T) {
  5892  	setParallel(t)
  5893  	defer afterTest(t)
  5894  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5895  		conn, buf, _ := w.(Hijacker).Hijack()
  5896  		buf.Write([]byte("HTTP/1.1 200 OK\r\n" +
  5897  			"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
  5898  			"Content-Type: text/html; charset=utf-8\r\n" +
  5899  			"Content-Length: 0\r\n" +
  5900  			"Foo : bar\r\n\r\n"))
  5901  		buf.Flush()
  5902  		conn.Close()
  5903  	}))
  5904  	defer cst.close()
  5905  	res, err := cst.c.Get(cst.ts.URL)
  5906  	if err != nil {
  5907  		t.Fatal(err)
  5908  	}
  5909  	defer res.Body.Close()
  5910  	if v := res.Header.Get("Foo"); v != "" {
  5911  		t.Errorf(`unexpected "Foo" header: %q`, v)
  5912  	}
  5913  	if v := res.Header.Get("Foo "); v != "bar" {
  5914  		t.Errorf(`bad "Foo " header value: %q, want %q`, v, "bar")
  5915  	}
  5916  }
  5917  
  5918  type bodyCloser bool
  5919  
  5920  func (bc *bodyCloser) Close() error {
  5921  	*bc = true
  5922  	return nil
  5923  }
  5924  func (bc *bodyCloser) Read(b []byte) (n int, err error) {
  5925  	return 0, io.EOF
  5926  }
  5927  
  5928  // Issue 35015: ensure that Transport closes the body on any error
  5929  // with an invalid request, as promised by Client.Do docs.
  5930  func TestTransportClosesBodyOnInvalidRequests(t *testing.T) {
  5931  	cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  5932  		t.Errorf("Should not have been invoked")
  5933  	}))
  5934  	defer cst.Close()
  5935  
  5936  	u, _ := url.Parse(cst.URL)
  5937  
  5938  	tests := []struct {
  5939  		name    string
  5940  		req     *Request
  5941  		wantErr string
  5942  	}{
  5943  		{
  5944  			name: "invalid method",
  5945  			req: &Request{
  5946  				Method: " ",
  5947  				URL:    u,
  5948  			},
  5949  			wantErr: "invalid method",
  5950  		},
  5951  		{
  5952  			name: "nil URL",
  5953  			req: &Request{
  5954  				Method: "GET",
  5955  			},
  5956  			wantErr: "nil Request.URL",
  5957  		},
  5958  		{
  5959  			name: "invalid header key",
  5960  			req: &Request{
  5961  				Method: "GET",
  5962  				Header: Header{"💡": {"emoji"}},
  5963  				URL:    u,
  5964  			},
  5965  			wantErr: "invalid header field name",
  5966  		},
  5967  		{
  5968  			name: "invalid header value",
  5969  			req: &Request{
  5970  				Method: "POST",
  5971  				Header: Header{"key": {"\x19"}},
  5972  				URL:    u,
  5973  			},
  5974  			wantErr: "invalid header field value",
  5975  		},
  5976  		{
  5977  			name: "non HTTP(s) scheme",
  5978  			req: &Request{
  5979  				Method: "POST",
  5980  				URL:    &url.URL{Scheme: "faux"},
  5981  			},
  5982  			wantErr: "unsupported protocol scheme",
  5983  		},
  5984  		{
  5985  			name: "no Host in URL",
  5986  			req: &Request{
  5987  				Method: "POST",
  5988  				URL:    &url.URL{Scheme: "http"},
  5989  			},
  5990  			wantErr: "no Host",
  5991  		},
  5992  	}
  5993  
  5994  	for _, tt := range tests {
  5995  		t.Run(tt.name, func(t *testing.T) {
  5996  			var bc bodyCloser
  5997  			req := tt.req
  5998  			req.Body = &bc
  5999  			_, err := DefaultClient.Do(tt.req)
  6000  			if err == nil {
  6001  				t.Fatal("Expected an error")
  6002  			}
  6003  			if !bc {
  6004  				t.Fatal("Expected body to have been closed")
  6005  			}
  6006  			if g, w := err.Error(), tt.wantErr; !strings.Contains(g, w) {
  6007  				t.Fatalf("Error mismatch\n\t%q\ndoes not contain\n\t%q", g, w)
  6008  			}
  6009  		})
  6010  	}
  6011  }
  6012  
  6013  // breakableConn is a net.Conn wrapper with a Write method
  6014  // that will fail when its brokenState is true.
  6015  type breakableConn struct {
  6016  	net.Conn
  6017  	*brokenState
  6018  }
  6019  
  6020  type brokenState struct {
  6021  	sync.Mutex
  6022  	broken bool
  6023  }
  6024  
  6025  func (w *breakableConn) Write(b []byte) (n int, err error) {
  6026  	w.Lock()
  6027  	defer w.Unlock()
  6028  	if w.broken {
  6029  		return 0, errors.New("some write error")
  6030  	}
  6031  	return w.Conn.Write(b)
  6032  }
  6033  
  6034  // Issue 34978: don't cache a broken HTTP/2 connection
  6035  func TestDontCacheBrokenHTTP2Conn(t *testing.T) {
  6036  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), optQuietLog)
  6037  	defer cst.close()
  6038  
  6039  	var brokenState brokenState
  6040  
  6041  	const numReqs = 5
  6042  	var numDials, gotConns uint32 // atomic
  6043  
  6044  	cst.tr.Dial = func(netw, addr string) (net.Conn, error) {
  6045  		atomic.AddUint32(&numDials, 1)
  6046  		c, err := net.Dial(netw, addr)
  6047  		if err != nil {
  6048  			t.Errorf("unexpected Dial error: %v", err)
  6049  			return nil, err
  6050  		}
  6051  		return &breakableConn{c, &brokenState}, err
  6052  	}
  6053  
  6054  	for i := 1; i <= numReqs; i++ {
  6055  		brokenState.Lock()
  6056  		brokenState.broken = false
  6057  		brokenState.Unlock()
  6058  
  6059  		// doBreak controls whether we break the TCP connection after the TLS
  6060  		// handshake (before the HTTP/2 handshake). We test a few failures
  6061  		// in a row followed by a final success.
  6062  		doBreak := i != numReqs
  6063  
  6064  		ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  6065  			GotConn: func(info httptrace.GotConnInfo) {
  6066  				t.Logf("got conn: %v, reused=%v, wasIdle=%v, idleTime=%v", info.Conn.LocalAddr(), info.Reused, info.WasIdle, info.IdleTime)
  6067  				atomic.AddUint32(&gotConns, 1)
  6068  			},
  6069  			TLSHandshakeDone: func(cfg tls.ConnectionState, err error) {
  6070  				brokenState.Lock()
  6071  				defer brokenState.Unlock()
  6072  				if doBreak {
  6073  					brokenState.broken = true
  6074  				}
  6075  			},
  6076  		})
  6077  		req, err := NewRequestWithContext(ctx, "GET", cst.ts.URL, nil)
  6078  		if err != nil {
  6079  			t.Fatal(err)
  6080  		}
  6081  		_, err = cst.c.Do(req)
  6082  		if doBreak != (err != nil) {
  6083  			t.Errorf("for iteration %d, doBreak=%v; unexpected error %v", i, doBreak, err)
  6084  		}
  6085  	}
  6086  	if got, want := atomic.LoadUint32(&gotConns), 1; int(got) != want {
  6087  		t.Errorf("GotConn calls = %v; want %v", got, want)
  6088  	}
  6089  	if got, want := atomic.LoadUint32(&numDials), numReqs; int(got) != want {
  6090  		t.Errorf("Dials = %v; want %v", got, want)
  6091  	}
  6092  }
  6093  
  6094  // Issue 34941
  6095  // When the client has too many concurrent requests on a single connection,
  6096  // http.http2noCachedConnError is reported on multiple requests. There should
  6097  // only be one decrement regardless of the number of failures.
  6098  func TestTransportDecrementConnWhenIdleConnRemoved(t *testing.T) {
  6099  	defer afterTest(t)
  6100  	CondSkipHTTP2(t)
  6101  
  6102  	h := HandlerFunc(func(w ResponseWriter, r *Request) {
  6103  		_, err := w.Write([]byte("foo"))
  6104  		if err != nil {
  6105  			t.Fatalf("Write: %v", err)
  6106  		}
  6107  	})
  6108  
  6109  	ts := httptest.NewUnstartedServer(h)
  6110  	ts.EnableHTTP2 = true
  6111  	ts.StartTLS()
  6112  	defer ts.Close()
  6113  
  6114  	c := ts.Client()
  6115  	tr := c.Transport.(*Transport)
  6116  	tr.MaxConnsPerHost = 1
  6117  	if err := ExportHttp2ConfigureTransport(tr); err != nil {
  6118  		t.Fatalf("ExportHttp2ConfigureTransport: %v", err)
  6119  	}
  6120  
  6121  	errCh := make(chan error, 300)
  6122  	doReq := func() {
  6123  		resp, err := c.Get(ts.URL)
  6124  		if err != nil {
  6125  			errCh <- fmt.Errorf("request failed: %v", err)
  6126  			return
  6127  		}
  6128  		defer resp.Body.Close()
  6129  		_, err = ioutil.ReadAll(resp.Body)
  6130  		if err != nil {
  6131  			errCh <- fmt.Errorf("read body failed: %v", err)
  6132  		}
  6133  	}
  6134  
  6135  	var wg sync.WaitGroup
  6136  	for i := 0; i < 300; i++ {
  6137  		wg.Add(1)
  6138  		go func() {
  6139  			defer wg.Done()
  6140  			doReq()
  6141  		}()
  6142  	}
  6143  	wg.Wait()
  6144  	close(errCh)
  6145  
  6146  	for err := range errCh {
  6147  		t.Errorf("error occurred: %v", err)
  6148  	}
  6149  }
  6150  
  6151  // Issue 36820
  6152  // Test that we use the older backward compatible cancellation protocol
  6153  // when a RoundTripper is registered via RegisterProtocol.
  6154  func TestAltProtoCancellation(t *testing.T) {
  6155  	defer afterTest(t)
  6156  	tr := &Transport{}
  6157  	c := &Client{
  6158  		Transport: tr,
  6159  		Timeout:   time.Millisecond,
  6160  	}
  6161  	tr.RegisterProtocol("timeout", timeoutProto{})
  6162  	_, err := c.Get("timeout://bar.com/path")
  6163  	if err == nil {
  6164  		t.Error("request unexpectedly succeeded")
  6165  	} else if !strings.Contains(err.Error(), timeoutProtoErr.Error()) {
  6166  		t.Errorf("got error %q, does not contain expected string %q", err, timeoutProtoErr)
  6167  	}
  6168  }
  6169  
  6170  var timeoutProtoErr = errors.New("canceled as expected")
  6171  
  6172  type timeoutProto struct{}
  6173  
  6174  func (timeoutProto) RoundTrip(req *Request) (*Response, error) {
  6175  	select {
  6176  	case <-req.Cancel:
  6177  		return nil, timeoutProtoErr
  6178  	case <-time.After(5 * time.Second):
  6179  		return nil, errors.New("request was not canceled")
  6180  	}
  6181  }