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