...
Run Format

Source file src/net/http/transport_test.go

Documentation: net/http

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

View as plain text