github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/net/http/transport_test.go (about)

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