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