github.com/remobjects/goldbaselibrary@v0.0.0-20230924164425-d458680a936b/Source/Gold/net/http/transport_test.go (about)

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