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

View as plain text