github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/net/http/transport_test.go (about)

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