Source file src/net/http/transport_test.go

Documentation: net/http

     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  	defer afterTest(t)
  1882  
  1883  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1884  		runtime.Gosched()
  1885  		w.WriteHeader(StatusOK)
  1886  	}))
  1887  	defer ts.Close()
  1888  
  1889  	c := ts.Client()
  1890  	c.Transport.(*Transport).MaxConnsPerHost = 1
  1891  
  1892  	ctx := context.Background()
  1893  	body := []byte("Hello")
  1894  	doPosts := func(cc *contextCounter) {
  1895  		var wg sync.WaitGroup
  1896  		for n := 64; n > 0; n-- {
  1897  			wg.Add(1)
  1898  			go func() {
  1899  				defer wg.Done()
  1900  
  1901  				ctx := cc.Track(ctx)
  1902  				req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
  1903  				if err != nil {
  1904  					t.Error(err)
  1905  				}
  1906  
  1907  				_, err = c.Do(req.WithContext(ctx))
  1908  				if err != nil {
  1909  					t.Errorf("Do failed with error: %v", err)
  1910  				}
  1911  			}()
  1912  		}
  1913  		wg.Wait()
  1914  	}
  1915  
  1916  	var initialCC contextCounter
  1917  	doPosts(&initialCC)
  1918  
  1919  	// flushCC exists only to put pressure on the GC to finalize the initialCC
  1920  	// contexts: the flushCC allocations should eventually displace the initialCC
  1921  	// allocations.
  1922  	var flushCC contextCounter
  1923  	for i := 0; ; i++ {
  1924  		live := initialCC.Read()
  1925  		if live == 0 {
  1926  			break
  1927  		}
  1928  		if i >= 100 {
  1929  			t.Fatalf("%d Contexts still not finalized after %d GC cycles.", live, i)
  1930  		}
  1931  		doPosts(&flushCC)
  1932  		runtime.GC()
  1933  	}
  1934  }
  1935  
  1936  // This used to crash; https://golang.org/issue/3266
  1937  func TestTransportIdleConnCrash(t *testing.T) {
  1938  	defer afterTest(t)
  1939  	var tr *Transport
  1940  
  1941  	unblockCh := make(chan bool, 1)
  1942  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1943  		<-unblockCh
  1944  		tr.CloseIdleConnections()
  1945  	}))
  1946  	defer ts.Close()
  1947  	c := ts.Client()
  1948  	tr = c.Transport.(*Transport)
  1949  
  1950  	didreq := make(chan bool)
  1951  	go func() {
  1952  		res, err := c.Get(ts.URL)
  1953  		if err != nil {
  1954  			t.Error(err)
  1955  		} else {
  1956  			res.Body.Close() // returns idle conn
  1957  		}
  1958  		didreq <- true
  1959  	}()
  1960  	unblockCh <- true
  1961  	<-didreq
  1962  }
  1963  
  1964  // Test that the transport doesn't close the TCP connection early,
  1965  // before the response body has been read. This was a regression
  1966  // which sadly lacked a triggering test. The large response body made
  1967  // the old race easier to trigger.
  1968  func TestIssue3644(t *testing.T) {
  1969  	defer afterTest(t)
  1970  	const numFoos = 5000
  1971  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1972  		w.Header().Set("Connection", "close")
  1973  		for i := 0; i < numFoos; i++ {
  1974  			w.Write([]byte("foo "))
  1975  		}
  1976  	}))
  1977  	defer ts.Close()
  1978  	c := ts.Client()
  1979  	res, err := c.Get(ts.URL)
  1980  	if err != nil {
  1981  		t.Fatal(err)
  1982  	}
  1983  	defer res.Body.Close()
  1984  	bs, err := ioutil.ReadAll(res.Body)
  1985  	if err != nil {
  1986  		t.Fatal(err)
  1987  	}
  1988  	if len(bs) != numFoos*len("foo ") {
  1989  		t.Errorf("unexpected response length")
  1990  	}
  1991  }
  1992  
  1993  // Test that a client receives a server's reply, even if the server doesn't read
  1994  // the entire request body.
  1995  func TestIssue3595(t *testing.T) {
  1996  	setParallel(t)
  1997  	defer afterTest(t)
  1998  	const deniedMsg = "sorry, denied."
  1999  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2000  		Error(w, deniedMsg, StatusUnauthorized)
  2001  	}))
  2002  	defer ts.Close()
  2003  	c := ts.Client()
  2004  	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
  2005  	if err != nil {
  2006  		t.Errorf("Post: %v", err)
  2007  		return
  2008  	}
  2009  	got, err := ioutil.ReadAll(res.Body)
  2010  	if err != nil {
  2011  		t.Fatalf("Body ReadAll: %v", err)
  2012  	}
  2013  	if !strings.Contains(string(got), deniedMsg) {
  2014  		t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
  2015  	}
  2016  }
  2017  
  2018  // From https://golang.org/issue/4454 ,
  2019  // "client fails to handle requests with no body and chunked encoding"
  2020  func TestChunkedNoContent(t *testing.T) {
  2021  	defer afterTest(t)
  2022  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2023  		w.WriteHeader(StatusNoContent)
  2024  	}))
  2025  	defer ts.Close()
  2026  
  2027  	c := ts.Client()
  2028  	for _, closeBody := range []bool{true, false} {
  2029  		const n = 4
  2030  		for i := 1; i <= n; i++ {
  2031  			res, err := c.Get(ts.URL)
  2032  			if err != nil {
  2033  				t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
  2034  			} else {
  2035  				if closeBody {
  2036  					res.Body.Close()
  2037  				}
  2038  			}
  2039  		}
  2040  	}
  2041  }
  2042  
  2043  func TestTransportConcurrency(t *testing.T) {
  2044  	// Not parallel: uses global test hooks.
  2045  	defer afterTest(t)
  2046  	maxProcs, numReqs := 16, 500
  2047  	if testing.Short() {
  2048  		maxProcs, numReqs = 4, 50
  2049  	}
  2050  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
  2051  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2052  		fmt.Fprintf(w, "%v", r.FormValue("echo"))
  2053  	}))
  2054  	defer ts.Close()
  2055  
  2056  	var wg sync.WaitGroup
  2057  	wg.Add(numReqs)
  2058  
  2059  	// Due to the Transport's "socket late binding" (see
  2060  	// idleConnCh in transport.go), the numReqs HTTP requests
  2061  	// below can finish with a dial still outstanding. To keep
  2062  	// the leak checker happy, keep track of pending dials and
  2063  	// wait for them to finish (and be closed or returned to the
  2064  	// idle pool) before we close idle connections.
  2065  	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  2066  	defer SetPendingDialHooks(nil, nil)
  2067  
  2068  	c := ts.Client()
  2069  	reqs := make(chan string)
  2070  	defer close(reqs)
  2071  
  2072  	for i := 0; i < maxProcs*2; i++ {
  2073  		go func() {
  2074  			for req := range reqs {
  2075  				res, err := c.Get(ts.URL + "/?echo=" + req)
  2076  				if err != nil {
  2077  					t.Errorf("error on req %s: %v", req, err)
  2078  					wg.Done()
  2079  					continue
  2080  				}
  2081  				all, err := ioutil.ReadAll(res.Body)
  2082  				if err != nil {
  2083  					t.Errorf("read error on req %s: %v", req, err)
  2084  					wg.Done()
  2085  					continue
  2086  				}
  2087  				if string(all) != req {
  2088  					t.Errorf("body of req %s = %q; want %q", req, all, req)
  2089  				}
  2090  				res.Body.Close()
  2091  				wg.Done()
  2092  			}
  2093  		}()
  2094  	}
  2095  	for i := 0; i < numReqs; i++ {
  2096  		reqs <- fmt.Sprintf("request-%d", i)
  2097  	}
  2098  	wg.Wait()
  2099  }
  2100  
  2101  func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
  2102  	setParallel(t)
  2103  	defer afterTest(t)
  2104  	const debug = false
  2105  	mux := NewServeMux()
  2106  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  2107  		io.Copy(w, neverEnding('a'))
  2108  	})
  2109  	ts := httptest.NewServer(mux)
  2110  	defer ts.Close()
  2111  	timeout := 100 * time.Millisecond
  2112  
  2113  	c := ts.Client()
  2114  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  2115  		conn, err := net.Dial(n, addr)
  2116  		if err != nil {
  2117  			return nil, err
  2118  		}
  2119  		conn.SetDeadline(time.Now().Add(timeout))
  2120  		if debug {
  2121  			conn = NewLoggingConn("client", conn)
  2122  		}
  2123  		return conn, nil
  2124  	}
  2125  
  2126  	getFailed := false
  2127  	nRuns := 5
  2128  	if testing.Short() {
  2129  		nRuns = 1
  2130  	}
  2131  	for i := 0; i < nRuns; i++ {
  2132  		if debug {
  2133  			println("run", i+1, "of", nRuns)
  2134  		}
  2135  		sres, err := c.Get(ts.URL + "/get")
  2136  		if err != nil {
  2137  			if !getFailed {
  2138  				// Make the timeout longer, once.
  2139  				getFailed = true
  2140  				t.Logf("increasing timeout")
  2141  				i--
  2142  				timeout *= 10
  2143  				continue
  2144  			}
  2145  			t.Errorf("Error issuing GET: %v", err)
  2146  			break
  2147  		}
  2148  		_, err = io.Copy(ioutil.Discard, sres.Body)
  2149  		if err == nil {
  2150  			t.Errorf("Unexpected successful copy")
  2151  			break
  2152  		}
  2153  	}
  2154  	if debug {
  2155  		println("tests complete; waiting for handlers to finish")
  2156  	}
  2157  }
  2158  
  2159  func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
  2160  	setParallel(t)
  2161  	defer afterTest(t)
  2162  	const debug = false
  2163  	mux := NewServeMux()
  2164  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  2165  		io.Copy(w, neverEnding('a'))
  2166  	})
  2167  	mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
  2168  		defer r.Body.Close()
  2169  		io.Copy(ioutil.Discard, r.Body)
  2170  	})
  2171  	ts := httptest.NewServer(mux)
  2172  	timeout := 100 * time.Millisecond
  2173  
  2174  	c := ts.Client()
  2175  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  2176  		conn, err := net.Dial(n, addr)
  2177  		if err != nil {
  2178  			return nil, err
  2179  		}
  2180  		conn.SetDeadline(time.Now().Add(timeout))
  2181  		if debug {
  2182  			conn = NewLoggingConn("client", conn)
  2183  		}
  2184  		return conn, nil
  2185  	}
  2186  
  2187  	getFailed := false
  2188  	nRuns := 5
  2189  	if testing.Short() {
  2190  		nRuns = 1
  2191  	}
  2192  	for i := 0; i < nRuns; i++ {
  2193  		if debug {
  2194  			println("run", i+1, "of", nRuns)
  2195  		}
  2196  		sres, err := c.Get(ts.URL + "/get")
  2197  		if err != nil {
  2198  			if !getFailed {
  2199  				// Make the timeout longer, once.
  2200  				getFailed = true
  2201  				t.Logf("increasing timeout")
  2202  				i--
  2203  				timeout *= 10
  2204  				continue
  2205  			}
  2206  			t.Errorf("Error issuing GET: %v", err)
  2207  			break
  2208  		}
  2209  		req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
  2210  		_, err = c.Do(req)
  2211  		if err == nil {
  2212  			sres.Body.Close()
  2213  			t.Errorf("Unexpected successful PUT")
  2214  			break
  2215  		}
  2216  		sres.Body.Close()
  2217  	}
  2218  	if debug {
  2219  		println("tests complete; waiting for handlers to finish")
  2220  	}
  2221  	ts.Close()
  2222  }
  2223  
  2224  func TestTransportResponseHeaderTimeout(t *testing.T) {
  2225  	setParallel(t)
  2226  	defer afterTest(t)
  2227  	if testing.Short() {
  2228  		t.Skip("skipping timeout test in -short mode")
  2229  	}
  2230  	inHandler := make(chan bool, 1)
  2231  	mux := NewServeMux()
  2232  	mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {
  2233  		inHandler <- true
  2234  	})
  2235  	mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
  2236  		inHandler <- true
  2237  		time.Sleep(2 * time.Second)
  2238  	})
  2239  	ts := httptest.NewServer(mux)
  2240  	defer ts.Close()
  2241  
  2242  	c := ts.Client()
  2243  	c.Transport.(*Transport).ResponseHeaderTimeout = 500 * time.Millisecond
  2244  
  2245  	tests := []struct {
  2246  		path    string
  2247  		want    int
  2248  		wantErr string
  2249  	}{
  2250  		{path: "/fast", want: 200},
  2251  		{path: "/slow", wantErr: "timeout awaiting response headers"},
  2252  		{path: "/fast", want: 200},
  2253  	}
  2254  	for i, tt := range tests {
  2255  		req, _ := NewRequest("GET", ts.URL+tt.path, nil)
  2256  		req = req.WithT(t)
  2257  		res, err := c.Do(req)
  2258  		select {
  2259  		case <-inHandler:
  2260  		case <-time.After(5 * time.Second):
  2261  			t.Errorf("never entered handler for test index %d, %s", i, tt.path)
  2262  			continue
  2263  		}
  2264  		if err != nil {
  2265  			uerr, ok := err.(*url.Error)
  2266  			if !ok {
  2267  				t.Errorf("error is not an url.Error; got: %#v", err)
  2268  				continue
  2269  			}
  2270  			nerr, ok := uerr.Err.(net.Error)
  2271  			if !ok {
  2272  				t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
  2273  				continue
  2274  			}
  2275  			if !nerr.Timeout() {
  2276  				t.Errorf("want timeout error; got: %q", nerr)
  2277  				continue
  2278  			}
  2279  			if strings.Contains(err.Error(), tt.wantErr) {
  2280  				continue
  2281  			}
  2282  			t.Errorf("%d. unexpected error: %v", i, err)
  2283  			continue
  2284  		}
  2285  		if tt.wantErr != "" {
  2286  			t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
  2287  			continue
  2288  		}
  2289  		if res.StatusCode != tt.want {
  2290  			t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
  2291  		}
  2292  	}
  2293  }
  2294  
  2295  func TestTransportCancelRequest(t *testing.T) {
  2296  	setParallel(t)
  2297  	defer afterTest(t)
  2298  	if testing.Short() {
  2299  		t.Skip("skipping test in -short mode")
  2300  	}
  2301  	unblockc := make(chan bool)
  2302  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2303  		fmt.Fprintf(w, "Hello")
  2304  		w.(Flusher).Flush() // send headers and some body
  2305  		<-unblockc
  2306  	}))
  2307  	defer ts.Close()
  2308  	defer close(unblockc)
  2309  
  2310  	c := ts.Client()
  2311  	tr := c.Transport.(*Transport)
  2312  
  2313  	req, _ := NewRequest("GET", ts.URL, nil)
  2314  	res, err := c.Do(req)
  2315  	if err != nil {
  2316  		t.Fatal(err)
  2317  	}
  2318  	go func() {
  2319  		time.Sleep(1 * time.Second)
  2320  		tr.CancelRequest(req)
  2321  	}()
  2322  	t0 := time.Now()
  2323  	body, err := ioutil.ReadAll(res.Body)
  2324  	d := time.Since(t0)
  2325  
  2326  	if err != ExportErrRequestCanceled {
  2327  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  2328  	}
  2329  	if string(body) != "Hello" {
  2330  		t.Errorf("Body = %q; want Hello", body)
  2331  	}
  2332  	if d < 500*time.Millisecond {
  2333  		t.Errorf("expected ~1 second delay; got %v", d)
  2334  	}
  2335  	// Verify no outstanding requests after readLoop/writeLoop
  2336  	// goroutines shut down.
  2337  	for tries := 5; tries > 0; tries-- {
  2338  		n := tr.NumPendingRequestsForTesting()
  2339  		if n == 0 {
  2340  			break
  2341  		}
  2342  		time.Sleep(100 * time.Millisecond)
  2343  		if tries == 1 {
  2344  			t.Errorf("pending requests = %d; want 0", n)
  2345  		}
  2346  	}
  2347  }
  2348  
  2349  func TestTransportCancelRequestInDial(t *testing.T) {
  2350  	defer afterTest(t)
  2351  	if testing.Short() {
  2352  		t.Skip("skipping test in -short mode")
  2353  	}
  2354  	var logbuf bytes.Buffer
  2355  	eventLog := log.New(&logbuf, "", 0)
  2356  
  2357  	unblockDial := make(chan bool)
  2358  	defer close(unblockDial)
  2359  
  2360  	inDial := make(chan bool)
  2361  	tr := &Transport{
  2362  		Dial: func(network, addr string) (net.Conn, error) {
  2363  			eventLog.Println("dial: blocking")
  2364  			inDial <- true
  2365  			<-unblockDial
  2366  			return nil, errors.New("nope")
  2367  		},
  2368  	}
  2369  	cl := &Client{Transport: tr}
  2370  	gotres := make(chan bool)
  2371  	req, _ := NewRequest("GET", "http://something.no-network.tld/", nil)
  2372  	go func() {
  2373  		_, err := cl.Do(req)
  2374  		eventLog.Printf("Get = %v", err)
  2375  		gotres <- true
  2376  	}()
  2377  
  2378  	select {
  2379  	case <-inDial:
  2380  	case <-time.After(5 * time.Second):
  2381  		t.Fatal("timeout; never saw blocking dial")
  2382  	}
  2383  
  2384  	eventLog.Printf("canceling")
  2385  	tr.CancelRequest(req)
  2386  	tr.CancelRequest(req) // used to panic on second call
  2387  
  2388  	select {
  2389  	case <-gotres:
  2390  	case <-time.After(5 * time.Second):
  2391  		panic("hang. events are: " + logbuf.String())
  2392  	}
  2393  
  2394  	got := logbuf.String()
  2395  	want := `dial: blocking
  2396  canceling
  2397  Get = Get "http://something.no-network.tld/": net/http: request canceled while waiting for connection
  2398  `
  2399  	if got != want {
  2400  		t.Errorf("Got events:\n%s\nWant:\n%s", got, want)
  2401  	}
  2402  }
  2403  
  2404  func TestCancelRequestWithChannel(t *testing.T) {
  2405  	setParallel(t)
  2406  	defer afterTest(t)
  2407  	if testing.Short() {
  2408  		t.Skip("skipping test in -short mode")
  2409  	}
  2410  	unblockc := make(chan bool)
  2411  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2412  		fmt.Fprintf(w, "Hello")
  2413  		w.(Flusher).Flush() // send headers and some body
  2414  		<-unblockc
  2415  	}))
  2416  	defer ts.Close()
  2417  	defer close(unblockc)
  2418  
  2419  	c := ts.Client()
  2420  	tr := c.Transport.(*Transport)
  2421  
  2422  	req, _ := NewRequest("GET", ts.URL, nil)
  2423  	ch := make(chan struct{})
  2424  	req.Cancel = ch
  2425  
  2426  	res, err := c.Do(req)
  2427  	if err != nil {
  2428  		t.Fatal(err)
  2429  	}
  2430  	go func() {
  2431  		time.Sleep(1 * time.Second)
  2432  		close(ch)
  2433  	}()
  2434  	t0 := time.Now()
  2435  	body, err := ioutil.ReadAll(res.Body)
  2436  	d := time.Since(t0)
  2437  
  2438  	if err != ExportErrRequestCanceled {
  2439  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  2440  	}
  2441  	if string(body) != "Hello" {
  2442  		t.Errorf("Body = %q; want Hello", body)
  2443  	}
  2444  	if d < 500*time.Millisecond {
  2445  		t.Errorf("expected ~1 second delay; got %v", d)
  2446  	}
  2447  	// Verify no outstanding requests after readLoop/writeLoop
  2448  	// goroutines shut down.
  2449  	for tries := 5; tries > 0; tries-- {
  2450  		n := tr.NumPendingRequestsForTesting()
  2451  		if n == 0 {
  2452  			break
  2453  		}
  2454  		time.Sleep(100 * time.Millisecond)
  2455  		if tries == 1 {
  2456  			t.Errorf("pending requests = %d; want 0", n)
  2457  		}
  2458  	}
  2459  }
  2460  
  2461  func TestCancelRequestWithChannelBeforeDo_Cancel(t *testing.T) {
  2462  	testCancelRequestWithChannelBeforeDo(t, false)
  2463  }
  2464  func TestCancelRequestWithChannelBeforeDo_Context(t *testing.T) {
  2465  	testCancelRequestWithChannelBeforeDo(t, true)
  2466  }
  2467  func testCancelRequestWithChannelBeforeDo(t *testing.T, withCtx bool) {
  2468  	setParallel(t)
  2469  	defer afterTest(t)
  2470  	unblockc := make(chan bool)
  2471  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2472  		<-unblockc
  2473  	}))
  2474  	defer ts.Close()
  2475  	defer close(unblockc)
  2476  
  2477  	c := ts.Client()
  2478  
  2479  	req, _ := NewRequest("GET", ts.URL, nil)
  2480  	if withCtx {
  2481  		ctx, cancel := context.WithCancel(context.Background())
  2482  		cancel()
  2483  		req = req.WithContext(ctx)
  2484  	} else {
  2485  		ch := make(chan struct{})
  2486  		req.Cancel = ch
  2487  		close(ch)
  2488  	}
  2489  
  2490  	_, err := c.Do(req)
  2491  	if ue, ok := err.(*url.Error); ok {
  2492  		err = ue.Err
  2493  	}
  2494  	if withCtx {
  2495  		if err != context.Canceled {
  2496  			t.Errorf("Do error = %v; want %v", err, context.Canceled)
  2497  		}
  2498  	} else {
  2499  		if err == nil || !strings.Contains(err.Error(), "canceled") {
  2500  			t.Errorf("Do error = %v; want cancellation", err)
  2501  		}
  2502  	}
  2503  }
  2504  
  2505  // Issue 11020. The returned error message should be errRequestCanceled
  2506  func TestTransportCancelBeforeResponseHeaders(t *testing.T) {
  2507  	defer afterTest(t)
  2508  
  2509  	serverConnCh := make(chan net.Conn, 1)
  2510  	tr := &Transport{
  2511  		Dial: func(network, addr string) (net.Conn, error) {
  2512  			cc, sc := net.Pipe()
  2513  			serverConnCh <- sc
  2514  			return cc, nil
  2515  		},
  2516  	}
  2517  	defer tr.CloseIdleConnections()
  2518  	errc := make(chan error, 1)
  2519  	req, _ := NewRequest("GET", "http://example.com/", nil)
  2520  	go func() {
  2521  		_, err := tr.RoundTrip(req)
  2522  		errc <- err
  2523  	}()
  2524  
  2525  	sc := <-serverConnCh
  2526  	verb := make([]byte, 3)
  2527  	if _, err := io.ReadFull(sc, verb); err != nil {
  2528  		t.Errorf("Error reading HTTP verb from server: %v", err)
  2529  	}
  2530  	if string(verb) != "GET" {
  2531  		t.Errorf("server received %q; want GET", verb)
  2532  	}
  2533  	defer sc.Close()
  2534  
  2535  	tr.CancelRequest(req)
  2536  
  2537  	err := <-errc
  2538  	if err == nil {
  2539  		t.Fatalf("unexpected success from RoundTrip")
  2540  	}
  2541  	if err != ExportErrRequestCanceled {
  2542  		t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err)
  2543  	}
  2544  }
  2545  
  2546  // golang.org/issue/3672 -- Client can't close HTTP stream
  2547  // Calling Close on a Response.Body used to just read until EOF.
  2548  // Now it actually closes the TCP connection.
  2549  func TestTransportCloseResponseBody(t *testing.T) {
  2550  	defer afterTest(t)
  2551  	writeErr := make(chan error, 1)
  2552  	msg := []byte("young\n")
  2553  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2554  		for {
  2555  			_, err := w.Write(msg)
  2556  			if err != nil {
  2557  				writeErr <- err
  2558  				return
  2559  			}
  2560  			w.(Flusher).Flush()
  2561  		}
  2562  	}))
  2563  	defer ts.Close()
  2564  
  2565  	c := ts.Client()
  2566  	tr := c.Transport.(*Transport)
  2567  
  2568  	req, _ := NewRequest("GET", ts.URL, nil)
  2569  	defer tr.CancelRequest(req)
  2570  
  2571  	res, err := c.Do(req)
  2572  	if err != nil {
  2573  		t.Fatal(err)
  2574  	}
  2575  
  2576  	const repeats = 3
  2577  	buf := make([]byte, len(msg)*repeats)
  2578  	want := bytes.Repeat(msg, repeats)
  2579  
  2580  	_, err = io.ReadFull(res.Body, buf)
  2581  	if err != nil {
  2582  		t.Fatal(err)
  2583  	}
  2584  	if !bytes.Equal(buf, want) {
  2585  		t.Fatalf("read %q; want %q", buf, want)
  2586  	}
  2587  	didClose := make(chan error, 1)
  2588  	go func() {
  2589  		didClose <- res.Body.Close()
  2590  	}()
  2591  	select {
  2592  	case err := <-didClose:
  2593  		if err != nil {
  2594  			t.Errorf("Close = %v", err)
  2595  		}
  2596  	case <-time.After(10 * time.Second):
  2597  		t.Fatal("too long waiting for close")
  2598  	}
  2599  	select {
  2600  	case err := <-writeErr:
  2601  		if err == nil {
  2602  			t.Errorf("expected non-nil write error")
  2603  		}
  2604  	case <-time.After(10 * time.Second):
  2605  		t.Fatal("too long waiting for write error")
  2606  	}
  2607  }
  2608  
  2609  type fooProto struct{}
  2610  
  2611  func (fooProto) RoundTrip(req *Request) (*Response, error) {
  2612  	res := &Response{
  2613  		Status:     "200 OK",
  2614  		StatusCode: 200,
  2615  		Header:     make(Header),
  2616  		Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
  2617  	}
  2618  	return res, nil
  2619  }
  2620  
  2621  func TestTransportAltProto(t *testing.T) {
  2622  	defer afterTest(t)
  2623  	tr := &Transport{}
  2624  	c := &Client{Transport: tr}
  2625  	tr.RegisterProtocol("foo", fooProto{})
  2626  	res, err := c.Get("foo://bar.com/path")
  2627  	if err != nil {
  2628  		t.Fatal(err)
  2629  	}
  2630  	bodyb, err := ioutil.ReadAll(res.Body)
  2631  	if err != nil {
  2632  		t.Fatal(err)
  2633  	}
  2634  	body := string(bodyb)
  2635  	if e := "You wanted foo://bar.com/path"; body != e {
  2636  		t.Errorf("got response %q, want %q", body, e)
  2637  	}
  2638  }
  2639  
  2640  func TestTransportNoHost(t *testing.T) {
  2641  	defer afterTest(t)
  2642  	tr := &Transport{}
  2643  	_, err := tr.RoundTrip(&Request{
  2644  		Header: make(Header),
  2645  		URL: &url.URL{
  2646  			Scheme: "http",
  2647  		},
  2648  	})
  2649  	want := "http: no Host in request URL"
  2650  	if got := fmt.Sprint(err); got != want {
  2651  		t.Errorf("error = %v; want %q", err, want)
  2652  	}
  2653  }
  2654  
  2655  // Issue 13311
  2656  func TestTransportEmptyMethod(t *testing.T) {
  2657  	req, _ := NewRequest("GET", "http://foo.com/", nil)
  2658  	req.Method = ""                                 // docs say "For client requests an empty string means GET"
  2659  	got, err := httputil.DumpRequestOut(req, false) // DumpRequestOut uses Transport
  2660  	if err != nil {
  2661  		t.Fatal(err)
  2662  	}
  2663  	if !strings.Contains(string(got), "GET ") {
  2664  		t.Fatalf("expected substring 'GET '; got: %s", got)
  2665  	}
  2666  }
  2667  
  2668  func TestTransportSocketLateBinding(t *testing.T) {
  2669  	setParallel(t)
  2670  	defer afterTest(t)
  2671  
  2672  	mux := NewServeMux()
  2673  	fooGate := make(chan bool, 1)
  2674  	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
  2675  		w.Header().Set("foo-ipport", r.RemoteAddr)
  2676  		w.(Flusher).Flush()
  2677  		<-fooGate
  2678  	})
  2679  	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
  2680  		w.Header().Set("bar-ipport", r.RemoteAddr)
  2681  	})
  2682  	ts := httptest.NewServer(mux)
  2683  	defer ts.Close()
  2684  
  2685  	dialGate := make(chan bool, 1)
  2686  	c := ts.Client()
  2687  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  2688  		if <-dialGate {
  2689  			return net.Dial(n, addr)
  2690  		}
  2691  		return nil, errors.New("manually closed")
  2692  	}
  2693  
  2694  	dialGate <- true // only allow one dial
  2695  	fooRes, err := c.Get(ts.URL + "/foo")
  2696  	if err != nil {
  2697  		t.Fatal(err)
  2698  	}
  2699  	fooAddr := fooRes.Header.Get("foo-ipport")
  2700  	if fooAddr == "" {
  2701  		t.Fatal("No addr on /foo request")
  2702  	}
  2703  	time.AfterFunc(200*time.Millisecond, func() {
  2704  		// let the foo response finish so we can use its
  2705  		// connection for /bar
  2706  		fooGate <- true
  2707  		io.Copy(ioutil.Discard, fooRes.Body)
  2708  		fooRes.Body.Close()
  2709  	})
  2710  
  2711  	barRes, err := c.Get(ts.URL + "/bar")
  2712  	if err != nil {
  2713  		t.Fatal(err)
  2714  	}
  2715  	barAddr := barRes.Header.Get("bar-ipport")
  2716  	if barAddr != fooAddr {
  2717  		t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
  2718  	}
  2719  	barRes.Body.Close()
  2720  	dialGate <- false
  2721  }
  2722  
  2723  // Issue 2184
  2724  func TestTransportReading100Continue(t *testing.T) {
  2725  	defer afterTest(t)
  2726  
  2727  	const numReqs = 5
  2728  	reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
  2729  	reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
  2730  
  2731  	send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
  2732  		defer w.Close()
  2733  		defer r.Close()
  2734  		br := bufio.NewReader(r)
  2735  		n := 0
  2736  		for {
  2737  			n++
  2738  			req, err := ReadRequest(br)
  2739  			if err == io.EOF {
  2740  				return
  2741  			}
  2742  			if err != nil {
  2743  				t.Error(err)
  2744  				return
  2745  			}
  2746  			slurp, err := ioutil.ReadAll(req.Body)
  2747  			if err != nil {
  2748  				t.Errorf("Server request body slurp: %v", err)
  2749  				return
  2750  			}
  2751  			id := req.Header.Get("Request-Id")
  2752  			resCode := req.Header.Get("X-Want-Response-Code")
  2753  			if resCode == "" {
  2754  				resCode = "100 Continue"
  2755  				if string(slurp) != reqBody(n) {
  2756  					t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
  2757  				}
  2758  			}
  2759  			body := fmt.Sprintf("Response number %d", n)
  2760  			v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
  2761  Date: Thu, 28 Feb 2013 17:55:41 GMT
  2762  
  2763  HTTP/1.1 200 OK
  2764  Content-Type: text/html
  2765  Echo-Request-Id: %s
  2766  Content-Length: %d
  2767  
  2768  %s`, resCode, id, len(body), body), "\n", "\r\n", -1))
  2769  			w.Write(v)
  2770  			if id == reqID(numReqs) {
  2771  				return
  2772  			}
  2773  		}
  2774  
  2775  	}
  2776  
  2777  	tr := &Transport{
  2778  		Dial: func(n, addr string) (net.Conn, error) {
  2779  			sr, sw := io.Pipe() // server read/write
  2780  			cr, cw := io.Pipe() // client read/write
  2781  			conn := &rwTestConn{
  2782  				Reader: cr,
  2783  				Writer: sw,
  2784  				closeFunc: func() error {
  2785  					sw.Close()
  2786  					cw.Close()
  2787  					return nil
  2788  				},
  2789  			}
  2790  			go send100Response(cw, sr)
  2791  			return conn, nil
  2792  		},
  2793  		DisableKeepAlives: false,
  2794  	}
  2795  	defer tr.CloseIdleConnections()
  2796  	c := &Client{Transport: tr}
  2797  
  2798  	testResponse := func(req *Request, name string, wantCode int) {
  2799  		t.Helper()
  2800  		res, err := c.Do(req)
  2801  		if err != nil {
  2802  			t.Fatalf("%s: Do: %v", name, err)
  2803  		}
  2804  		if res.StatusCode != wantCode {
  2805  			t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
  2806  		}
  2807  		if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
  2808  			t.Errorf("%s: response id %q != request id %q", name, idBack, id)
  2809  		}
  2810  		_, err = ioutil.ReadAll(res.Body)
  2811  		if err != nil {
  2812  			t.Fatalf("%s: Slurp error: %v", name, err)
  2813  		}
  2814  	}
  2815  
  2816  	// Few 100 responses, making sure we're not off-by-one.
  2817  	for i := 1; i <= numReqs; i++ {
  2818  		req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
  2819  		req.Header.Set("Request-Id", reqID(i))
  2820  		testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
  2821  	}
  2822  }
  2823  
  2824  // Issue 17739: the HTTP client must ignore any unknown 1xx
  2825  // informational responses before the actual response.
  2826  func TestTransportIgnore1xxResponses(t *testing.T) {
  2827  	setParallel(t)
  2828  	defer afterTest(t)
  2829  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  2830  		conn, buf, _ := w.(Hijacker).Hijack()
  2831  		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"))
  2832  		buf.Flush()
  2833  		conn.Close()
  2834  	}))
  2835  	defer cst.close()
  2836  	cst.tr.DisableKeepAlives = true // prevent log spam; our test server is hanging up anyway
  2837  
  2838  	var got bytes.Buffer
  2839  
  2840  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  2841  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  2842  		Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
  2843  			fmt.Fprintf(&got, "1xx: code=%v, header=%v\n", code, header)
  2844  			return nil
  2845  		},
  2846  	}))
  2847  	res, err := cst.c.Do(req)
  2848  	if err != nil {
  2849  		t.Fatal(err)
  2850  	}
  2851  	defer res.Body.Close()
  2852  
  2853  	res.Write(&got)
  2854  	want := "1xx: code=123, header=map[Foo:[bar]]\nHTTP/1.1 200 OK\r\nContent-Length: 5\r\nBar: baz\r\n\r\nHello"
  2855  	if got.String() != want {
  2856  		t.Errorf(" got: %q\nwant: %q\n", got.Bytes(), want)
  2857  	}
  2858  }
  2859  
  2860  func TestTransportLimits1xxResponses(t *testing.T) {
  2861  	setParallel(t)
  2862  	defer afterTest(t)
  2863  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  2864  		conn, buf, _ := w.(Hijacker).Hijack()
  2865  		for i := 0; i < 10; i++ {
  2866  			buf.Write([]byte("HTTP/1.1 123 OneTwoThree\r\n\r\n"))
  2867  		}
  2868  		buf.Write([]byte("HTTP/1.1 204 No Content\r\n\r\n"))
  2869  		buf.Flush()
  2870  		conn.Close()
  2871  	}))
  2872  	defer cst.close()
  2873  	cst.tr.DisableKeepAlives = true // prevent log spam; our test server is hanging up anyway
  2874  
  2875  	res, err := cst.c.Get(cst.ts.URL)
  2876  	if res != nil {
  2877  		defer res.Body.Close()
  2878  	}
  2879  	got := fmt.Sprint(err)
  2880  	wantSub := "too many 1xx informational responses"
  2881  	if !strings.Contains(got, wantSub) {
  2882  		t.Errorf("Get error = %v; want substring %q", err, wantSub)
  2883  	}
  2884  }
  2885  
  2886  // Issue 26161: the HTTP client must treat 101 responses
  2887  // as the final response.
  2888  func TestTransportTreat101Terminal(t *testing.T) {
  2889  	setParallel(t)
  2890  	defer afterTest(t)
  2891  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  2892  		conn, buf, _ := w.(Hijacker).Hijack()
  2893  		buf.Write([]byte("HTTP/1.1 101 Switching Protocols\r\n\r\n"))
  2894  		buf.Write([]byte("HTTP/1.1 204 No Content\r\n\r\n"))
  2895  		buf.Flush()
  2896  		conn.Close()
  2897  	}))
  2898  	defer cst.close()
  2899  	res, err := cst.c.Get(cst.ts.URL)
  2900  	if err != nil {
  2901  		t.Fatal(err)
  2902  	}
  2903  	defer res.Body.Close()
  2904  	if res.StatusCode != StatusSwitchingProtocols {
  2905  		t.Errorf("StatusCode = %v; want 101 Switching Protocols", res.StatusCode)
  2906  	}
  2907  }
  2908  
  2909  type proxyFromEnvTest struct {
  2910  	req string // URL to fetch; blank means "http://example.com"
  2911  
  2912  	env      string // HTTP_PROXY
  2913  	httpsenv string // HTTPS_PROXY
  2914  	noenv    string // NO_PROXY
  2915  	reqmeth  string // REQUEST_METHOD
  2916  
  2917  	want    string
  2918  	wanterr error
  2919  }
  2920  
  2921  func (t proxyFromEnvTest) String() string {
  2922  	var buf bytes.Buffer
  2923  	space := func() {
  2924  		if buf.Len() > 0 {
  2925  			buf.WriteByte(' ')
  2926  		}
  2927  	}
  2928  	if t.env != "" {
  2929  		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
  2930  	}
  2931  	if t.httpsenv != "" {
  2932  		space()
  2933  		fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv)
  2934  	}
  2935  	if t.noenv != "" {
  2936  		space()
  2937  		fmt.Fprintf(&buf, "no_proxy=%q", t.noenv)
  2938  	}
  2939  	if t.reqmeth != "" {
  2940  		space()
  2941  		fmt.Fprintf(&buf, "request_method=%q", t.reqmeth)
  2942  	}
  2943  	req := "http://example.com"
  2944  	if t.req != "" {
  2945  		req = t.req
  2946  	}
  2947  	space()
  2948  	fmt.Fprintf(&buf, "req=%q", req)
  2949  	return strings.TrimSpace(buf.String())
  2950  }
  2951  
  2952  var proxyFromEnvTests = []proxyFromEnvTest{
  2953  	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2954  	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
  2955  	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
  2956  	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
  2957  	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2958  	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
  2959  	{env: "socks5://127.0.0.1", want: "socks5://127.0.0.1"},
  2960  
  2961  	// Don't use secure for http
  2962  	{req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"},
  2963  	// Use secure for https.
  2964  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"},
  2965  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"},
  2966  
  2967  	// Issue 16405: don't use HTTP_PROXY in a CGI environment,
  2968  	// where HTTP_PROXY can be attacker-controlled.
  2969  	{env: "http://10.1.2.3:8080", reqmeth: "POST",
  2970  		want:    "<nil>",
  2971  		wanterr: errors.New("refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxy")},
  2972  
  2973  	{want: "<nil>"},
  2974  
  2975  	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  2976  	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2977  	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2978  	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
  2979  	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2980  }
  2981  
  2982  func testProxyForRequest(t *testing.T, tt proxyFromEnvTest, proxyForRequest func(req *Request) (*url.URL, error)) {
  2983  	t.Helper()
  2984  	reqURL := tt.req
  2985  	if reqURL == "" {
  2986  		reqURL = "http://example.com"
  2987  	}
  2988  	req, _ := NewRequest("GET", reqURL, nil)
  2989  	url, err := proxyForRequest(req)
  2990  	if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
  2991  		t.Errorf("%v: got error = %q, want %q", tt, g, e)
  2992  		return
  2993  	}
  2994  	if got := fmt.Sprintf("%s", url); got != tt.want {
  2995  		t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
  2996  	}
  2997  }
  2998  
  2999  func TestProxyFromEnvironment(t *testing.T) {
  3000  	ResetProxyEnv()
  3001  	defer ResetProxyEnv()
  3002  	for _, tt := range proxyFromEnvTests {
  3003  		testProxyForRequest(t, tt, func(req *Request) (*url.URL, error) {
  3004  			os.Setenv("HTTP_PROXY", tt.env)
  3005  			os.Setenv("HTTPS_PROXY", tt.httpsenv)
  3006  			os.Setenv("NO_PROXY", tt.noenv)
  3007  			os.Setenv("REQUEST_METHOD", tt.reqmeth)
  3008  			ResetCachedEnvironment()
  3009  			return ProxyFromEnvironment(req)
  3010  		})
  3011  	}
  3012  }
  3013  
  3014  func TestProxyFromEnvironmentLowerCase(t *testing.T) {
  3015  	ResetProxyEnv()
  3016  	defer ResetProxyEnv()
  3017  	for _, tt := range proxyFromEnvTests {
  3018  		testProxyForRequest(t, tt, func(req *Request) (*url.URL, error) {
  3019  			os.Setenv("http_proxy", tt.env)
  3020  			os.Setenv("https_proxy", tt.httpsenv)
  3021  			os.Setenv("no_proxy", tt.noenv)
  3022  			os.Setenv("REQUEST_METHOD", tt.reqmeth)
  3023  			ResetCachedEnvironment()
  3024  			return ProxyFromEnvironment(req)
  3025  		})
  3026  	}
  3027  }
  3028  
  3029  func TestIdleConnChannelLeak(t *testing.T) {
  3030  	// Not parallel: uses global test hooks.
  3031  	var mu sync.Mutex
  3032  	var n int
  3033  
  3034  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3035  		mu.Lock()
  3036  		n++
  3037  		mu.Unlock()
  3038  	}))
  3039  	defer ts.Close()
  3040  
  3041  	const nReqs = 5
  3042  	didRead := make(chan bool, nReqs)
  3043  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
  3044  	defer SetReadLoopBeforeNextReadHook(nil)
  3045  
  3046  	c := ts.Client()
  3047  	tr := c.Transport.(*Transport)
  3048  	tr.Dial = func(netw, addr string) (net.Conn, error) {
  3049  		return net.Dial(netw, ts.Listener.Addr().String())
  3050  	}
  3051  
  3052  	// First, without keep-alives.
  3053  	for _, disableKeep := range []bool{true, false} {
  3054  		tr.DisableKeepAlives = disableKeep
  3055  		for i := 0; i < nReqs; i++ {
  3056  			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
  3057  			if err != nil {
  3058  				t.Fatal(err)
  3059  			}
  3060  			// Note: no res.Body.Close is needed here, since the
  3061  			// response Content-Length is zero. Perhaps the test
  3062  			// should be more explicit and use a HEAD, but tests
  3063  			// elsewhere guarantee that zero byte responses generate
  3064  			// a "Content-Length: 0" instead of chunking.
  3065  		}
  3066  
  3067  		// At this point, each of the 5 Transport.readLoop goroutines
  3068  		// are scheduling noting that there are no response bodies (see
  3069  		// earlier comment), and are then calling putIdleConn, which
  3070  		// decrements this count. Usually that happens quickly, which is
  3071  		// why this test has seemed to work for ages. But it's still
  3072  		// racey: we have wait for them to finish first. See Issue 10427
  3073  		for i := 0; i < nReqs; i++ {
  3074  			<-didRead
  3075  		}
  3076  
  3077  		if got := tr.IdleConnWaitMapSizeForTesting(); got != 0 {
  3078  			t.Fatalf("for DisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
  3079  		}
  3080  	}
  3081  }
  3082  
  3083  // Verify the status quo: that the Client.Post function coerces its
  3084  // body into a ReadCloser if it's a Closer, and that the Transport
  3085  // then closes it.
  3086  func TestTransportClosesRequestBody(t *testing.T) {
  3087  	defer afterTest(t)
  3088  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3089  		io.Copy(ioutil.Discard, r.Body)
  3090  	}))
  3091  	defer ts.Close()
  3092  
  3093  	c := ts.Client()
  3094  
  3095  	closes := 0
  3096  
  3097  	res, err := c.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
  3098  	if err != nil {
  3099  		t.Fatal(err)
  3100  	}
  3101  	res.Body.Close()
  3102  	if closes != 1 {
  3103  		t.Errorf("closes = %d; want 1", closes)
  3104  	}
  3105  }
  3106  
  3107  func TestTransportTLSHandshakeTimeout(t *testing.T) {
  3108  	defer afterTest(t)
  3109  	if testing.Short() {
  3110  		t.Skip("skipping in short mode")
  3111  	}
  3112  	ln := newLocalListener(t)
  3113  	defer ln.Close()
  3114  	testdonec := make(chan struct{})
  3115  	defer close(testdonec)
  3116  
  3117  	go func() {
  3118  		c, err := ln.Accept()
  3119  		if err != nil {
  3120  			t.Error(err)
  3121  			return
  3122  		}
  3123  		<-testdonec
  3124  		c.Close()
  3125  	}()
  3126  
  3127  	getdonec := make(chan struct{})
  3128  	go func() {
  3129  		defer close(getdonec)
  3130  		tr := &Transport{
  3131  			Dial: func(_, _ string) (net.Conn, error) {
  3132  				return net.Dial("tcp", ln.Addr().String())
  3133  			},
  3134  			TLSHandshakeTimeout: 250 * time.Millisecond,
  3135  		}
  3136  		cl := &Client{Transport: tr}
  3137  		_, err := cl.Get("https://dummy.tld/")
  3138  		if err == nil {
  3139  			t.Error("expected error")
  3140  			return
  3141  		}
  3142  		ue, ok := err.(*url.Error)
  3143  		if !ok {
  3144  			t.Errorf("expected url.Error; got %#v", err)
  3145  			return
  3146  		}
  3147  		ne, ok := ue.Err.(net.Error)
  3148  		if !ok {
  3149  			t.Errorf("expected net.Error; got %#v", err)
  3150  			return
  3151  		}
  3152  		if !ne.Timeout() {
  3153  			t.Errorf("expected timeout error; got %v", err)
  3154  		}
  3155  		if !strings.Contains(err.Error(), "handshake timeout") {
  3156  			t.Errorf("expected 'handshake timeout' in error; got %v", err)
  3157  		}
  3158  	}()
  3159  	select {
  3160  	case <-getdonec:
  3161  	case <-time.After(5 * time.Second):
  3162  		t.Error("test timeout; TLS handshake hung?")
  3163  	}
  3164  }
  3165  
  3166  // Trying to repro golang.org/issue/3514
  3167  func TestTLSServerClosesConnection(t *testing.T) {
  3168  	defer afterTest(t)
  3169  
  3170  	closedc := make(chan bool, 1)
  3171  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3172  		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
  3173  			conn, _, _ := w.(Hijacker).Hijack()
  3174  			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
  3175  			conn.Close()
  3176  			closedc <- true
  3177  			return
  3178  		}
  3179  		fmt.Fprintf(w, "hello")
  3180  	}))
  3181  	defer ts.Close()
  3182  
  3183  	c := ts.Client()
  3184  	tr := c.Transport.(*Transport)
  3185  
  3186  	var nSuccess = 0
  3187  	var errs []error
  3188  	const trials = 20
  3189  	for i := 0; i < trials; i++ {
  3190  		tr.CloseIdleConnections()
  3191  		res, err := c.Get(ts.URL + "/keep-alive-then-die")
  3192  		if err != nil {
  3193  			t.Fatal(err)
  3194  		}
  3195  		<-closedc
  3196  		slurp, err := ioutil.ReadAll(res.Body)
  3197  		if err != nil {
  3198  			t.Fatal(err)
  3199  		}
  3200  		if string(slurp) != "foo" {
  3201  			t.Errorf("Got %q, want foo", slurp)
  3202  		}
  3203  
  3204  		// Now try again and see if we successfully
  3205  		// pick a new connection.
  3206  		res, err = c.Get(ts.URL + "/")
  3207  		if err != nil {
  3208  			errs = append(errs, err)
  3209  			continue
  3210  		}
  3211  		slurp, err = ioutil.ReadAll(res.Body)
  3212  		if err != nil {
  3213  			errs = append(errs, err)
  3214  			continue
  3215  		}
  3216  		nSuccess++
  3217  	}
  3218  	if nSuccess > 0 {
  3219  		t.Logf("successes = %d of %d", nSuccess, trials)
  3220  	} else {
  3221  		t.Errorf("All runs failed:")
  3222  	}
  3223  	for _, err := range errs {
  3224  		t.Logf("  err: %v", err)
  3225  	}
  3226  }
  3227  
  3228  // byteFromChanReader is an io.Reader that reads a single byte at a
  3229  // time from the channel. When the channel is closed, the reader
  3230  // returns io.EOF.
  3231  type byteFromChanReader chan byte
  3232  
  3233  func (c byteFromChanReader) Read(p []byte) (n int, err error) {
  3234  	if len(p) == 0 {
  3235  		return
  3236  	}
  3237  	b, ok := <-c
  3238  	if !ok {
  3239  		return 0, io.EOF
  3240  	}
  3241  	p[0] = b
  3242  	return 1, nil
  3243  }
  3244  
  3245  // Verifies that the Transport doesn't reuse a connection in the case
  3246  // where the server replies before the request has been fully
  3247  // written. We still honor that reply (see TestIssue3595), but don't
  3248  // send future requests on the connection because it's then in a
  3249  // questionable state.
  3250  // golang.org/issue/7569
  3251  func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
  3252  	setParallel(t)
  3253  	defer afterTest(t)
  3254  	var sconn struct {
  3255  		sync.Mutex
  3256  		c net.Conn
  3257  	}
  3258  	var getOkay bool
  3259  	closeConn := func() {
  3260  		sconn.Lock()
  3261  		defer sconn.Unlock()
  3262  		if sconn.c != nil {
  3263  			sconn.c.Close()
  3264  			sconn.c = nil
  3265  			if !getOkay {
  3266  				t.Logf("Closed server connection")
  3267  			}
  3268  		}
  3269  	}
  3270  	defer closeConn()
  3271  
  3272  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3273  		if r.Method == "GET" {
  3274  			io.WriteString(w, "bar")
  3275  			return
  3276  		}
  3277  		conn, _, _ := w.(Hijacker).Hijack()
  3278  		sconn.Lock()
  3279  		sconn.c = conn
  3280  		sconn.Unlock()
  3281  		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
  3282  		go io.Copy(ioutil.Discard, conn)
  3283  	}))
  3284  	defer ts.Close()
  3285  	c := ts.Client()
  3286  
  3287  	const bodySize = 256 << 10
  3288  	finalBit := make(byteFromChanReader, 1)
  3289  	req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
  3290  	req.ContentLength = bodySize
  3291  	res, err := c.Do(req)
  3292  	if err := wantBody(res, err, "foo"); err != nil {
  3293  		t.Errorf("POST response: %v", err)
  3294  	}
  3295  	donec := make(chan bool)
  3296  	go func() {
  3297  		defer close(donec)
  3298  		res, err = c.Get(ts.URL)
  3299  		if err := wantBody(res, err, "bar"); err != nil {
  3300  			t.Errorf("GET response: %v", err)
  3301  			return
  3302  		}
  3303  		getOkay = true // suppress test noise
  3304  	}()
  3305  	time.AfterFunc(5*time.Second, closeConn)
  3306  	select {
  3307  	case <-donec:
  3308  		finalBit <- 'x' // unblock the writeloop of the first Post
  3309  		close(finalBit)
  3310  	case <-time.After(7 * time.Second):
  3311  		t.Fatal("timeout waiting for GET request to finish")
  3312  	}
  3313  }
  3314  
  3315  // Tests that we don't leak Transport persistConn.readLoop goroutines
  3316  // when a server hangs up immediately after saying it would keep-alive.
  3317  func TestTransportIssue10457(t *testing.T) {
  3318  	defer afterTest(t) // used to fail in goroutine leak check
  3319  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3320  		// Send a response with no body, keep-alive
  3321  		// (implicit), and then lie and immediately close the
  3322  		// connection. This forces the Transport's readLoop to
  3323  		// immediately Peek an io.EOF and get to the point
  3324  		// that used to hang.
  3325  		conn, _, _ := w.(Hijacker).Hijack()
  3326  		conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
  3327  		conn.Close()
  3328  	}))
  3329  	defer ts.Close()
  3330  	c := ts.Client()
  3331  
  3332  	res, err := c.Get(ts.URL)
  3333  	if err != nil {
  3334  		t.Fatalf("Get: %v", err)
  3335  	}
  3336  	defer res.Body.Close()
  3337  
  3338  	// Just a sanity check that we at least get the response. The real
  3339  	// test here is that the "defer afterTest" above doesn't find any
  3340  	// leaked goroutines.
  3341  	if got, want := res.Header.Get("Foo"), "Bar"; got != want {
  3342  		t.Errorf("Foo header = %q; want %q", got, want)
  3343  	}
  3344  }
  3345  
  3346  type errorReader struct {
  3347  	err error
  3348  }
  3349  
  3350  func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
  3351  
  3352  type closerFunc func() error
  3353  
  3354  func (f closerFunc) Close() error { return f() }
  3355  
  3356  type writerFuncConn struct {
  3357  	net.Conn
  3358  	write func(p []byte) (n int, err error)
  3359  }
  3360  
  3361  func (c writerFuncConn) Write(p []byte) (n int, err error) { return c.write(p) }
  3362  
  3363  // Issues 4677, 18241, and 17844. If we try to reuse a connection that the
  3364  // server is in the process of closing, we may end up successfully writing out
  3365  // our request (or a portion of our request) only to find a connection error
  3366  // when we try to read from (or finish writing to) the socket.
  3367  //
  3368  // NOTE: we resend a request only if:
  3369  //   - we reused a keep-alive connection
  3370  //   - we haven't yet received any header data
  3371  //   - either we wrote no bytes to the server, or the request is idempotent
  3372  // This automatically prevents an infinite resend loop because we'll run out of
  3373  // the cached keep-alive connections eventually.
  3374  func TestRetryRequestsOnError(t *testing.T) {
  3375  	newRequest := func(method, urlStr string, body io.Reader) *Request {
  3376  		req, err := NewRequest(method, urlStr, body)
  3377  		if err != nil {
  3378  			t.Fatal(err)
  3379  		}
  3380  		return req
  3381  	}
  3382  
  3383  	testCases := []struct {
  3384  		name       string
  3385  		failureN   int
  3386  		failureErr error
  3387  		// Note that we can't just re-use the Request object across calls to c.Do
  3388  		// because we need to rewind Body between calls.  (GetBody is only used to
  3389  		// rewind Body on failure and redirects, not just because it's done.)
  3390  		req       func() *Request
  3391  		reqString string
  3392  	}{
  3393  		{
  3394  			name: "IdempotentNoBodySomeWritten",
  3395  			// Believe that we've written some bytes to the server, so we know we're
  3396  			// not just in the "retry when no bytes sent" case".
  3397  			failureN: 1,
  3398  			// Use the specific error that shouldRetryRequest looks for with idempotent requests.
  3399  			failureErr: ExportErrServerClosedIdle,
  3400  			req: func() *Request {
  3401  				return newRequest("GET", "http://fake.golang", nil)
  3402  			},
  3403  			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`,
  3404  		},
  3405  		{
  3406  			name: "IdempotentGetBodySomeWritten",
  3407  			// Believe that we've written some bytes to the server, so we know we're
  3408  			// not just in the "retry when no bytes sent" case".
  3409  			failureN: 1,
  3410  			// Use the specific error that shouldRetryRequest looks for with idempotent requests.
  3411  			failureErr: ExportErrServerClosedIdle,
  3412  			req: func() *Request {
  3413  				return newRequest("GET", "http://fake.golang", strings.NewReader("foo\n"))
  3414  			},
  3415  			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`,
  3416  		},
  3417  		{
  3418  			name: "NothingWrittenNoBody",
  3419  			// It's key that we return 0 here -- that's what enables Transport to know
  3420  			// that nothing was written, even though this is a non-idempotent request.
  3421  			failureN:   0,
  3422  			failureErr: errors.New("second write fails"),
  3423  			req: func() *Request {
  3424  				return newRequest("DELETE", "http://fake.golang", nil)
  3425  			},
  3426  			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`,
  3427  		},
  3428  		{
  3429  			name: "NothingWrittenGetBody",
  3430  			// It's key that we return 0 here -- that's what enables Transport to know
  3431  			// that nothing was written, even though this is a non-idempotent request.
  3432  			failureN:   0,
  3433  			failureErr: errors.New("second write fails"),
  3434  			// Note that NewRequest will set up GetBody for strings.Reader, which is
  3435  			// required for the retry to occur
  3436  			req: func() *Request {
  3437  				return newRequest("POST", "http://fake.golang", strings.NewReader("foo\n"))
  3438  			},
  3439  			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`,
  3440  		},
  3441  	}
  3442  
  3443  	for _, tc := range testCases {
  3444  		t.Run(tc.name, func(t *testing.T) {
  3445  			defer afterTest(t)
  3446  
  3447  			var (
  3448  				mu     sync.Mutex
  3449  				logbuf bytes.Buffer
  3450  			)
  3451  			logf := func(format string, args ...interface{}) {
  3452  				mu.Lock()
  3453  				defer mu.Unlock()
  3454  				fmt.Fprintf(&logbuf, format, args...)
  3455  				logbuf.WriteByte('\n')
  3456  			}
  3457  
  3458  			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3459  				logf("Handler")
  3460  				w.Header().Set("X-Status", "ok")
  3461  			}))
  3462  			defer ts.Close()
  3463  
  3464  			var writeNumAtomic int32
  3465  			c := ts.Client()
  3466  			c.Transport.(*Transport).Dial = func(network, addr string) (net.Conn, error) {
  3467  				logf("Dial")
  3468  				c, err := net.Dial(network, ts.Listener.Addr().String())
  3469  				if err != nil {
  3470  					logf("Dial error: %v", err)
  3471  					return nil, err
  3472  				}
  3473  				return &writerFuncConn{
  3474  					Conn: c,
  3475  					write: func(p []byte) (n int, err error) {
  3476  						if atomic.AddInt32(&writeNumAtomic, 1) == 2 {
  3477  							logf("intentional write failure")
  3478  							return tc.failureN, tc.failureErr
  3479  						}
  3480  						logf("Write(%q)", p)
  3481  						return c.Write(p)
  3482  					},
  3483  				}, nil
  3484  			}
  3485  
  3486  			SetRoundTripRetried(func() {
  3487  				logf("Retried.")
  3488  			})
  3489  			defer SetRoundTripRetried(nil)
  3490  
  3491  			for i := 0; i < 3; i++ {
  3492  				t0 := time.Now()
  3493  				res, err := c.Do(tc.req())
  3494  				if err != nil {
  3495  					if time.Since(t0) < MaxWriteWaitBeforeConnReuse/2 {
  3496  						mu.Lock()
  3497  						got := logbuf.String()
  3498  						mu.Unlock()
  3499  						t.Fatalf("i=%d: Do = %v; log:\n%s", i, err, got)
  3500  					}
  3501  					t.Skipf("connection likely wasn't recycled within %d, interfering with actual test; skipping", MaxWriteWaitBeforeConnReuse)
  3502  				}
  3503  				res.Body.Close()
  3504  			}
  3505  
  3506  			mu.Lock()
  3507  			got := logbuf.String()
  3508  			mu.Unlock()
  3509  			want := fmt.Sprintf(`Dial
  3510  Write("%s")
  3511  Handler
  3512  intentional write failure
  3513  Retried.
  3514  Dial
  3515  Write("%s")
  3516  Handler
  3517  Write("%s")
  3518  Handler
  3519  `, tc.reqString, tc.reqString, tc.reqString)
  3520  			if got != want {
  3521  				t.Errorf("Log of events differs. Got:\n%s\nWant:\n%s", got, want)
  3522  			}
  3523  		})
  3524  	}
  3525  }
  3526  
  3527  // Issue 6981
  3528  func TestTransportClosesBodyOnError(t *testing.T) {
  3529  	setParallel(t)
  3530  	defer afterTest(t)
  3531  	readBody := make(chan error, 1)
  3532  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3533  		_, err := ioutil.ReadAll(r.Body)
  3534  		readBody <- err
  3535  	}))
  3536  	defer ts.Close()
  3537  	c := ts.Client()
  3538  	fakeErr := errors.New("fake error")
  3539  	didClose := make(chan bool, 1)
  3540  	req, _ := NewRequest("POST", ts.URL, struct {
  3541  		io.Reader
  3542  		io.Closer
  3543  	}{
  3544  		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}),
  3545  		closerFunc(func() error {
  3546  			select {
  3547  			case didClose <- true:
  3548  			default:
  3549  			}
  3550  			return nil
  3551  		}),
  3552  	})
  3553  	res, err := c.Do(req)
  3554  	if res != nil {
  3555  		defer res.Body.Close()
  3556  	}
  3557  	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
  3558  		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
  3559  	}
  3560  	select {
  3561  	case err := <-readBody:
  3562  		if err == nil {
  3563  			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
  3564  		}
  3565  	case <-time.After(5 * time.Second):
  3566  		t.Error("timeout waiting for server handler to complete")
  3567  	}
  3568  	select {
  3569  	case <-didClose:
  3570  	default:
  3571  		t.Errorf("didn't see Body.Close")
  3572  	}
  3573  }
  3574  
  3575  func TestTransportDialTLS(t *testing.T) {
  3576  	setParallel(t)
  3577  	defer afterTest(t)
  3578  	var mu sync.Mutex // guards following
  3579  	var gotReq, didDial bool
  3580  
  3581  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3582  		mu.Lock()
  3583  		gotReq = true
  3584  		mu.Unlock()
  3585  	}))
  3586  	defer ts.Close()
  3587  	c := ts.Client()
  3588  	c.Transport.(*Transport).DialTLS = func(netw, addr string) (net.Conn, error) {
  3589  		mu.Lock()
  3590  		didDial = true
  3591  		mu.Unlock()
  3592  		c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig)
  3593  		if err != nil {
  3594  			return nil, err
  3595  		}
  3596  		return c, c.Handshake()
  3597  	}
  3598  
  3599  	res, err := c.Get(ts.URL)
  3600  	if err != nil {
  3601  		t.Fatal(err)
  3602  	}
  3603  	res.Body.Close()
  3604  	mu.Lock()
  3605  	if !gotReq {
  3606  		t.Error("didn't get request")
  3607  	}
  3608  	if !didDial {
  3609  		t.Error("didn't use dial hook")
  3610  	}
  3611  }
  3612  
  3613  func TestTransportDialContext(t *testing.T) {
  3614  	setParallel(t)
  3615  	defer afterTest(t)
  3616  	var mu sync.Mutex // guards following
  3617  	var gotReq bool
  3618  	var receivedContext context.Context
  3619  
  3620  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3621  		mu.Lock()
  3622  		gotReq = true
  3623  		mu.Unlock()
  3624  	}))
  3625  	defer ts.Close()
  3626  	c := ts.Client()
  3627  	c.Transport.(*Transport).DialContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
  3628  		mu.Lock()
  3629  		receivedContext = ctx
  3630  		mu.Unlock()
  3631  		return net.Dial(netw, addr)
  3632  	}
  3633  
  3634  	req, err := NewRequest("GET", ts.URL, nil)
  3635  	if err != nil {
  3636  		t.Fatal(err)
  3637  	}
  3638  	ctx := context.WithValue(context.Background(), "some-key", "some-value")
  3639  	res, err := c.Do(req.WithContext(ctx))
  3640  	if err != nil {
  3641  		t.Fatal(err)
  3642  	}
  3643  	res.Body.Close()
  3644  	mu.Lock()
  3645  	if !gotReq {
  3646  		t.Error("didn't get request")
  3647  	}
  3648  	if receivedContext != ctx {
  3649  		t.Error("didn't receive correct context")
  3650  	}
  3651  }
  3652  
  3653  func TestTransportDialTLSContext(t *testing.T) {
  3654  	setParallel(t)
  3655  	defer afterTest(t)
  3656  	var mu sync.Mutex // guards following
  3657  	var gotReq bool
  3658  	var receivedContext context.Context
  3659  
  3660  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3661  		mu.Lock()
  3662  		gotReq = true
  3663  		mu.Unlock()
  3664  	}))
  3665  	defer ts.Close()
  3666  	c := ts.Client()
  3667  	c.Transport.(*Transport).DialTLSContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
  3668  		mu.Lock()
  3669  		receivedContext = ctx
  3670  		mu.Unlock()
  3671  		c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig)
  3672  		if err != nil {
  3673  			return nil, err
  3674  		}
  3675  		return c, c.Handshake()
  3676  	}
  3677  
  3678  	req, err := NewRequest("GET", ts.URL, nil)
  3679  	if err != nil {
  3680  		t.Fatal(err)
  3681  	}
  3682  	ctx := context.WithValue(context.Background(), "some-key", "some-value")
  3683  	res, err := c.Do(req.WithContext(ctx))
  3684  	if err != nil {
  3685  		t.Fatal(err)
  3686  	}
  3687  	res.Body.Close()
  3688  	mu.Lock()
  3689  	if !gotReq {
  3690  		t.Error("didn't get request")
  3691  	}
  3692  	if receivedContext != ctx {
  3693  		t.Error("didn't receive correct context")
  3694  	}
  3695  }
  3696  
  3697  // Test for issue 8755
  3698  // Ensure that if a proxy returns an error, it is exposed by RoundTrip
  3699  func TestRoundTripReturnsProxyError(t *testing.T) {
  3700  	badProxy := func(*Request) (*url.URL, error) {
  3701  		return nil, errors.New("errorMessage")
  3702  	}
  3703  
  3704  	tr := &Transport{Proxy: badProxy}
  3705  
  3706  	req, _ := NewRequest("GET", "http://example.com", nil)
  3707  
  3708  	_, err := tr.RoundTrip(req)
  3709  
  3710  	if err == nil {
  3711  		t.Error("Expected proxy error to be returned by RoundTrip")
  3712  	}
  3713  }
  3714  
  3715  // tests that putting an idle conn after a call to CloseIdleConns does return it
  3716  func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
  3717  	tr := &Transport{}
  3718  	wantIdle := func(when string, n int) bool {
  3719  		got := tr.IdleConnCountForTesting("http", "example.com") // key used by PutIdleTestConn
  3720  		if got == n {
  3721  			return true
  3722  		}
  3723  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  3724  		return false
  3725  	}
  3726  	wantIdle("start", 0)
  3727  	if !tr.PutIdleTestConn("http", "example.com") {
  3728  		t.Fatal("put failed")
  3729  	}
  3730  	if !tr.PutIdleTestConn("http", "example.com") {
  3731  		t.Fatal("second put failed")
  3732  	}
  3733  	wantIdle("after put", 2)
  3734  	tr.CloseIdleConnections()
  3735  	if !tr.IsIdleForTesting() {
  3736  		t.Error("should be idle after CloseIdleConnections")
  3737  	}
  3738  	wantIdle("after close idle", 0)
  3739  	if tr.PutIdleTestConn("http", "example.com") {
  3740  		t.Fatal("put didn't fail")
  3741  	}
  3742  	wantIdle("after second put", 0)
  3743  
  3744  	tr.QueueForIdleConnForTesting() // should toggle the transport out of idle mode
  3745  	if tr.IsIdleForTesting() {
  3746  		t.Error("shouldn't be idle after QueueForIdleConnForTesting")
  3747  	}
  3748  	if !tr.PutIdleTestConn("http", "example.com") {
  3749  		t.Fatal("after re-activation")
  3750  	}
  3751  	wantIdle("after final put", 1)
  3752  }
  3753  
  3754  // Test for issue 34282
  3755  // Ensure that getConn doesn't call the GotConn trace hook on a HTTP/2 idle conn
  3756  func TestTransportTraceGotConnH2IdleConns(t *testing.T) {
  3757  	tr := &Transport{}
  3758  	wantIdle := func(when string, n int) bool {
  3759  		got := tr.IdleConnCountForTesting("https", "example.com:443") // key used by PutIdleTestConnH2
  3760  		if got == n {
  3761  			return true
  3762  		}
  3763  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  3764  		return false
  3765  	}
  3766  	wantIdle("start", 0)
  3767  	alt := funcRoundTripper(func() {})
  3768  	if !tr.PutIdleTestConnH2("https", "example.com:443", alt) {
  3769  		t.Fatal("put failed")
  3770  	}
  3771  	wantIdle("after put", 1)
  3772  	ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  3773  		GotConn: func(httptrace.GotConnInfo) {
  3774  			// tr.getConn should leave it for the HTTP/2 alt to call GotConn.
  3775  			t.Error("GotConn called")
  3776  		},
  3777  	})
  3778  	req, _ := NewRequestWithContext(ctx, MethodGet, "https://example.com", nil)
  3779  	_, err := tr.RoundTrip(req)
  3780  	if err != errFakeRoundTrip {
  3781  		t.Errorf("got error: %v; want %q", err, errFakeRoundTrip)
  3782  	}
  3783  	wantIdle("after round trip", 1)
  3784  }
  3785  
  3786  func TestTransportRemovesH2ConnsAfterIdle(t *testing.T) {
  3787  	if testing.Short() {
  3788  		t.Skip("skipping in short mode")
  3789  	}
  3790  
  3791  	trFunc := func(tr *Transport) {
  3792  		tr.MaxConnsPerHost = 1
  3793  		tr.MaxIdleConnsPerHost = 1
  3794  		tr.IdleConnTimeout = 10 * time.Millisecond
  3795  	}
  3796  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), trFunc)
  3797  	defer cst.close()
  3798  
  3799  	if _, err := cst.c.Get(cst.ts.URL); err != nil {
  3800  		t.Fatalf("got error: %s", err)
  3801  	}
  3802  
  3803  	time.Sleep(100 * time.Millisecond)
  3804  	got := make(chan error)
  3805  	go func() {
  3806  		if _, err := cst.c.Get(cst.ts.URL); err != nil {
  3807  			got <- err
  3808  		}
  3809  		close(got)
  3810  	}()
  3811  
  3812  	timeout := time.NewTimer(5 * time.Second)
  3813  	defer timeout.Stop()
  3814  	select {
  3815  	case err := <-got:
  3816  		if err != nil {
  3817  			t.Fatalf("got error: %s", err)
  3818  		}
  3819  	case <-timeout.C:
  3820  		t.Fatal("request never completed")
  3821  	}
  3822  }
  3823  
  3824  // This tests that a client requesting a content range won't also
  3825  // implicitly ask for gzip support. If they want that, they need to do it
  3826  // on their own.
  3827  // golang.org/issue/8923
  3828  func TestTransportRangeAndGzip(t *testing.T) {
  3829  	defer afterTest(t)
  3830  	reqc := make(chan *Request, 1)
  3831  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3832  		reqc <- r
  3833  	}))
  3834  	defer ts.Close()
  3835  	c := ts.Client()
  3836  
  3837  	req, _ := NewRequest("GET", ts.URL, nil)
  3838  	req.Header.Set("Range", "bytes=7-11")
  3839  	res, err := c.Do(req)
  3840  	if err != nil {
  3841  		t.Fatal(err)
  3842  	}
  3843  
  3844  	select {
  3845  	case r := <-reqc:
  3846  		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  3847  			t.Error("Transport advertised gzip support in the Accept header")
  3848  		}
  3849  		if r.Header.Get("Range") == "" {
  3850  			t.Error("no Range in request")
  3851  		}
  3852  	case <-time.After(10 * time.Second):
  3853  		t.Fatal("timeout")
  3854  	}
  3855  	res.Body.Close()
  3856  }
  3857  
  3858  // Test for issue 10474
  3859  func TestTransportResponseCancelRace(t *testing.T) {
  3860  	defer afterTest(t)
  3861  
  3862  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3863  		// important that this response has a body.
  3864  		var b [1024]byte
  3865  		w.Write(b[:])
  3866  	}))
  3867  	defer ts.Close()
  3868  	tr := ts.Client().Transport.(*Transport)
  3869  
  3870  	req, err := NewRequest("GET", ts.URL, nil)
  3871  	if err != nil {
  3872  		t.Fatal(err)
  3873  	}
  3874  	res, err := tr.RoundTrip(req)
  3875  	if err != nil {
  3876  		t.Fatal(err)
  3877  	}
  3878  	// If we do an early close, Transport just throws the connection away and
  3879  	// doesn't reuse it. In order to trigger the bug, it has to reuse the connection
  3880  	// so read the body
  3881  	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
  3882  		t.Fatal(err)
  3883  	}
  3884  
  3885  	req2, err := NewRequest("GET", ts.URL, nil)
  3886  	if err != nil {
  3887  		t.Fatal(err)
  3888  	}
  3889  	tr.CancelRequest(req)
  3890  	res, err = tr.RoundTrip(req2)
  3891  	if err != nil {
  3892  		t.Fatal(err)
  3893  	}
  3894  	res.Body.Close()
  3895  }
  3896  
  3897  // Test for issue 19248: Content-Encoding's value is case insensitive.
  3898  func TestTransportContentEncodingCaseInsensitive(t *testing.T) {
  3899  	setParallel(t)
  3900  	defer afterTest(t)
  3901  	for _, ce := range []string{"gzip", "GZIP"} {
  3902  		ce := ce
  3903  		t.Run(ce, func(t *testing.T) {
  3904  			const encodedString = "Hello Gopher"
  3905  			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3906  				w.Header().Set("Content-Encoding", ce)
  3907  				gz := gzip.NewWriter(w)
  3908  				gz.Write([]byte(encodedString))
  3909  				gz.Close()
  3910  			}))
  3911  			defer ts.Close()
  3912  
  3913  			res, err := ts.Client().Get(ts.URL)
  3914  			if err != nil {
  3915  				t.Fatal(err)
  3916  			}
  3917  
  3918  			body, err := ioutil.ReadAll(res.Body)
  3919  			res.Body.Close()
  3920  			if err != nil {
  3921  				t.Fatal(err)
  3922  			}
  3923  
  3924  			if string(body) != encodedString {
  3925  				t.Fatalf("Expected body %q, got: %q\n", encodedString, string(body))
  3926  			}
  3927  		})
  3928  	}
  3929  }
  3930  
  3931  func TestTransportDialCancelRace(t *testing.T) {
  3932  	defer afterTest(t)
  3933  
  3934  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  3935  	defer ts.Close()
  3936  	tr := ts.Client().Transport.(*Transport)
  3937  
  3938  	req, err := NewRequest("GET", ts.URL, nil)
  3939  	if err != nil {
  3940  		t.Fatal(err)
  3941  	}
  3942  	SetEnterRoundTripHook(func() {
  3943  		tr.CancelRequest(req)
  3944  	})
  3945  	defer SetEnterRoundTripHook(nil)
  3946  	res, err := tr.RoundTrip(req)
  3947  	if err != ExportErrRequestCanceled {
  3948  		t.Errorf("expected canceled request error; got %v", err)
  3949  		if err == nil {
  3950  			res.Body.Close()
  3951  		}
  3952  	}
  3953  }
  3954  
  3955  // logWritesConn is a net.Conn that logs each Write call to writes
  3956  // and then proxies to w.
  3957  // It proxies Read calls to a reader it receives from rch.
  3958  type logWritesConn struct {
  3959  	net.Conn // nil. crash on use.
  3960  
  3961  	w io.Writer
  3962  
  3963  	rch <-chan io.Reader
  3964  	r   io.Reader // nil until received by rch
  3965  
  3966  	mu     sync.Mutex
  3967  	writes []string
  3968  }
  3969  
  3970  func (c *logWritesConn) Write(p []byte) (n int, err error) {
  3971  	c.mu.Lock()
  3972  	defer c.mu.Unlock()
  3973  	c.writes = append(c.writes, string(p))
  3974  	return c.w.Write(p)
  3975  }
  3976  
  3977  func (c *logWritesConn) Read(p []byte) (n int, err error) {
  3978  	if c.r == nil {
  3979  		c.r = <-c.rch
  3980  	}
  3981  	return c.r.Read(p)
  3982  }
  3983  
  3984  func (c *logWritesConn) Close() error { return nil }
  3985  
  3986  // Issue 6574
  3987  func TestTransportFlushesBodyChunks(t *testing.T) {
  3988  	defer afterTest(t)
  3989  	resBody := make(chan io.Reader, 1)
  3990  	connr, connw := io.Pipe() // connection pipe pair
  3991  	lw := &logWritesConn{
  3992  		rch: resBody,
  3993  		w:   connw,
  3994  	}
  3995  	tr := &Transport{
  3996  		Dial: func(network, addr string) (net.Conn, error) {
  3997  			return lw, nil
  3998  		},
  3999  	}
  4000  	bodyr, bodyw := io.Pipe() // body pipe pair
  4001  	go func() {
  4002  		defer bodyw.Close()
  4003  		for i := 0; i < 3; i++ {
  4004  			fmt.Fprintf(bodyw, "num%d\n", i)
  4005  		}
  4006  	}()
  4007  	resc := make(chan *Response)
  4008  	go func() {
  4009  		req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
  4010  		req.Header.Set("User-Agent", "x") // known value for test
  4011  		res, err := tr.RoundTrip(req)
  4012  		if err != nil {
  4013  			t.Errorf("RoundTrip: %v", err)
  4014  			close(resc)
  4015  			return
  4016  		}
  4017  		resc <- res
  4018  
  4019  	}()
  4020  	// Fully consume the request before checking the Write log vs. want.
  4021  	req, err := ReadRequest(bufio.NewReader(connr))
  4022  	if err != nil {
  4023  		t.Fatal(err)
  4024  	}
  4025  	io.Copy(ioutil.Discard, req.Body)
  4026  
  4027  	// Unblock the transport's roundTrip goroutine.
  4028  	resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
  4029  	res, ok := <-resc
  4030  	if !ok {
  4031  		return
  4032  	}
  4033  	defer res.Body.Close()
  4034  
  4035  	want := []string{
  4036  		"POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n",
  4037  		"5\r\nnum0\n\r\n",
  4038  		"5\r\nnum1\n\r\n",
  4039  		"5\r\nnum2\n\r\n",
  4040  		"0\r\n\r\n",
  4041  	}
  4042  	if !reflect.DeepEqual(lw.writes, want) {
  4043  		t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
  4044  	}
  4045  }
  4046  
  4047  // Issue 22088: flush Transport request headers if we're not sure the body won't block on read.
  4048  func TestTransportFlushesRequestHeader(t *testing.T) {
  4049  	defer afterTest(t)
  4050  	gotReq := make(chan struct{})
  4051  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4052  		close(gotReq)
  4053  	}))
  4054  	defer cst.close()
  4055  
  4056  	pr, pw := io.Pipe()
  4057  	req, err := NewRequest("POST", cst.ts.URL, pr)
  4058  	if err != nil {
  4059  		t.Fatal(err)
  4060  	}
  4061  	gotRes := make(chan struct{})
  4062  	go func() {
  4063  		defer close(gotRes)
  4064  		res, err := cst.tr.RoundTrip(req)
  4065  		if err != nil {
  4066  			t.Error(err)
  4067  			return
  4068  		}
  4069  		res.Body.Close()
  4070  	}()
  4071  
  4072  	select {
  4073  	case <-gotReq:
  4074  		pw.Close()
  4075  	case <-time.After(5 * time.Second):
  4076  		t.Fatal("timeout waiting for handler to get request")
  4077  	}
  4078  	<-gotRes
  4079  }
  4080  
  4081  // Issue 11745.
  4082  func TestTransportPrefersResponseOverWriteError(t *testing.T) {
  4083  	if testing.Short() {
  4084  		t.Skip("skipping in short mode")
  4085  	}
  4086  	defer afterTest(t)
  4087  	const contentLengthLimit = 1024 * 1024 // 1MB
  4088  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4089  		if r.ContentLength >= contentLengthLimit {
  4090  			w.WriteHeader(StatusBadRequest)
  4091  			r.Body.Close()
  4092  			return
  4093  		}
  4094  		w.WriteHeader(StatusOK)
  4095  	}))
  4096  	defer ts.Close()
  4097  	c := ts.Client()
  4098  
  4099  	fail := 0
  4100  	count := 100
  4101  	bigBody := strings.Repeat("a", contentLengthLimit*2)
  4102  	for i := 0; i < count; i++ {
  4103  		req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
  4104  		if err != nil {
  4105  			t.Fatal(err)
  4106  		}
  4107  		resp, err := c.Do(req)
  4108  		if err != nil {
  4109  			fail++
  4110  			t.Logf("%d = %#v", i, err)
  4111  			if ue, ok := err.(*url.Error); ok {
  4112  				t.Logf("urlErr = %#v", ue.Err)
  4113  				if ne, ok := ue.Err.(*net.OpError); ok {
  4114  					t.Logf("netOpError = %#v", ne.Err)
  4115  				}
  4116  			}
  4117  		} else {
  4118  			resp.Body.Close()
  4119  			if resp.StatusCode != 400 {
  4120  				t.Errorf("Expected status code 400, got %v", resp.Status)
  4121  			}
  4122  		}
  4123  	}
  4124  	if fail > 0 {
  4125  		t.Errorf("Failed %v out of %v\n", fail, count)
  4126  	}
  4127  }
  4128  
  4129  func TestTransportAutomaticHTTP2(t *testing.T) {
  4130  	testTransportAutoHTTP(t, &Transport{}, true)
  4131  }
  4132  
  4133  func TestTransportAutomaticHTTP2_DialerAndTLSConfigSupportsHTTP2AndTLSConfig(t *testing.T) {
  4134  	testTransportAutoHTTP(t, &Transport{
  4135  		ForceAttemptHTTP2: true,
  4136  		TLSClientConfig:   new(tls.Config),
  4137  	}, true)
  4138  }
  4139  
  4140  // golang.org/issue/14391: also check DefaultTransport
  4141  func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
  4142  	testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
  4143  }
  4144  
  4145  func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
  4146  	testTransportAutoHTTP(t, &Transport{
  4147  		TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
  4148  	}, false)
  4149  }
  4150  
  4151  func TestTransportAutomaticHTTP2_TLSConfig(t *testing.T) {
  4152  	testTransportAutoHTTP(t, &Transport{
  4153  		TLSClientConfig: new(tls.Config),
  4154  	}, false)
  4155  }
  4156  
  4157  func TestTransportAutomaticHTTP2_ExpectContinueTimeout(t *testing.T) {
  4158  	testTransportAutoHTTP(t, &Transport{
  4159  		ExpectContinueTimeout: 1 * time.Second,
  4160  	}, true)
  4161  }
  4162  
  4163  func TestTransportAutomaticHTTP2_Dial(t *testing.T) {
  4164  	var d net.Dialer
  4165  	testTransportAutoHTTP(t, &Transport{
  4166  		Dial: d.Dial,
  4167  	}, false)
  4168  }
  4169  
  4170  func TestTransportAutomaticHTTP2_DialContext(t *testing.T) {
  4171  	var d net.Dialer
  4172  	testTransportAutoHTTP(t, &Transport{
  4173  		DialContext: d.DialContext,
  4174  	}, false)
  4175  }
  4176  
  4177  func TestTransportAutomaticHTTP2_DialTLS(t *testing.T) {
  4178  	testTransportAutoHTTP(t, &Transport{
  4179  		DialTLS: func(network, addr string) (net.Conn, error) {
  4180  			panic("unused")
  4181  		},
  4182  	}, false)
  4183  }
  4184  
  4185  func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) {
  4186  	CondSkipHTTP2(t)
  4187  	_, err := tr.RoundTrip(new(Request))
  4188  	if err == nil {
  4189  		t.Error("expected error from RoundTrip")
  4190  	}
  4191  	if reg := tr.TLSNextProto["h2"] != nil; reg != wantH2 {
  4192  		t.Errorf("HTTP/2 registered = %v; want %v", reg, wantH2)
  4193  	}
  4194  }
  4195  
  4196  // Issue 13633: there was a race where we returned bodyless responses
  4197  // to callers before recycling the persistent connection, which meant
  4198  // a client doing two subsequent requests could end up on different
  4199  // connections. It's somewhat harmless but enough tests assume it's
  4200  // not true in order to test other things that it's worth fixing.
  4201  // Plus it's nice to be consistent and not have timing-dependent
  4202  // behavior.
  4203  func TestTransportReuseConnEmptyResponseBody(t *testing.T) {
  4204  	defer afterTest(t)
  4205  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4206  		w.Header().Set("X-Addr", r.RemoteAddr)
  4207  		// Empty response body.
  4208  	}))
  4209  	defer cst.close()
  4210  	n := 100
  4211  	if testing.Short() {
  4212  		n = 10
  4213  	}
  4214  	var firstAddr string
  4215  	for i := 0; i < n; i++ {
  4216  		res, err := cst.c.Get(cst.ts.URL)
  4217  		if err != nil {
  4218  			log.Fatal(err)
  4219  		}
  4220  		addr := res.Header.Get("X-Addr")
  4221  		if i == 0 {
  4222  			firstAddr = addr
  4223  		} else if addr != firstAddr {
  4224  			t.Fatalf("On request %d, addr %q != original addr %q", i+1, addr, firstAddr)
  4225  		}
  4226  		res.Body.Close()
  4227  	}
  4228  }
  4229  
  4230  // Issue 13839
  4231  func TestNoCrashReturningTransportAltConn(t *testing.T) {
  4232  	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
  4233  	if err != nil {
  4234  		t.Fatal(err)
  4235  	}
  4236  	ln := newLocalListener(t)
  4237  	defer ln.Close()
  4238  
  4239  	var wg sync.WaitGroup
  4240  	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  4241  	defer SetPendingDialHooks(nil, nil)
  4242  
  4243  	testDone := make(chan struct{})
  4244  	defer close(testDone)
  4245  	go func() {
  4246  		tln := tls.NewListener(ln, &tls.Config{
  4247  			NextProtos:   []string{"foo"},
  4248  			Certificates: []tls.Certificate{cert},
  4249  		})
  4250  		sc, err := tln.Accept()
  4251  		if err != nil {
  4252  			t.Error(err)
  4253  			return
  4254  		}
  4255  		if err := sc.(*tls.Conn).Handshake(); err != nil {
  4256  			t.Error(err)
  4257  			return
  4258  		}
  4259  		<-testDone
  4260  		sc.Close()
  4261  	}()
  4262  
  4263  	addr := ln.Addr().String()
  4264  
  4265  	req, _ := NewRequest("GET", "https://fake.tld/", nil)
  4266  	cancel := make(chan struct{})
  4267  	req.Cancel = cancel
  4268  
  4269  	doReturned := make(chan bool, 1)
  4270  	madeRoundTripper := make(chan bool, 1)
  4271  
  4272  	tr := &Transport{
  4273  		DisableKeepAlives: true,
  4274  		TLSNextProto: map[string]func(string, *tls.Conn) RoundTripper{
  4275  			"foo": func(authority string, c *tls.Conn) RoundTripper {
  4276  				madeRoundTripper <- true
  4277  				return funcRoundTripper(func() {
  4278  					t.Error("foo RoundTripper should not be called")
  4279  				})
  4280  			},
  4281  		},
  4282  		Dial: func(_, _ string) (net.Conn, error) {
  4283  			panic("shouldn't be called")
  4284  		},
  4285  		DialTLS: func(_, _ string) (net.Conn, error) {
  4286  			tc, err := tls.Dial("tcp", addr, &tls.Config{
  4287  				InsecureSkipVerify: true,
  4288  				NextProtos:         []string{"foo"},
  4289  			})
  4290  			if err != nil {
  4291  				return nil, err
  4292  			}
  4293  			if err := tc.Handshake(); err != nil {
  4294  				return nil, err
  4295  			}
  4296  			close(cancel)
  4297  			<-doReturned
  4298  			return tc, nil
  4299  		},
  4300  	}
  4301  	c := &Client{Transport: tr}
  4302  
  4303  	_, err = c.Do(req)
  4304  	if ue, ok := err.(*url.Error); !ok || ue.Err != ExportErrRequestCanceledConn {
  4305  		t.Fatalf("Do error = %v; want url.Error with errRequestCanceledConn", err)
  4306  	}
  4307  
  4308  	doReturned <- true
  4309  	<-madeRoundTripper
  4310  	wg.Wait()
  4311  }
  4312  
  4313  func TestTransportReuseConnection_Gzip_Chunked(t *testing.T) {
  4314  	testTransportReuseConnection_Gzip(t, true)
  4315  }
  4316  
  4317  func TestTransportReuseConnection_Gzip_ContentLength(t *testing.T) {
  4318  	testTransportReuseConnection_Gzip(t, false)
  4319  }
  4320  
  4321  // Make sure we re-use underlying TCP connection for gzipped responses too.
  4322  func testTransportReuseConnection_Gzip(t *testing.T, chunked bool) {
  4323  	setParallel(t)
  4324  	defer afterTest(t)
  4325  	addr := make(chan string, 2)
  4326  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4327  		addr <- r.RemoteAddr
  4328  		w.Header().Set("Content-Encoding", "gzip")
  4329  		if chunked {
  4330  			w.(Flusher).Flush()
  4331  		}
  4332  		w.Write(rgz) // arbitrary gzip response
  4333  	}))
  4334  	defer ts.Close()
  4335  	c := ts.Client()
  4336  
  4337  	for i := 0; i < 2; i++ {
  4338  		res, err := c.Get(ts.URL)
  4339  		if err != nil {
  4340  			t.Fatal(err)
  4341  		}
  4342  		buf := make([]byte, len(rgz))
  4343  		if n, err := io.ReadFull(res.Body, buf); err != nil {
  4344  			t.Errorf("%d. ReadFull = %v, %v", i, n, err)
  4345  		}
  4346  		// Note: no res.Body.Close call. It should work without it,
  4347  		// since the flate.Reader's internal buffering will hit EOF
  4348  		// and that should be sufficient.
  4349  	}
  4350  	a1, a2 := <-addr, <-addr
  4351  	if a1 != a2 {
  4352  		t.Fatalf("didn't reuse connection")
  4353  	}
  4354  }
  4355  
  4356  func TestTransportResponseHeaderLength(t *testing.T) {
  4357  	setParallel(t)
  4358  	defer afterTest(t)
  4359  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4360  		if r.URL.Path == "/long" {
  4361  			w.Header().Set("Long", strings.Repeat("a", 1<<20))
  4362  		}
  4363  	}))
  4364  	defer ts.Close()
  4365  	c := ts.Client()
  4366  	c.Transport.(*Transport).MaxResponseHeaderBytes = 512 << 10
  4367  
  4368  	if res, err := c.Get(ts.URL); err != nil {
  4369  		t.Fatal(err)
  4370  	} else {
  4371  		res.Body.Close()
  4372  	}
  4373  
  4374  	res, err := c.Get(ts.URL + "/long")
  4375  	if err == nil {
  4376  		defer res.Body.Close()
  4377  		var n int64
  4378  		for k, vv := range res.Header {
  4379  			for _, v := range vv {
  4380  				n += int64(len(k)) + int64(len(v))
  4381  			}
  4382  		}
  4383  		t.Fatalf("Unexpected success. Got %v and %d bytes of response headers", res.Status, n)
  4384  	}
  4385  	if want := "server response headers exceeded 524288 bytes"; !strings.Contains(err.Error(), want) {
  4386  		t.Errorf("got error: %v; want %q", err, want)
  4387  	}
  4388  }
  4389  
  4390  func TestTransportEventTrace(t *testing.T)    { testTransportEventTrace(t, h1Mode, false) }
  4391  func TestTransportEventTrace_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, false) }
  4392  
  4393  // test a non-nil httptrace.ClientTrace but with all hooks set to zero.
  4394  func TestTransportEventTrace_NoHooks(t *testing.T)    { testTransportEventTrace(t, h1Mode, true) }
  4395  func TestTransportEventTrace_NoHooks_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, true) }
  4396  
  4397  func testTransportEventTrace(t *testing.T, h2 bool, noHooks bool) {
  4398  	defer afterTest(t)
  4399  	const resBody = "some body"
  4400  	gotWroteReqEvent := make(chan struct{}, 500)
  4401  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  4402  		if r.Method == "GET" {
  4403  			// Do nothing for the second request.
  4404  			return
  4405  		}
  4406  		if _, err := ioutil.ReadAll(r.Body); err != nil {
  4407  			t.Error(err)
  4408  		}
  4409  		if !noHooks {
  4410  			select {
  4411  			case <-gotWroteReqEvent:
  4412  			case <-time.After(5 * time.Second):
  4413  				t.Error("timeout waiting for WroteRequest event")
  4414  			}
  4415  		}
  4416  		io.WriteString(w, resBody)
  4417  	}))
  4418  	defer cst.close()
  4419  
  4420  	cst.tr.ExpectContinueTimeout = 1 * time.Second
  4421  
  4422  	var mu sync.Mutex // guards buf
  4423  	var buf bytes.Buffer
  4424  	logf := func(format string, args ...interface{}) {
  4425  		mu.Lock()
  4426  		defer mu.Unlock()
  4427  		fmt.Fprintf(&buf, format, args...)
  4428  		buf.WriteByte('\n')
  4429  	}
  4430  
  4431  	addrStr := cst.ts.Listener.Addr().String()
  4432  	ip, port, err := net.SplitHostPort(addrStr)
  4433  	if err != nil {
  4434  		t.Fatal(err)
  4435  	}
  4436  
  4437  	// Install a fake DNS server.
  4438  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, network, host string) ([]net.IPAddr, error) {
  4439  		if host != "dns-is-faked.golang" {
  4440  			t.Errorf("unexpected DNS host lookup for %q/%q", network, host)
  4441  			return nil, nil
  4442  		}
  4443  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  4444  	})
  4445  
  4446  	body := "some body"
  4447  	req, _ := NewRequest("POST", cst.scheme()+"://dns-is-faked.golang:"+port, strings.NewReader(body))
  4448  	req.Header["X-Foo-Multiple-Vals"] = []string{"bar", "baz"}
  4449  	trace := &httptrace.ClientTrace{
  4450  		GetConn:              func(hostPort string) { logf("Getting conn for %v ...", hostPort) },
  4451  		GotConn:              func(ci httptrace.GotConnInfo) { logf("got conn: %+v", ci) },
  4452  		GotFirstResponseByte: func() { logf("first response byte") },
  4453  		PutIdleConn:          func(err error) { logf("PutIdleConn = %v", err) },
  4454  		DNSStart:             func(e httptrace.DNSStartInfo) { logf("DNS start: %+v", e) },
  4455  		DNSDone:              func(e httptrace.DNSDoneInfo) { logf("DNS done: %+v", e) },
  4456  		ConnectStart:         func(network, addr string) { logf("ConnectStart: Connecting to %s %s ...", network, addr) },
  4457  		ConnectDone: func(network, addr string, err error) {
  4458  			if err != nil {
  4459  				t.Errorf("ConnectDone: %v", err)
  4460  			}
  4461  			logf("ConnectDone: connected to %s %s = %v", network, addr, err)
  4462  		},
  4463  		WroteHeaderField: func(key string, value []string) {
  4464  			logf("WroteHeaderField: %s: %v", key, value)
  4465  		},
  4466  		WroteHeaders: func() {
  4467  			logf("WroteHeaders")
  4468  		},
  4469  		Wait100Continue: func() { logf("Wait100Continue") },
  4470  		Got100Continue:  func() { logf("Got100Continue") },
  4471  		WroteRequest: func(e httptrace.WroteRequestInfo) {
  4472  			logf("WroteRequest: %+v", e)
  4473  			gotWroteReqEvent <- struct{}{}
  4474  		},
  4475  	}
  4476  	if h2 {
  4477  		trace.TLSHandshakeStart = func() { logf("tls handshake start") }
  4478  		trace.TLSHandshakeDone = func(s tls.ConnectionState, err error) {
  4479  			logf("tls handshake done. ConnectionState = %v \n err = %v", s, err)
  4480  		}
  4481  	}
  4482  	if noHooks {
  4483  		// zero out all func pointers, trying to get some path to crash
  4484  		*trace = httptrace.ClientTrace{}
  4485  	}
  4486  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  4487  
  4488  	req.Header.Set("Expect", "100-continue")
  4489  	res, err := cst.c.Do(req)
  4490  	if err != nil {
  4491  		t.Fatal(err)
  4492  	}
  4493  	logf("got roundtrip.response")
  4494  	slurp, err := ioutil.ReadAll(res.Body)
  4495  	if err != nil {
  4496  		t.Fatal(err)
  4497  	}
  4498  	logf("consumed body")
  4499  	if string(slurp) != resBody || res.StatusCode != 200 {
  4500  		t.Fatalf("Got %q, %v; want %q, 200 OK", slurp, res.Status, resBody)
  4501  	}
  4502  	res.Body.Close()
  4503  
  4504  	if noHooks {
  4505  		// Done at this point. Just testing a full HTTP
  4506  		// requests can happen with a trace pointing to a zero
  4507  		// ClientTrace, full of nil func pointers.
  4508  		return
  4509  	}
  4510  
  4511  	mu.Lock()
  4512  	got := buf.String()
  4513  	mu.Unlock()
  4514  
  4515  	wantOnce := func(sub string) {
  4516  		if strings.Count(got, sub) != 1 {
  4517  			t.Errorf("expected substring %q exactly once in output.", sub)
  4518  		}
  4519  	}
  4520  	wantOnceOrMore := func(sub string) {
  4521  		if strings.Count(got, sub) == 0 {
  4522  			t.Errorf("expected substring %q at least once in output.", sub)
  4523  		}
  4524  	}
  4525  	wantOnce("Getting conn for dns-is-faked.golang:" + port)
  4526  	wantOnce("DNS start: {Host:dns-is-faked.golang}")
  4527  	wantOnce("DNS done: {Addrs:[{IP:" + ip + " Zone:}] Err:<nil> Coalesced:false}")
  4528  	wantOnce("got conn: {")
  4529  	wantOnceOrMore("Connecting to tcp " + addrStr)
  4530  	wantOnceOrMore("connected to tcp " + addrStr + " = <nil>")
  4531  	wantOnce("Reused:false WasIdle:false IdleTime:0s")
  4532  	wantOnce("first response byte")
  4533  	if h2 {
  4534  		wantOnce("tls handshake start")
  4535  		wantOnce("tls handshake done")
  4536  	} else {
  4537  		wantOnce("PutIdleConn = <nil>")
  4538  		wantOnce("WroteHeaderField: User-Agent: [Go-http-client/1.1]")
  4539  		// TODO(meirf): issue 19761. Make these agnostic to h1/h2. (These are not h1 specific, but the
  4540  		// WroteHeaderField hook is not yet implemented in h2.)
  4541  		wantOnce(fmt.Sprintf("WroteHeaderField: Host: [dns-is-faked.golang:%s]", port))
  4542  		wantOnce(fmt.Sprintf("WroteHeaderField: Content-Length: [%d]", len(body)))
  4543  		wantOnce("WroteHeaderField: X-Foo-Multiple-Vals: [bar baz]")
  4544  		wantOnce("WroteHeaderField: Accept-Encoding: [gzip]")
  4545  	}
  4546  	wantOnce("WroteHeaders")
  4547  	wantOnce("Wait100Continue")
  4548  	wantOnce("Got100Continue")
  4549  	wantOnce("WroteRequest: {Err:<nil>}")
  4550  	if strings.Contains(got, " to udp ") {
  4551  		t.Errorf("should not see UDP (DNS) connections")
  4552  	}
  4553  	if t.Failed() {
  4554  		t.Errorf("Output:\n%s", got)
  4555  	}
  4556  
  4557  	// And do a second request:
  4558  	req, _ = NewRequest("GET", cst.scheme()+"://dns-is-faked.golang:"+port, nil)
  4559  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  4560  	res, err = cst.c.Do(req)
  4561  	if err != nil {
  4562  		t.Fatal(err)
  4563  	}
  4564  	if res.StatusCode != 200 {
  4565  		t.Fatal(res.Status)
  4566  	}
  4567  	res.Body.Close()
  4568  
  4569  	mu.Lock()
  4570  	got = buf.String()
  4571  	mu.Unlock()
  4572  
  4573  	sub := "Getting conn for dns-is-faked.golang:"
  4574  	if gotn, want := strings.Count(got, sub), 2; gotn != want {
  4575  		t.Errorf("substring %q appeared %d times; want %d. Log:\n%s", sub, gotn, want, got)
  4576  	}
  4577  
  4578  }
  4579  
  4580  func TestTransportEventTraceTLSVerify(t *testing.T) {
  4581  	var mu sync.Mutex
  4582  	var buf bytes.Buffer
  4583  	logf := func(format string, args ...interface{}) {
  4584  		mu.Lock()
  4585  		defer mu.Unlock()
  4586  		fmt.Fprintf(&buf, format, args...)
  4587  		buf.WriteByte('\n')
  4588  	}
  4589  
  4590  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4591  		t.Error("Unexpected request")
  4592  	}))
  4593  	defer ts.Close()
  4594  	ts.Config.ErrorLog = log.New(funcWriter(func(p []byte) (int, error) {
  4595  		logf("%s", p)
  4596  		return len(p), nil
  4597  	}), "", 0)
  4598  
  4599  	certpool := x509.NewCertPool()
  4600  	certpool.AddCert(ts.Certificate())
  4601  
  4602  	c := &Client{Transport: &Transport{
  4603  		TLSClientConfig: &tls.Config{
  4604  			ServerName: "dns-is-faked.golang",
  4605  			RootCAs:    certpool,
  4606  		},
  4607  	}}
  4608  
  4609  	trace := &httptrace.ClientTrace{
  4610  		TLSHandshakeStart: func() { logf("TLSHandshakeStart") },
  4611  		TLSHandshakeDone: func(s tls.ConnectionState, err error) {
  4612  			logf("TLSHandshakeDone: ConnectionState = %v \n err = %v", s, err)
  4613  		},
  4614  	}
  4615  
  4616  	req, _ := NewRequest("GET", ts.URL, nil)
  4617  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  4618  	_, err := c.Do(req)
  4619  	if err == nil {
  4620  		t.Error("Expected request to fail TLS verification")
  4621  	}
  4622  
  4623  	mu.Lock()
  4624  	got := buf.String()
  4625  	mu.Unlock()
  4626  
  4627  	wantOnce := func(sub string) {
  4628  		if strings.Count(got, sub) != 1 {
  4629  			t.Errorf("expected substring %q exactly once in output.", sub)
  4630  		}
  4631  	}
  4632  
  4633  	wantOnce("TLSHandshakeStart")
  4634  	wantOnce("TLSHandshakeDone")
  4635  	wantOnce("err = x509: certificate is valid for example.com")
  4636  
  4637  	if t.Failed() {
  4638  		t.Errorf("Output:\n%s", got)
  4639  	}
  4640  }
  4641  
  4642  var (
  4643  	isDNSHijackedOnce sync.Once
  4644  	isDNSHijacked     bool
  4645  )
  4646  
  4647  func skipIfDNSHijacked(t *testing.T) {
  4648  	// Skip this test if the user is using a shady/ISP
  4649  	// DNS server hijacking queries.
  4650  	// See issues 16732, 16716.
  4651  	isDNSHijackedOnce.Do(func() {
  4652  		addrs, _ := net.LookupHost("dns-should-not-resolve.golang")
  4653  		isDNSHijacked = len(addrs) != 0
  4654  	})
  4655  	if isDNSHijacked {
  4656  		t.Skip("skipping; test requires non-hijacking DNS server")
  4657  	}
  4658  }
  4659  
  4660  func TestTransportEventTraceRealDNS(t *testing.T) {
  4661  	skipIfDNSHijacked(t)
  4662  	defer afterTest(t)
  4663  	tr := &Transport{}
  4664  	defer tr.CloseIdleConnections()
  4665  	c := &Client{Transport: tr}
  4666  
  4667  	var mu sync.Mutex // guards buf
  4668  	var buf bytes.Buffer
  4669  	logf := func(format string, args ...interface{}) {
  4670  		mu.Lock()
  4671  		defer mu.Unlock()
  4672  		fmt.Fprintf(&buf, format, args...)
  4673  		buf.WriteByte('\n')
  4674  	}
  4675  
  4676  	req, _ := NewRequest("GET", "http://dns-should-not-resolve.golang:80", nil)
  4677  	trace := &httptrace.ClientTrace{
  4678  		DNSStart:     func(e httptrace.DNSStartInfo) { logf("DNSStart: %+v", e) },
  4679  		DNSDone:      func(e httptrace.DNSDoneInfo) { logf("DNSDone: %+v", e) },
  4680  		ConnectStart: func(network, addr string) { logf("ConnectStart: %s %s", network, addr) },
  4681  		ConnectDone:  func(network, addr string, err error) { logf("ConnectDone: %s %s %v", network, addr, err) },
  4682  	}
  4683  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  4684  
  4685  	resp, err := c.Do(req)
  4686  	if err == nil {
  4687  		resp.Body.Close()
  4688  		t.Fatal("expected error during DNS lookup")
  4689  	}
  4690  
  4691  	mu.Lock()
  4692  	got := buf.String()
  4693  	mu.Unlock()
  4694  
  4695  	wantSub := func(sub string) {
  4696  		if !strings.Contains(got, sub) {
  4697  			t.Errorf("expected substring %q in output.", sub)
  4698  		}
  4699  	}
  4700  	wantSub("DNSStart: {Host:dns-should-not-resolve.golang}")
  4701  	wantSub("DNSDone: {Addrs:[] Err:")
  4702  	if strings.Contains(got, "ConnectStart") || strings.Contains(got, "ConnectDone") {
  4703  		t.Errorf("should not see Connect events")
  4704  	}
  4705  	if t.Failed() {
  4706  		t.Errorf("Output:\n%s", got)
  4707  	}
  4708  }
  4709  
  4710  // Issue 14353: port can only contain digits.
  4711  func TestTransportRejectsAlphaPort(t *testing.T) {
  4712  	res, err := Get("http://dummy.tld:123foo/bar")
  4713  	if err == nil {
  4714  		res.Body.Close()
  4715  		t.Fatal("unexpected success")
  4716  	}
  4717  	ue, ok := err.(*url.Error)
  4718  	if !ok {
  4719  		t.Fatalf("got %#v; want *url.Error", err)
  4720  	}
  4721  	got := ue.Err.Error()
  4722  	want := `invalid port ":123foo" after host`
  4723  	if got != want {
  4724  		t.Errorf("got error %q; want %q", got, want)
  4725  	}
  4726  }
  4727  
  4728  // Test the httptrace.TLSHandshake{Start,Done} hooks with a https http1
  4729  // connections. The http2 test is done in TestTransportEventTrace_h2
  4730  func TestTLSHandshakeTrace(t *testing.T) {
  4731  	defer afterTest(t)
  4732  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  4733  	defer ts.Close()
  4734  
  4735  	var mu sync.Mutex
  4736  	var start, done bool
  4737  	trace := &httptrace.ClientTrace{
  4738  		TLSHandshakeStart: func() {
  4739  			mu.Lock()
  4740  			defer mu.Unlock()
  4741  			start = true
  4742  		},
  4743  		TLSHandshakeDone: func(s tls.ConnectionState, err error) {
  4744  			mu.Lock()
  4745  			defer mu.Unlock()
  4746  			done = true
  4747  			if err != nil {
  4748  				t.Fatal("Expected error to be nil but was:", err)
  4749  			}
  4750  		},
  4751  	}
  4752  
  4753  	c := ts.Client()
  4754  	req, err := NewRequest("GET", ts.URL, nil)
  4755  	if err != nil {
  4756  		t.Fatal("Unable to construct test request:", err)
  4757  	}
  4758  	req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
  4759  
  4760  	r, err := c.Do(req)
  4761  	if err != nil {
  4762  		t.Fatal("Unexpected error making request:", err)
  4763  	}
  4764  	r.Body.Close()
  4765  	mu.Lock()
  4766  	defer mu.Unlock()
  4767  	if !start {
  4768  		t.Fatal("Expected TLSHandshakeStart to be called, but wasn't")
  4769  	}
  4770  	if !done {
  4771  		t.Fatal("Expected TLSHandshakeDone to be called, but wasnt't")
  4772  	}
  4773  }
  4774  
  4775  func TestTransportMaxIdleConns(t *testing.T) {
  4776  	defer afterTest(t)
  4777  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4778  		// No body for convenience.
  4779  	}))
  4780  	defer ts.Close()
  4781  	c := ts.Client()
  4782  	tr := c.Transport.(*Transport)
  4783  	tr.MaxIdleConns = 4
  4784  
  4785  	ip, port, err := net.SplitHostPort(ts.Listener.Addr().String())
  4786  	if err != nil {
  4787  		t.Fatal(err)
  4788  	}
  4789  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, _, host string) ([]net.IPAddr, error) {
  4790  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  4791  	})
  4792  
  4793  	hitHost := func(n int) {
  4794  		req, _ := NewRequest("GET", fmt.Sprintf("http://host-%d.dns-is-faked.golang:"+port, n), nil)
  4795  		req = req.WithContext(ctx)
  4796  		res, err := c.Do(req)
  4797  		if err != nil {
  4798  			t.Fatal(err)
  4799  		}
  4800  		res.Body.Close()
  4801  	}
  4802  	for i := 0; i < 4; i++ {
  4803  		hitHost(i)
  4804  	}
  4805  	want := []string{
  4806  		"|http|host-0.dns-is-faked.golang:" + port,
  4807  		"|http|host-1.dns-is-faked.golang:" + port,
  4808  		"|http|host-2.dns-is-faked.golang:" + port,
  4809  		"|http|host-3.dns-is-faked.golang:" + port,
  4810  	}
  4811  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  4812  		t.Fatalf("idle conn keys mismatch.\n got: %q\nwant: %q\n", got, want)
  4813  	}
  4814  
  4815  	// Now hitting the 5th host should kick out the first host:
  4816  	hitHost(4)
  4817  	want = []string{
  4818  		"|http|host-1.dns-is-faked.golang:" + port,
  4819  		"|http|host-2.dns-is-faked.golang:" + port,
  4820  		"|http|host-3.dns-is-faked.golang:" + port,
  4821  		"|http|host-4.dns-is-faked.golang:" + port,
  4822  	}
  4823  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  4824  		t.Fatalf("idle conn keys mismatch after 5th host.\n got: %q\nwant: %q\n", got, want)
  4825  	}
  4826  }
  4827  
  4828  func TestTransportIdleConnTimeout_h1(t *testing.T) { testTransportIdleConnTimeout(t, h1Mode) }
  4829  func TestTransportIdleConnTimeout_h2(t *testing.T) { testTransportIdleConnTimeout(t, h2Mode) }
  4830  func testTransportIdleConnTimeout(t *testing.T, h2 bool) {
  4831  	if testing.Short() {
  4832  		t.Skip("skipping in short mode")
  4833  	}
  4834  	defer afterTest(t)
  4835  
  4836  	const timeout = 1 * time.Second
  4837  
  4838  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  4839  		// No body for convenience.
  4840  	}))
  4841  	defer cst.close()
  4842  	tr := cst.tr
  4843  	tr.IdleConnTimeout = timeout
  4844  	defer tr.CloseIdleConnections()
  4845  	c := &Client{Transport: tr}
  4846  
  4847  	idleConns := func() []string {
  4848  		if h2 {
  4849  			return tr.IdleConnStrsForTesting_h2()
  4850  		} else {
  4851  			return tr.IdleConnStrsForTesting()
  4852  		}
  4853  	}
  4854  
  4855  	var conn string
  4856  	doReq := func(n int) {
  4857  		req, _ := NewRequest("GET", cst.ts.URL, nil)
  4858  		req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  4859  			PutIdleConn: func(err error) {
  4860  				if err != nil {
  4861  					t.Errorf("failed to keep idle conn: %v", err)
  4862  				}
  4863  			},
  4864  		}))
  4865  		res, err := c.Do(req)
  4866  		if err != nil {
  4867  			t.Fatal(err)
  4868  		}
  4869  		res.Body.Close()
  4870  		conns := idleConns()
  4871  		if len(conns) != 1 {
  4872  			t.Fatalf("req %v: unexpected number of idle conns: %q", n, conns)
  4873  		}
  4874  		if conn == "" {
  4875  			conn = conns[0]
  4876  		}
  4877  		if conn != conns[0] {
  4878  			t.Fatalf("req %v: cached connection changed; expected the same one throughout the test", n)
  4879  		}
  4880  	}
  4881  	for i := 0; i < 3; i++ {
  4882  		doReq(i)
  4883  		time.Sleep(timeout / 2)
  4884  	}
  4885  	time.Sleep(timeout * 3 / 2)
  4886  	if got := idleConns(); len(got) != 0 {
  4887  		t.Errorf("idle conns = %q; want none", got)
  4888  	}
  4889  }
  4890  
  4891  // Issue 16208: Go 1.7 crashed after Transport.IdleConnTimeout if an
  4892  // HTTP/2 connection was established but its caller no longer
  4893  // wanted it. (Assuming the connection cache was enabled, which it is
  4894  // by default)
  4895  //
  4896  // This test reproduced the crash by setting the IdleConnTimeout low
  4897  // (to make the test reasonable) and then making a request which is
  4898  // canceled by the DialTLS hook, which then also waits to return the
  4899  // real connection until after the RoundTrip saw the error.  Then we
  4900  // know the successful tls.Dial from DialTLS will need to go into the
  4901  // idle pool. Then we give it a of time to explode.
  4902  func TestIdleConnH2Crash(t *testing.T) {
  4903  	setParallel(t)
  4904  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4905  		// nothing
  4906  	}))
  4907  	defer cst.close()
  4908  
  4909  	ctx, cancel := context.WithCancel(context.Background())
  4910  	defer cancel()
  4911  
  4912  	sawDoErr := make(chan bool, 1)
  4913  	testDone := make(chan struct{})
  4914  	defer close(testDone)
  4915  
  4916  	cst.tr.IdleConnTimeout = 5 * time.Millisecond
  4917  	cst.tr.DialTLS = func(network, addr string) (net.Conn, error) {
  4918  		c, err := tls.Dial(network, addr, &tls.Config{
  4919  			InsecureSkipVerify: true,
  4920  			NextProtos:         []string{"h2"},
  4921  		})
  4922  		if err != nil {
  4923  			t.Error(err)
  4924  			return nil, err
  4925  		}
  4926  		if cs := c.ConnectionState(); cs.NegotiatedProtocol != "h2" {
  4927  			t.Errorf("protocol = %q; want %q", cs.NegotiatedProtocol, "h2")
  4928  			c.Close()
  4929  			return nil, errors.New("bogus")
  4930  		}
  4931  
  4932  		cancel()
  4933  
  4934  		failTimer := time.NewTimer(5 * time.Second)
  4935  		defer failTimer.Stop()
  4936  		select {
  4937  		case <-sawDoErr:
  4938  		case <-testDone:
  4939  		case <-failTimer.C:
  4940  			t.Error("timeout in DialTLS, waiting too long for cst.c.Do to fail")
  4941  		}
  4942  		return c, nil
  4943  	}
  4944  
  4945  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  4946  	req = req.WithContext(ctx)
  4947  	res, err := cst.c.Do(req)
  4948  	if err == nil {
  4949  		res.Body.Close()
  4950  		t.Fatal("unexpected success")
  4951  	}
  4952  	sawDoErr <- true
  4953  
  4954  	// Wait for the explosion.
  4955  	time.Sleep(cst.tr.IdleConnTimeout * 10)
  4956  }
  4957  
  4958  type funcConn struct {
  4959  	net.Conn
  4960  	read  func([]byte) (int, error)
  4961  	write func([]byte) (int, error)
  4962  }
  4963  
  4964  func (c funcConn) Read(p []byte) (int, error)  { return c.read(p) }
  4965  func (c funcConn) Write(p []byte) (int, error) { return c.write(p) }
  4966  func (c funcConn) Close() error                { return nil }
  4967  
  4968  // Issue 16465: Transport.RoundTrip should return the raw net.Conn.Read error from Peek
  4969  // back to the caller.
  4970  func TestTransportReturnsPeekError(t *testing.T) {
  4971  	errValue := errors.New("specific error value")
  4972  
  4973  	wrote := make(chan struct{})
  4974  	var wroteOnce sync.Once
  4975  
  4976  	tr := &Transport{
  4977  		Dial: func(network, addr string) (net.Conn, error) {
  4978  			c := funcConn{
  4979  				read: func([]byte) (int, error) {
  4980  					<-wrote
  4981  					return 0, errValue
  4982  				},
  4983  				write: func(p []byte) (int, error) {
  4984  					wroteOnce.Do(func() { close(wrote) })
  4985  					return len(p), nil
  4986  				},
  4987  			}
  4988  			return c, nil
  4989  		},
  4990  	}
  4991  	_, err := tr.RoundTrip(httptest.NewRequest("GET", "http://fake.tld/", nil))
  4992  	if err != errValue {
  4993  		t.Errorf("error = %#v; want %v", err, errValue)
  4994  	}
  4995  }
  4996  
  4997  // Issue 13835: international domain names should work
  4998  func TestTransportIDNA_h1(t *testing.T) { testTransportIDNA(t, h1Mode) }
  4999  func TestTransportIDNA_h2(t *testing.T) { testTransportIDNA(t, h2Mode) }
  5000  func testTransportIDNA(t *testing.T, h2 bool) {
  5001  	defer afterTest(t)
  5002  
  5003  	const uniDomain = "гофер.го"
  5004  	const punyDomain = "xn--c1ae0ajs.xn--c1aw"
  5005  
  5006  	var port string
  5007  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  5008  		want := punyDomain + ":" + port
  5009  		if r.Host != want {
  5010  			t.Errorf("Host header = %q; want %q", r.Host, want)
  5011  		}
  5012  		if h2 {
  5013  			if r.TLS == nil {
  5014  				t.Errorf("r.TLS == nil")
  5015  			} else if r.TLS.ServerName != punyDomain {
  5016  				t.Errorf("TLS.ServerName = %q; want %q", r.TLS.ServerName, punyDomain)
  5017  			}
  5018  		}
  5019  		w.Header().Set("Hit-Handler", "1")
  5020  	}))
  5021  	defer cst.close()
  5022  
  5023  	ip, port, err := net.SplitHostPort(cst.ts.Listener.Addr().String())
  5024  	if err != nil {
  5025  		t.Fatal(err)
  5026  	}
  5027  
  5028  	// Install a fake DNS server.
  5029  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, network, host string) ([]net.IPAddr, error) {
  5030  		if host != punyDomain {
  5031  			t.Errorf("got DNS host lookup for %q/%q; want %q", network, host, punyDomain)
  5032  			return nil, nil
  5033  		}
  5034  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  5035  	})
  5036  
  5037  	req, _ := NewRequest("GET", cst.scheme()+"://"+uniDomain+":"+port, nil)
  5038  	trace := &httptrace.ClientTrace{
  5039  		GetConn: func(hostPort string) {
  5040  			want := net.JoinHostPort(punyDomain, port)
  5041  			if hostPort != want {
  5042  				t.Errorf("getting conn for %q; want %q", hostPort, want)
  5043  			}
  5044  		},
  5045  		DNSStart: func(e httptrace.DNSStartInfo) {
  5046  			if e.Host != punyDomain {
  5047  				t.Errorf("DNSStart Host = %q; want %q", e.Host, punyDomain)
  5048  			}
  5049  		},
  5050  	}
  5051  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  5052  
  5053  	res, err := cst.tr.RoundTrip(req)
  5054  	if err != nil {
  5055  		t.Fatal(err)
  5056  	}
  5057  	defer res.Body.Close()
  5058  	if res.Header.Get("Hit-Handler") != "1" {
  5059  		out, err := httputil.DumpResponse(res, true)
  5060  		if err != nil {
  5061  			t.Fatal(err)
  5062  		}
  5063  		t.Errorf("Response body wasn't from Handler. Got:\n%s\n", out)
  5064  	}
  5065  }
  5066  
  5067  // Issue 13290: send User-Agent in proxy CONNECT
  5068  func TestTransportProxyConnectHeader(t *testing.T) {
  5069  	defer afterTest(t)
  5070  	reqc := make(chan *Request, 1)
  5071  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  5072  		if r.Method != "CONNECT" {
  5073  			t.Errorf("method = %q; want CONNECT", r.Method)
  5074  		}
  5075  		reqc <- r
  5076  		c, _, err := w.(Hijacker).Hijack()
  5077  		if err != nil {
  5078  			t.Errorf("Hijack: %v", err)
  5079  			return
  5080  		}
  5081  		c.Close()
  5082  	}))
  5083  	defer ts.Close()
  5084  
  5085  	c := ts.Client()
  5086  	c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) {
  5087  		return url.Parse(ts.URL)
  5088  	}
  5089  	c.Transport.(*Transport).ProxyConnectHeader = Header{
  5090  		"User-Agent": {"foo"},
  5091  		"Other":      {"bar"},
  5092  	}
  5093  
  5094  	res, err := c.Get("https://dummy.tld/") // https to force a CONNECT
  5095  	if err == nil {
  5096  		res.Body.Close()
  5097  		t.Errorf("unexpected success")
  5098  	}
  5099  	select {
  5100  	case <-time.After(3 * time.Second):
  5101  		t.Fatal("timeout")
  5102  	case r := <-reqc:
  5103  		if got, want := r.Header.Get("User-Agent"), "foo"; got != want {
  5104  			t.Errorf("CONNECT request User-Agent = %q; want %q", got, want)
  5105  		}
  5106  		if got, want := r.Header.Get("Other"), "bar"; got != want {
  5107  			t.Errorf("CONNECT request Other = %q; want %q", got, want)
  5108  		}
  5109  	}
  5110  }
  5111  
  5112  var errFakeRoundTrip = errors.New("fake roundtrip")
  5113  
  5114  type funcRoundTripper func()
  5115  
  5116  func (fn funcRoundTripper) RoundTrip(*Request) (*Response, error) {
  5117  	fn()
  5118  	return nil, errFakeRoundTrip
  5119  }
  5120  
  5121  func wantBody(res *Response, err error, want string) error {
  5122  	if err != nil {
  5123  		return err
  5124  	}
  5125  	slurp, err := ioutil.ReadAll(res.Body)
  5126  	if err != nil {
  5127  		return fmt.Errorf("error reading body: %v", err)
  5128  	}
  5129  	if string(slurp) != want {
  5130  		return fmt.Errorf("body = %q; want %q", slurp, want)
  5131  	}
  5132  	if err := res.Body.Close(); err != nil {
  5133  		return fmt.Errorf("body Close = %v", err)
  5134  	}
  5135  	return nil
  5136  }
  5137  
  5138  func newLocalListener(t *testing.T) net.Listener {
  5139  	ln, err := net.Listen("tcp", "127.0.0.1:0")
  5140  	if err != nil {
  5141  		ln, err = net.Listen("tcp6", "[::1]:0")
  5142  	}
  5143  	if err != nil {
  5144  		t.Fatal(err)
  5145  	}
  5146  	return ln
  5147  }
  5148  
  5149  type countCloseReader struct {
  5150  	n *int
  5151  	io.Reader
  5152  }
  5153  
  5154  func (cr countCloseReader) Close() error {
  5155  	(*cr.n)++
  5156  	return nil
  5157  }
  5158  
  5159  // rgz is a gzip quine that uncompresses to itself.
  5160  var rgz = []byte{
  5161  	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  5162  	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  5163  	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  5164  	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  5165  	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  5166  	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  5167  	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  5168  	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  5169  	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  5170  	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  5171  	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  5172  	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  5173  	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  5174  	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  5175  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  5176  	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  5177  	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  5178  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  5179  	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  5180  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  5181  	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  5182  	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  5183  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  5184  	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  5185  	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  5186  	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  5187  	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  5188  	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  5189  	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  5190  	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  5191  	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  5192  	0x00, 0x00,
  5193  }
  5194  
  5195  // Ensure that a missing status doesn't make the server panic
  5196  // See Issue https://golang.org/issues/21701
  5197  func TestMissingStatusNoPanic(t *testing.T) {
  5198  	t.Parallel()
  5199  
  5200  	const want = "unknown status code"
  5201  
  5202  	ln := newLocalListener(t)
  5203  	addr := ln.Addr().String()
  5204  	shutdown := make(chan bool, 1)
  5205  	done := make(chan bool)
  5206  	fullAddrURL := fmt.Sprintf("http://%s", addr)
  5207  	raw := "HTTP/1.1 400\r\n" +
  5208  		"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
  5209  		"Content-Type: text/html; charset=utf-8\r\n" +
  5210  		"Content-Length: 10\r\n" +
  5211  		"Last-Modified: Wed, 30 Aug 2017 19:02:02 GMT\r\n" +
  5212  		"Vary: Accept-Encoding\r\n\r\n" +
  5213  		"Aloha Olaa"
  5214  
  5215  	go func() {
  5216  		defer func() {
  5217  			ln.Close()
  5218  			close(done)
  5219  		}()
  5220  
  5221  		conn, _ := ln.Accept()
  5222  		if conn != nil {
  5223  			io.WriteString(conn, raw)
  5224  			ioutil.ReadAll(conn)
  5225  			conn.Close()
  5226  		}
  5227  	}()
  5228  
  5229  	proxyURL, err := url.Parse(fullAddrURL)
  5230  	if err != nil {
  5231  		t.Fatalf("proxyURL: %v", err)
  5232  	}
  5233  
  5234  	tr := &Transport{Proxy: ProxyURL(proxyURL)}
  5235  
  5236  	req, _ := NewRequest("GET", "https://golang.org/", nil)
  5237  	res, err, panicked := doFetchCheckPanic(tr, req)
  5238  	if panicked {
  5239  		t.Error("panicked, expecting an error")
  5240  	}
  5241  	if res != nil && res.Body != nil {
  5242  		io.Copy(ioutil.Discard, res.Body)
  5243  		res.Body.Close()
  5244  	}
  5245  
  5246  	if err == nil || !strings.Contains(err.Error(), want) {
  5247  		t.Errorf("got=%v want=%q", err, want)
  5248  	}
  5249  
  5250  	close(shutdown)
  5251  	<-done
  5252  }
  5253  
  5254  func doFetchCheckPanic(tr *Transport, req *Request) (res *Response, err error, panicked bool) {
  5255  	defer func() {
  5256  		if r := recover(); r != nil {
  5257  			panicked = true
  5258  		}
  5259  	}()
  5260  	res, err = tr.RoundTrip(req)
  5261  	return
  5262  }
  5263  
  5264  // Issue 22330: do not allow the response body to be read when the status code
  5265  // forbids a response body.
  5266  func TestNoBodyOnChunked304Response(t *testing.T) {
  5267  	defer afterTest(t)
  5268  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5269  		conn, buf, _ := w.(Hijacker).Hijack()
  5270  		buf.Write([]byte("HTTP/1.1 304 NOT MODIFIED\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"))
  5271  		buf.Flush()
  5272  		conn.Close()
  5273  	}))
  5274  	defer cst.close()
  5275  
  5276  	// Our test server above is sending back bogus data after the
  5277  	// response (the "0\r\n\r\n" part), which causes the Transport
  5278  	// code to log spam. Disable keep-alives so we never even try
  5279  	// to reuse the connection.
  5280  	cst.tr.DisableKeepAlives = true
  5281  
  5282  	res, err := cst.c.Get(cst.ts.URL)
  5283  	if err != nil {
  5284  		t.Fatal(err)
  5285  	}
  5286  
  5287  	if res.Body != NoBody {
  5288  		t.Errorf("Unexpected body on 304 response")
  5289  	}
  5290  }
  5291  
  5292  type funcWriter func([]byte) (int, error)
  5293  
  5294  func (f funcWriter) Write(p []byte) (int, error) { return f(p) }
  5295  
  5296  type doneContext struct {
  5297  	context.Context
  5298  	err error
  5299  }
  5300  
  5301  func (doneContext) Done() <-chan struct{} {
  5302  	c := make(chan struct{})
  5303  	close(c)
  5304  	return c
  5305  }
  5306  
  5307  func (d doneContext) Err() error { return d.err }
  5308  
  5309  // Issue 25852: Transport should check whether Context is done early.
  5310  func TestTransportCheckContextDoneEarly(t *testing.T) {
  5311  	tr := &Transport{}
  5312  	req, _ := NewRequest("GET", "http://fake.example/", nil)
  5313  	wantErr := errors.New("some error")
  5314  	req = req.WithContext(doneContext{context.Background(), wantErr})
  5315  	_, err := tr.RoundTrip(req)
  5316  	if err != wantErr {
  5317  		t.Errorf("error = %v; want %v", err, wantErr)
  5318  	}
  5319  }
  5320  
  5321  // Issue 23399: verify that if a client request times out, the Transport's
  5322  // conn is closed so that it's not reused.
  5323  //
  5324  // This is the test variant that times out before the server replies with
  5325  // any response headers.
  5326  func TestClientTimeoutKillsConn_BeforeHeaders(t *testing.T) {
  5327  	setParallel(t)
  5328  	defer afterTest(t)
  5329  	inHandler := make(chan net.Conn, 1)
  5330  	handlerReadReturned := make(chan bool, 1)
  5331  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5332  		conn, _, err := w.(Hijacker).Hijack()
  5333  		if err != nil {
  5334  			t.Error(err)
  5335  			return
  5336  		}
  5337  		inHandler <- conn
  5338  		n, err := conn.Read([]byte{0})
  5339  		if n != 0 || err != io.EOF {
  5340  			t.Errorf("unexpected Read result: %v, %v", n, err)
  5341  		}
  5342  		handlerReadReturned <- true
  5343  	}))
  5344  	defer cst.close()
  5345  
  5346  	const timeout = 50 * time.Millisecond
  5347  	cst.c.Timeout = timeout
  5348  
  5349  	_, err := cst.c.Get(cst.ts.URL)
  5350  	if err == nil {
  5351  		t.Fatal("unexpected Get succeess")
  5352  	}
  5353  
  5354  	select {
  5355  	case c := <-inHandler:
  5356  		select {
  5357  		case <-handlerReadReturned:
  5358  			// Success.
  5359  			return
  5360  		case <-time.After(5 * time.Second):
  5361  			t.Error("Handler's conn.Read seems to be stuck in Read")
  5362  			c.Close() // close it to unblock Handler
  5363  		}
  5364  	case <-time.After(timeout * 10):
  5365  		// If we didn't get into the Handler in 50ms, that probably means
  5366  		// the builder was just slow and the Get failed in that time
  5367  		// but never made it to the server. That's fine. We'll usually
  5368  		// test the part above on faster machines.
  5369  		t.Skip("skipping test on slow builder")
  5370  	}
  5371  }
  5372  
  5373  // Issue 23399: verify that if a client request times out, the Transport's
  5374  // conn is closed so that it's not reused.
  5375  //
  5376  // This is the test variant that has the server send response headers
  5377  // first, and time out during the write of the response body.
  5378  func TestClientTimeoutKillsConn_AfterHeaders(t *testing.T) {
  5379  	setParallel(t)
  5380  	defer afterTest(t)
  5381  	inHandler := make(chan net.Conn, 1)
  5382  	handlerResult := make(chan error, 1)
  5383  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5384  		w.Header().Set("Content-Length", "100")
  5385  		w.(Flusher).Flush()
  5386  		conn, _, err := w.(Hijacker).Hijack()
  5387  		if err != nil {
  5388  			t.Error(err)
  5389  			return
  5390  		}
  5391  		conn.Write([]byte("foo"))
  5392  		inHandler <- conn
  5393  		n, err := conn.Read([]byte{0})
  5394  		// The error should be io.EOF or "read tcp
  5395  		// 127.0.0.1:35827->127.0.0.1:40290: read: connection
  5396  		// reset by peer" depending on timing. Really we just
  5397  		// care that it returns at all. But if it returns with
  5398  		// data, that's weird.
  5399  		if n != 0 || err == nil {
  5400  			handlerResult <- fmt.Errorf("unexpected Read result: %v, %v", n, err)
  5401  			return
  5402  		}
  5403  		handlerResult <- nil
  5404  	}))
  5405  	defer cst.close()
  5406  
  5407  	// Set Timeout to something very long but non-zero to exercise
  5408  	// the codepaths that check for it. But rather than wait for it to fire
  5409  	// (which would make the test slow), we send on the req.Cancel channel instead,
  5410  	// which happens to exercise the same code paths.
  5411  	cst.c.Timeout = time.Minute // just to be non-zero, not to hit it.
  5412  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  5413  	cancel := make(chan struct{})
  5414  	req.Cancel = cancel
  5415  
  5416  	res, err := cst.c.Do(req)
  5417  	if err != nil {
  5418  		select {
  5419  		case <-inHandler:
  5420  			t.Fatalf("Get error: %v", err)
  5421  		default:
  5422  			// Failed before entering handler. Ignore result.
  5423  			t.Skip("skipping test on slow builder")
  5424  		}
  5425  	}
  5426  
  5427  	close(cancel)
  5428  	got, err := ioutil.ReadAll(res.Body)
  5429  	if err == nil {
  5430  		t.Fatalf("unexpected success; read %q, nil", got)
  5431  	}
  5432  
  5433  	select {
  5434  	case c := <-inHandler:
  5435  		select {
  5436  		case err := <-handlerResult:
  5437  			if err != nil {
  5438  				t.Errorf("handler: %v", err)
  5439  			}
  5440  			return
  5441  		case <-time.After(5 * time.Second):
  5442  			t.Error("Handler's conn.Read seems to be stuck in Read")
  5443  			c.Close() // close it to unblock Handler
  5444  		}
  5445  	case <-time.After(5 * time.Second):
  5446  		t.Fatal("timeout")
  5447  	}
  5448  }
  5449  
  5450  func TestTransportResponseBodyWritableOnProtocolSwitch(t *testing.T) {
  5451  	setParallel(t)
  5452  	defer afterTest(t)
  5453  	done := make(chan struct{})
  5454  	defer close(done)
  5455  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5456  		conn, _, err := w.(Hijacker).Hijack()
  5457  		if err != nil {
  5458  			t.Error(err)
  5459  			return
  5460  		}
  5461  		defer conn.Close()
  5462  		io.WriteString(conn, "HTTP/1.1 101 Switching Protocols Hi\r\nConnection: upgRADe\r\nUpgrade: foo\r\n\r\nSome buffered data\n")
  5463  		bs := bufio.NewScanner(conn)
  5464  		bs.Scan()
  5465  		fmt.Fprintf(conn, "%s\n", strings.ToUpper(bs.Text()))
  5466  		<-done
  5467  	}))
  5468  	defer cst.close()
  5469  
  5470  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  5471  	req.Header.Set("Upgrade", "foo")
  5472  	req.Header.Set("Connection", "upgrade")
  5473  	res, err := cst.c.Do(req)
  5474  	if err != nil {
  5475  		t.Fatal(err)
  5476  	}
  5477  	if res.StatusCode != 101 {
  5478  		t.Fatalf("expected 101 switching protocols; got %v, %v", res.Status, res.Header)
  5479  	}
  5480  	rwc, ok := res.Body.(io.ReadWriteCloser)
  5481  	if !ok {
  5482  		t.Fatalf("expected a ReadWriteCloser; got a %T", res.Body)
  5483  	}
  5484  	defer rwc.Close()
  5485  	bs := bufio.NewScanner(rwc)
  5486  	if !bs.Scan() {
  5487  		t.Fatalf("expected readable input")
  5488  	}
  5489  	if got, want := bs.Text(), "Some buffered data"; got != want {
  5490  		t.Errorf("read %q; want %q", got, want)
  5491  	}
  5492  	io.WriteString(rwc, "echo\n")
  5493  	if !bs.Scan() {
  5494  		t.Fatalf("expected another line")
  5495  	}
  5496  	if got, want := bs.Text(), "ECHO"; got != want {
  5497  		t.Errorf("read %q; want %q", got, want)
  5498  	}
  5499  }
  5500  
  5501  func TestTransportCONNECTBidi(t *testing.T) {
  5502  	defer afterTest(t)
  5503  	const target = "backend:443"
  5504  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5505  		if r.Method != "CONNECT" {
  5506  			t.Errorf("unexpected method %q", r.Method)
  5507  			w.WriteHeader(500)
  5508  			return
  5509  		}
  5510  		if r.RequestURI != target {
  5511  			t.Errorf("unexpected CONNECT target %q", r.RequestURI)
  5512  			w.WriteHeader(500)
  5513  			return
  5514  		}
  5515  		nc, brw, err := w.(Hijacker).Hijack()
  5516  		if err != nil {
  5517  			t.Error(err)
  5518  			return
  5519  		}
  5520  		defer nc.Close()
  5521  		nc.Write([]byte("HTTP/1.1 200 OK\r\n\r\n"))
  5522  		// Switch to a little protocol that capitalize its input lines:
  5523  		for {
  5524  			line, err := brw.ReadString('\n')
  5525  			if err != nil {
  5526  				if err != io.EOF {
  5527  					t.Error(err)
  5528  				}
  5529  				return
  5530  			}
  5531  			io.WriteString(brw, strings.ToUpper(line))
  5532  			brw.Flush()
  5533  		}
  5534  	}))
  5535  	defer cst.close()
  5536  	pr, pw := io.Pipe()
  5537  	defer pw.Close()
  5538  	req, err := NewRequest("CONNECT", cst.ts.URL, pr)
  5539  	if err != nil {
  5540  		t.Fatal(err)
  5541  	}
  5542  	req.URL.Opaque = target
  5543  	res, err := cst.c.Do(req)
  5544  	if err != nil {
  5545  		t.Fatal(err)
  5546  	}
  5547  	defer res.Body.Close()
  5548  	if res.StatusCode != 200 {
  5549  		t.Fatalf("status code = %d; want 200", res.StatusCode)
  5550  	}
  5551  	br := bufio.NewReader(res.Body)
  5552  	for _, str := range []string{"foo", "bar", "baz"} {
  5553  		fmt.Fprintf(pw, "%s\n", str)
  5554  		got, err := br.ReadString('\n')
  5555  		if err != nil {
  5556  			t.Fatal(err)
  5557  		}
  5558  		got = strings.TrimSpace(got)
  5559  		want := strings.ToUpper(str)
  5560  		if got != want {
  5561  			t.Fatalf("got %q; want %q", got, want)
  5562  		}
  5563  	}
  5564  }
  5565  
  5566  func TestTransportRequestReplayable(t *testing.T) {
  5567  	someBody := ioutil.NopCloser(strings.NewReader(""))
  5568  	tests := []struct {
  5569  		name string
  5570  		req  *Request
  5571  		want bool
  5572  	}{
  5573  		{
  5574  			name: "GET",
  5575  			req:  &Request{Method: "GET"},
  5576  			want: true,
  5577  		},
  5578  		{
  5579  			name: "GET_http.NoBody",
  5580  			req:  &Request{Method: "GET", Body: NoBody},
  5581  			want: true,
  5582  		},
  5583  		{
  5584  			name: "GET_body",
  5585  			req:  &Request{Method: "GET", Body: someBody},
  5586  			want: false,
  5587  		},
  5588  		{
  5589  			name: "POST",
  5590  			req:  &Request{Method: "POST"},
  5591  			want: false,
  5592  		},
  5593  		{
  5594  			name: "POST_idempotency-key",
  5595  			req:  &Request{Method: "POST", Header: Header{"Idempotency-Key": {"x"}}},
  5596  			want: true,
  5597  		},
  5598  		{
  5599  			name: "POST_x-idempotency-key",
  5600  			req:  &Request{Method: "POST", Header: Header{"X-Idempotency-Key": {"x"}}},
  5601  			want: true,
  5602  		},
  5603  		{
  5604  			name: "POST_body",
  5605  			req:  &Request{Method: "POST", Header: Header{"Idempotency-Key": {"x"}}, Body: someBody},
  5606  			want: false,
  5607  		},
  5608  	}
  5609  	for _, tt := range tests {
  5610  		t.Run(tt.name, func(t *testing.T) {
  5611  			got := tt.req.ExportIsReplayable()
  5612  			if got != tt.want {
  5613  				t.Errorf("replyable = %v; want %v", got, tt.want)
  5614  			}
  5615  		})
  5616  	}
  5617  }
  5618  
  5619  // testMockTCPConn is a mock TCP connection used to test that
  5620  // ReadFrom is called when sending the request body.
  5621  type testMockTCPConn struct {
  5622  	*net.TCPConn
  5623  
  5624  	ReadFromCalled bool
  5625  }
  5626  
  5627  func (c *testMockTCPConn) ReadFrom(r io.Reader) (int64, error) {
  5628  	c.ReadFromCalled = true
  5629  	return c.TCPConn.ReadFrom(r)
  5630  }
  5631  
  5632  func TestTransportRequestWriteRoundTrip(t *testing.T) {
  5633  	nBytes := int64(1 << 10)
  5634  	newFileFunc := func() (r io.Reader, done func(), err error) {
  5635  		f, err := ioutil.TempFile("", "net-http-newfilefunc")
  5636  		if err != nil {
  5637  			return nil, nil, err
  5638  		}
  5639  
  5640  		// Write some bytes to the file to enable reading.
  5641  		if _, err := io.CopyN(f, rand.Reader, nBytes); err != nil {
  5642  			return nil, nil, fmt.Errorf("failed to write data to file: %v", err)
  5643  		}
  5644  		if _, err := f.Seek(0, 0); err != nil {
  5645  			return nil, nil, fmt.Errorf("failed to seek to front: %v", err)
  5646  		}
  5647  
  5648  		done = func() {
  5649  			f.Close()
  5650  			os.Remove(f.Name())
  5651  		}
  5652  
  5653  		return f, done, nil
  5654  	}
  5655  
  5656  	newBufferFunc := func() (io.Reader, func(), error) {
  5657  		return bytes.NewBuffer(make([]byte, nBytes)), func() {}, nil
  5658  	}
  5659  
  5660  	cases := []struct {
  5661  		name             string
  5662  		readerFunc       func() (io.Reader, func(), error)
  5663  		contentLength    int64
  5664  		expectedReadFrom bool
  5665  	}{
  5666  		{
  5667  			name:             "file, length",
  5668  			readerFunc:       newFileFunc,
  5669  			contentLength:    nBytes,
  5670  			expectedReadFrom: true,
  5671  		},
  5672  		{
  5673  			name:       "file, no length",
  5674  			readerFunc: newFileFunc,
  5675  		},
  5676  		{
  5677  			name:          "file, negative length",
  5678  			readerFunc:    newFileFunc,
  5679  			contentLength: -1,
  5680  		},
  5681  		{
  5682  			name:          "buffer",
  5683  			contentLength: nBytes,
  5684  			readerFunc:    newBufferFunc,
  5685  		},
  5686  		{
  5687  			name:       "buffer, no length",
  5688  			readerFunc: newBufferFunc,
  5689  		},
  5690  		{
  5691  			name:          "buffer, length -1",
  5692  			contentLength: -1,
  5693  			readerFunc:    newBufferFunc,
  5694  		},
  5695  	}
  5696  
  5697  	for _, tc := range cases {
  5698  		t.Run(tc.name, func(t *testing.T) {
  5699  			r, cleanup, err := tc.readerFunc()
  5700  			if err != nil {
  5701  				t.Fatal(err)
  5702  			}
  5703  			defer cleanup()
  5704  
  5705  			tConn := &testMockTCPConn{}
  5706  			trFunc := func(tr *Transport) {
  5707  				tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
  5708  					var d net.Dialer
  5709  					conn, err := d.DialContext(ctx, network, addr)
  5710  					if err != nil {
  5711  						return nil, err
  5712  					}
  5713  
  5714  					tcpConn, ok := conn.(*net.TCPConn)
  5715  					if !ok {
  5716  						return nil, fmt.Errorf("%s/%s does not provide a *net.TCPConn", network, addr)
  5717  					}
  5718  
  5719  					tConn.TCPConn = tcpConn
  5720  					return tConn, nil
  5721  				}
  5722  			}
  5723  
  5724  			cst := newClientServerTest(
  5725  				t,
  5726  				h1Mode,
  5727  				HandlerFunc(func(w ResponseWriter, r *Request) {
  5728  					io.Copy(ioutil.Discard, r.Body)
  5729  					r.Body.Close()
  5730  					w.WriteHeader(200)
  5731  				}),
  5732  				trFunc,
  5733  			)
  5734  			defer cst.close()
  5735  
  5736  			req, err := NewRequest("PUT", cst.ts.URL, r)
  5737  			if err != nil {
  5738  				t.Fatal(err)
  5739  			}
  5740  			req.ContentLength = tc.contentLength
  5741  			req.Header.Set("Content-Type", "application/octet-stream")
  5742  			resp, err := cst.c.Do(req)
  5743  			if err != nil {
  5744  				t.Fatal(err)
  5745  			}
  5746  			defer resp.Body.Close()
  5747  			if resp.StatusCode != 200 {
  5748  				t.Fatalf("status code = %d; want 200", resp.StatusCode)
  5749  			}
  5750  
  5751  			if !tConn.ReadFromCalled && tc.expectedReadFrom {
  5752  				t.Fatalf("did not call ReadFrom")
  5753  			}
  5754  
  5755  			if tConn.ReadFromCalled && !tc.expectedReadFrom {
  5756  				t.Fatalf("ReadFrom was unexpectedly invoked")
  5757  			}
  5758  		})
  5759  	}
  5760  }
  5761  
  5762  func TestTransportClone(t *testing.T) {
  5763  	tr := &Transport{
  5764  		Proxy:                  func(*Request) (*url.URL, error) { panic("") },
  5765  		DialContext:            func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") },
  5766  		Dial:                   func(network, addr string) (net.Conn, error) { panic("") },
  5767  		DialTLS:                func(network, addr string) (net.Conn, error) { panic("") },
  5768  		DialTLSContext:         func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") },
  5769  		TLSClientConfig:        new(tls.Config),
  5770  		TLSHandshakeTimeout:    time.Second,
  5771  		DisableKeepAlives:      true,
  5772  		DisableCompression:     true,
  5773  		MaxIdleConns:           1,
  5774  		MaxIdleConnsPerHost:    1,
  5775  		MaxConnsPerHost:        1,
  5776  		IdleConnTimeout:        time.Second,
  5777  		ResponseHeaderTimeout:  time.Second,
  5778  		ExpectContinueTimeout:  time.Second,
  5779  		ProxyConnectHeader:     Header{},
  5780  		MaxResponseHeaderBytes: 1,
  5781  		ForceAttemptHTTP2:      true,
  5782  		TLSNextProto: map[string]func(authority string, c *tls.Conn) RoundTripper{
  5783  			"foo": func(authority string, c *tls.Conn) RoundTripper { panic("") },
  5784  		},
  5785  		ReadBufferSize:  1,
  5786  		WriteBufferSize: 1,
  5787  	}
  5788  	tr2 := tr.Clone()
  5789  	rv := reflect.ValueOf(tr2).Elem()
  5790  	rt := rv.Type()
  5791  	for i := 0; i < rt.NumField(); i++ {
  5792  		sf := rt.Field(i)
  5793  		if !token.IsExported(sf.Name) {
  5794  			continue
  5795  		}
  5796  		if rv.Field(i).IsZero() {
  5797  			t.Errorf("cloned field t2.%s is zero", sf.Name)
  5798  		}
  5799  	}
  5800  
  5801  	if _, ok := tr2.TLSNextProto["foo"]; !ok {
  5802  		t.Errorf("cloned Transport lacked TLSNextProto 'foo' key")
  5803  	}
  5804  
  5805  	// But test that a nil TLSNextProto is kept nil:
  5806  	tr = new(Transport)
  5807  	tr2 = tr.Clone()
  5808  	if tr2.TLSNextProto != nil {
  5809  		t.Errorf("Transport.TLSNextProto unexpected non-nil")
  5810  	}
  5811  }
  5812  
  5813  func TestIs408(t *testing.T) {
  5814  	tests := []struct {
  5815  		in   string
  5816  		want bool
  5817  	}{
  5818  		{"HTTP/1.0 408", true},
  5819  		{"HTTP/1.1 408", true},
  5820  		{"HTTP/1.8 408", true},
  5821  		{"HTTP/2.0 408", false}, // maybe h2c would do this? but false for now.
  5822  		{"HTTP/1.1 408 ", true},
  5823  		{"HTTP/1.1 40", false},
  5824  		{"http/1.0 408", false},
  5825  		{"HTTP/1-1 408", false},
  5826  	}
  5827  	for _, tt := range tests {
  5828  		if got := Export_is408Message([]byte(tt.in)); got != tt.want {
  5829  			t.Errorf("is408Message(%q) = %v; want %v", tt.in, got, tt.want)
  5830  		}
  5831  	}
  5832  }
  5833  
  5834  func TestTransportIgnores408(t *testing.T) {
  5835  	// Not parallel. Relies on mutating the log package's global Output.
  5836  	defer log.SetOutput(log.Writer())
  5837  
  5838  	var logout bytes.Buffer
  5839  	log.SetOutput(&logout)
  5840  
  5841  	defer afterTest(t)
  5842  	const target = "backend:443"
  5843  
  5844  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5845  		nc, _, err := w.(Hijacker).Hijack()
  5846  		if err != nil {
  5847  			t.Error(err)
  5848  			return
  5849  		}
  5850  		defer nc.Close()
  5851  		nc.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok"))
  5852  		nc.Write([]byte("HTTP/1.1 408 bye\r\n")) // changing 408 to 409 makes test fail
  5853  	}))
  5854  	defer cst.close()
  5855  	req, err := NewRequest("GET", cst.ts.URL, nil)
  5856  	if err != nil {
  5857  		t.Fatal(err)
  5858  	}
  5859  	res, err := cst.c.Do(req)
  5860  	if err != nil {
  5861  		t.Fatal(err)
  5862  	}
  5863  	slurp, err := ioutil.ReadAll(res.Body)
  5864  	if err != nil {
  5865  		t.Fatal(err)
  5866  	}
  5867  	if err != nil {
  5868  		t.Fatal(err)
  5869  	}
  5870  	if string(slurp) != "ok" {
  5871  		t.Fatalf("got %q; want ok", slurp)
  5872  	}
  5873  
  5874  	t0 := time.Now()
  5875  	for i := 0; i < 50; i++ {
  5876  		time.Sleep(time.Duration(i) * 5 * time.Millisecond)
  5877  		if cst.tr.IdleConnKeyCountForTesting() == 0 {
  5878  			if got := logout.String(); got != "" {
  5879  				t.Fatalf("expected no log output; got: %s", got)
  5880  			}
  5881  			return
  5882  		}
  5883  	}
  5884  	t.Fatalf("timeout after %v waiting for Transport connections to die off", time.Since(t0))
  5885  }
  5886  
  5887  func TestInvalidHeaderResponse(t *testing.T) {
  5888  	setParallel(t)
  5889  	defer afterTest(t)
  5890  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5891  		conn, buf, _ := w.(Hijacker).Hijack()
  5892  		buf.Write([]byte("HTTP/1.1 200 OK\r\n" +
  5893  			"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
  5894  			"Content-Type: text/html; charset=utf-8\r\n" +
  5895  			"Content-Length: 0\r\n" +
  5896  			"Foo : bar\r\n\r\n"))
  5897  		buf.Flush()
  5898  		conn.Close()
  5899  	}))
  5900  	defer cst.close()
  5901  	res, err := cst.c.Get(cst.ts.URL)
  5902  	if err != nil {
  5903  		t.Fatal(err)
  5904  	}
  5905  	defer res.Body.Close()
  5906  	if v := res.Header.Get("Foo"); v != "" {
  5907  		t.Errorf(`unexpected "Foo" header: %q`, v)
  5908  	}
  5909  	if v := res.Header.Get("Foo "); v != "bar" {
  5910  		t.Errorf(`bad "Foo " header value: %q, want %q`, v, "bar")
  5911  	}
  5912  }
  5913  
  5914  type bodyCloser bool
  5915  
  5916  func (bc *bodyCloser) Close() error {
  5917  	*bc = true
  5918  	return nil
  5919  }
  5920  func (bc *bodyCloser) Read(b []byte) (n int, err error) {
  5921  	return 0, io.EOF
  5922  }
  5923  
  5924  // Issue 35015: ensure that Transport closes the body on any error
  5925  // with an invalid request, as promised by Client.Do docs.
  5926  func TestTransportClosesBodyOnInvalidRequests(t *testing.T) {
  5927  	cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  5928  		t.Errorf("Should not have been invoked")
  5929  	}))
  5930  	defer cst.Close()
  5931  
  5932  	u, _ := url.Parse(cst.URL)
  5933  
  5934  	tests := []struct {
  5935  		name    string
  5936  		req     *Request
  5937  		wantErr string
  5938  	}{
  5939  		{
  5940  			name: "invalid method",
  5941  			req: &Request{
  5942  				Method: " ",
  5943  				URL:    u,
  5944  			},
  5945  			wantErr: "invalid method",
  5946  		},
  5947  		{
  5948  			name: "nil URL",
  5949  			req: &Request{
  5950  				Method: "GET",
  5951  			},
  5952  			wantErr: "nil Request.URL",
  5953  		},
  5954  		{
  5955  			name: "invalid header key",
  5956  			req: &Request{
  5957  				Method: "GET",
  5958  				Header: Header{"💡": {"emoji"}},
  5959  				URL:    u,
  5960  			},
  5961  			wantErr: "invalid header field name",
  5962  		},
  5963  		{
  5964  			name: "invalid header value",
  5965  			req: &Request{
  5966  				Method: "POST",
  5967  				Header: Header{"key": {"\x19"}},
  5968  				URL:    u,
  5969  			},
  5970  			wantErr: "invalid header field value",
  5971  		},
  5972  		{
  5973  			name: "non HTTP(s) scheme",
  5974  			req: &Request{
  5975  				Method: "POST",
  5976  				URL:    &url.URL{Scheme: "faux"},
  5977  			},
  5978  			wantErr: "unsupported protocol scheme",
  5979  		},
  5980  		{
  5981  			name: "no Host in URL",
  5982  			req: &Request{
  5983  				Method: "POST",
  5984  				URL:    &url.URL{Scheme: "http"},
  5985  			},
  5986  			wantErr: "no Host",
  5987  		},
  5988  	}
  5989  
  5990  	for _, tt := range tests {
  5991  		t.Run(tt.name, func(t *testing.T) {
  5992  			var bc bodyCloser
  5993  			req := tt.req
  5994  			req.Body = &bc
  5995  			_, err := DefaultClient.Do(tt.req)
  5996  			if err == nil {
  5997  				t.Fatal("Expected an error")
  5998  			}
  5999  			if !bc {
  6000  				t.Fatal("Expected body to have been closed")
  6001  			}
  6002  			if g, w := err.Error(), tt.wantErr; !strings.Contains(g, w) {
  6003  				t.Fatalf("Error mismatch\n\t%q\ndoes not contain\n\t%q", g, w)
  6004  			}
  6005  		})
  6006  	}
  6007  }
  6008  
  6009  // breakableConn is a net.Conn wrapper with a Write method
  6010  // that will fail when its brokenState is true.
  6011  type breakableConn struct {
  6012  	net.Conn
  6013  	*brokenState
  6014  }
  6015  
  6016  type brokenState struct {
  6017  	sync.Mutex
  6018  	broken bool
  6019  }
  6020  
  6021  func (w *breakableConn) Write(b []byte) (n int, err error) {
  6022  	w.Lock()
  6023  	defer w.Unlock()
  6024  	if w.broken {
  6025  		return 0, errors.New("some write error")
  6026  	}
  6027  	return w.Conn.Write(b)
  6028  }
  6029  
  6030  // Issue 34978: don't cache a broken HTTP/2 connection
  6031  func TestDontCacheBrokenHTTP2Conn(t *testing.T) {
  6032  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), optQuietLog)
  6033  	defer cst.close()
  6034  
  6035  	var brokenState brokenState
  6036  
  6037  	const numReqs = 5
  6038  	var numDials, gotConns uint32 // atomic
  6039  
  6040  	cst.tr.Dial = func(netw, addr string) (net.Conn, error) {
  6041  		atomic.AddUint32(&numDials, 1)
  6042  		c, err := net.Dial(netw, addr)
  6043  		if err != nil {
  6044  			t.Errorf("unexpected Dial error: %v", err)
  6045  			return nil, err
  6046  		}
  6047  		return &breakableConn{c, &brokenState}, err
  6048  	}
  6049  
  6050  	for i := 1; i <= numReqs; i++ {
  6051  		brokenState.Lock()
  6052  		brokenState.broken = false
  6053  		brokenState.Unlock()
  6054  
  6055  		// doBreak controls whether we break the TCP connection after the TLS
  6056  		// handshake (before the HTTP/2 handshake). We test a few failures
  6057  		// in a row followed by a final success.
  6058  		doBreak := i != numReqs
  6059  
  6060  		ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  6061  			GotConn: func(info httptrace.GotConnInfo) {
  6062  				t.Logf("got conn: %v, reused=%v, wasIdle=%v, idleTime=%v", info.Conn.LocalAddr(), info.Reused, info.WasIdle, info.IdleTime)
  6063  				atomic.AddUint32(&gotConns, 1)
  6064  			},
  6065  			TLSHandshakeDone: func(cfg tls.ConnectionState, err error) {
  6066  				brokenState.Lock()
  6067  				defer brokenState.Unlock()
  6068  				if doBreak {
  6069  					brokenState.broken = true
  6070  				}
  6071  			},
  6072  		})
  6073  		req, err := NewRequestWithContext(ctx, "GET", cst.ts.URL, nil)
  6074  		if err != nil {
  6075  			t.Fatal(err)
  6076  		}
  6077  		_, err = cst.c.Do(req)
  6078  		if doBreak != (err != nil) {
  6079  			t.Errorf("for iteration %d, doBreak=%v; unexpected error %v", i, doBreak, err)
  6080  		}
  6081  	}
  6082  	if got, want := atomic.LoadUint32(&gotConns), 1; int(got) != want {
  6083  		t.Errorf("GotConn calls = %v; want %v", got, want)
  6084  	}
  6085  	if got, want := atomic.LoadUint32(&numDials), numReqs; int(got) != want {
  6086  		t.Errorf("Dials = %v; want %v", got, want)
  6087  	}
  6088  }
  6089  
  6090  // Issue 34941
  6091  // When the client has too many concurrent requests on a single connection,
  6092  // http.http2noCachedConnError is reported on multiple requests. There should
  6093  // only be one decrement regardless of the number of failures.
  6094  func TestTransportDecrementConnWhenIdleConnRemoved(t *testing.T) {
  6095  	defer afterTest(t)
  6096  	CondSkipHTTP2(t)
  6097  
  6098  	h := HandlerFunc(func(w ResponseWriter, r *Request) {
  6099  		_, err := w.Write([]byte("foo"))
  6100  		if err != nil {
  6101  			t.Fatalf("Write: %v", err)
  6102  		}
  6103  	})
  6104  
  6105  	ts := httptest.NewUnstartedServer(h)
  6106  	ts.EnableHTTP2 = true
  6107  	ts.StartTLS()
  6108  	defer ts.Close()
  6109  
  6110  	c := ts.Client()
  6111  	tr := c.Transport.(*Transport)
  6112  	tr.MaxConnsPerHost = 1
  6113  	if err := ExportHttp2ConfigureTransport(tr); err != nil {
  6114  		t.Fatalf("ExportHttp2ConfigureTransport: %v", err)
  6115  	}
  6116  
  6117  	errCh := make(chan error, 300)
  6118  	doReq := func() {
  6119  		resp, err := c.Get(ts.URL)
  6120  		if err != nil {
  6121  			errCh <- fmt.Errorf("request failed: %v", err)
  6122  			return
  6123  		}
  6124  		defer resp.Body.Close()
  6125  		_, err = ioutil.ReadAll(resp.Body)
  6126  		if err != nil {
  6127  			errCh <- fmt.Errorf("read body failed: %v", err)
  6128  		}
  6129  	}
  6130  
  6131  	var wg sync.WaitGroup
  6132  	for i := 0; i < 300; i++ {
  6133  		wg.Add(1)
  6134  		go func() {
  6135  			defer wg.Done()
  6136  			doReq()
  6137  		}()
  6138  	}
  6139  	wg.Wait()
  6140  	close(errCh)
  6141  
  6142  	for err := range errCh {
  6143  		t.Errorf("error occurred: %v", err)
  6144  	}
  6145  }
  6146  
  6147  // Issue 36820
  6148  // Test that we use the older backward compatible cancellation protocol
  6149  // when a RoundTripper is registered via RegisterProtocol.
  6150  func TestAltProtoCancellation(t *testing.T) {
  6151  	defer afterTest(t)
  6152  	tr := &Transport{}
  6153  	c := &Client{
  6154  		Transport: tr,
  6155  		Timeout:   time.Millisecond,
  6156  	}
  6157  	tr.RegisterProtocol("timeout", timeoutProto{})
  6158  	_, err := c.Get("timeout://bar.com/path")
  6159  	if err == nil {
  6160  		t.Error("request unexpectedly succeeded")
  6161  	} else if !strings.Contains(err.Error(), timeoutProtoErr.Error()) {
  6162  		t.Errorf("got error %q, does not contain expected string %q", err, timeoutProtoErr)
  6163  	}
  6164  }
  6165  
  6166  var timeoutProtoErr = errors.New("canceled as expected")
  6167  
  6168  type timeoutProto struct{}
  6169  
  6170  func (timeoutProto) RoundTrip(req *Request) (*Response, error) {
  6171  	select {
  6172  	case <-req.Cancel:
  6173  		return nil, timeoutProtoErr
  6174  	case <-time.After(5 * time.Second):
  6175  		return nil, errors.New("request was not canceled")
  6176  	}
  6177  }
  6178  

View as plain text