gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/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/zhaochuninhefei/gmgo/gmhttp"
    40  	"gitee.com/zhaochuninhefei/gmgo/gmhttp/httptest"
    41  	"gitee.com/zhaochuninhefei/gmgo/gmhttp/httptrace"
    42  	"gitee.com/zhaochuninhefei/gmgo/gmhttp/httputil"
    43  	"gitee.com/zhaochuninhefei/gmgo/gmhttp/internal/testcert"
    44  	tls "gitee.com/zhaochuninhefei/gmgo/gmtls"
    45  	"gitee.com/zhaochuninhefei/gmgo/internal/nettrace"
    46  	"gitee.com/zhaochuninhefei/gmgo/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/": gitee.com/zhaochuninhefei/gmgo/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  // This automatically prevents an infinite resend loop because we'll run out of
  3496  // the cached keep-alive connections eventually.
  3497  func TestRetryRequestsOnError(t *testing.T) {
  3498  	newRequest := func(method, urlStr string, body io.Reader) *Request {
  3499  		req, err := NewRequest(method, urlStr, body)
  3500  		if err != nil {
  3501  			t.Fatal(err)
  3502  		}
  3503  		return req
  3504  	}
  3505  
  3506  	testCases := []struct {
  3507  		name       string
  3508  		failureN   int
  3509  		failureErr error
  3510  		// Note that we can't just re-use the Request object across calls to c.Do
  3511  		// because we need to rewind Body between calls.  (GetBody is only used to
  3512  		// rewind Body on failure and redirects, not just because it's done.)
  3513  		req       func() *Request
  3514  		reqString string
  3515  	}{
  3516  		{
  3517  			name: "IdempotentNoBodySomeWritten",
  3518  			// Believe that we've written some bytes to the server, so we know we're
  3519  			// not just in the "retry when no bytes sent" case".
  3520  			failureN: 1,
  3521  			// Use the specific error that shouldRetryRequest looks for with idempotent requests.
  3522  			failureErr: ExportErrServerClosedIdle,
  3523  			req: func() *Request {
  3524  				return newRequest("GET", "http://fake.golang", nil)
  3525  			},
  3526  			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`,
  3527  		},
  3528  		{
  3529  			name: "IdempotentGetBodySomeWritten",
  3530  			// Believe that we've written some bytes to the server, so we know we're
  3531  			// not just in the "retry when no bytes sent" case".
  3532  			failureN: 1,
  3533  			// Use the specific error that shouldRetryRequest looks for with idempotent requests.
  3534  			failureErr: ExportErrServerClosedIdle,
  3535  			req: func() *Request {
  3536  				return newRequest("GET", "http://fake.golang", strings.NewReader("foo\n"))
  3537  			},
  3538  			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`,
  3539  		},
  3540  		{
  3541  			name: "NothingWrittenNoBody",
  3542  			// It's key that we return 0 here -- that's what enables Transport to know
  3543  			// that nothing was written, even though this is a non-idempotent request.
  3544  			failureN:   0,
  3545  			failureErr: errors.New("second write fails"),
  3546  			req: func() *Request {
  3547  				return newRequest("DELETE", "http://fake.golang", nil)
  3548  			},
  3549  			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`,
  3550  		},
  3551  		{
  3552  			name: "NothingWrittenGetBody",
  3553  			// It's key that we return 0 here -- that's what enables Transport to know
  3554  			// that nothing was written, even though this is a non-idempotent request.
  3555  			failureN:   0,
  3556  			failureErr: errors.New("second write fails"),
  3557  			// Note that NewRequest will set up GetBody for strings.Reader, which is
  3558  			// required for the retry to occur
  3559  			req: func() *Request {
  3560  				return newRequest("POST", "http://fake.golang", strings.NewReader("foo\n"))
  3561  			},
  3562  			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`,
  3563  		},
  3564  	}
  3565  
  3566  	for _, tc := range testCases {
  3567  		t.Run(tc.name, func(t *testing.T) {
  3568  			defer afterTest(t)
  3569  
  3570  			var (
  3571  				mu     sync.Mutex
  3572  				logbuf bytes.Buffer
  3573  			)
  3574  			logf := func(format string, args ...interface{}) {
  3575  				mu.Lock()
  3576  				defer mu.Unlock()
  3577  				_, _ = fmt.Fprintf(&logbuf, format, args...)
  3578  				logbuf.WriteByte('\n')
  3579  			}
  3580  
  3581  			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3582  				logf("Handler")
  3583  				w.Header().Set("X-Status", "ok")
  3584  			}))
  3585  			defer ts.Close()
  3586  
  3587  			var writeNumAtomic int32
  3588  			c := ts.Client()
  3589  			c.Transport.(*Transport).Dial = func(network, addr string) (net.Conn, error) {
  3590  				logf("Dial")
  3591  				c, err := net.Dial(network, ts.Listener.Addr().String())
  3592  				if err != nil {
  3593  					logf("Dial error: %v", err)
  3594  					return nil, err
  3595  				}
  3596  				return &writerFuncConn{
  3597  					Conn: c,
  3598  					write: func(p []byte) (n int, err error) {
  3599  						if atomic.AddInt32(&writeNumAtomic, 1) == 2 {
  3600  							logf("intentional write failure")
  3601  							return tc.failureN, tc.failureErr
  3602  						}
  3603  						logf("Write(%q)", p)
  3604  						return c.Write(p)
  3605  					},
  3606  				}, nil
  3607  			}
  3608  
  3609  			SetRoundTripRetried(func() {
  3610  				logf("Retried.")
  3611  			})
  3612  			defer SetRoundTripRetried(nil)
  3613  
  3614  			for i := 0; i < 3; i++ {
  3615  				t0 := time.Now()
  3616  				req := tc.req()
  3617  				res, err := c.Do(req)
  3618  				if err != nil {
  3619  					if time.Since(t0) < MaxWriteWaitBeforeConnReuse/2 {
  3620  						mu.Lock()
  3621  						got := logbuf.String()
  3622  						mu.Unlock()
  3623  						t.Fatalf("i=%d: Do = %v; log:\n%s", i, err, got)
  3624  					}
  3625  					t.Skipf("connection likely wasn't recycled within %d, interfering with actual test; skipping", MaxWriteWaitBeforeConnReuse)
  3626  				}
  3627  				_ = res.Body.Close()
  3628  				if res.Request != req {
  3629  					t.Errorf("Response.Request != original request; want identical Request")
  3630  				}
  3631  			}
  3632  
  3633  			mu.Lock()
  3634  			got := logbuf.String()
  3635  			mu.Unlock()
  3636  			want := fmt.Sprintf(`Dial
  3637  Write("%s")
  3638  Handler
  3639  intentional write failure
  3640  Retried.
  3641  Dial
  3642  Write("%s")
  3643  Handler
  3644  Write("%s")
  3645  Handler
  3646  `, tc.reqString, tc.reqString, tc.reqString)
  3647  			if got != want {
  3648  				t.Errorf("Log of events differs. Got:\n%s\nWant:\n%s", got, want)
  3649  			}
  3650  		})
  3651  	}
  3652  }
  3653  
  3654  // Issue 6981
  3655  func TestTransportClosesBodyOnError(t *testing.T) {
  3656  	setParallel(t)
  3657  	defer afterTest(t)
  3658  	readBody := make(chan error, 1)
  3659  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3660  		_, err := io.ReadAll(r.Body)
  3661  		readBody <- err
  3662  	}))
  3663  	defer ts.Close()
  3664  	c := ts.Client()
  3665  	fakeErr := errors.New("fake error")
  3666  	didClose := make(chan bool, 1)
  3667  	req, _ := NewRequest("POST", ts.URL, struct {
  3668  		io.Reader
  3669  		io.Closer
  3670  	}{
  3671  		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), iotest.ErrReader(fakeErr)),
  3672  		closerFunc(func() error {
  3673  			select {
  3674  			case didClose <- true:
  3675  			default:
  3676  			}
  3677  			return nil
  3678  		}),
  3679  	})
  3680  	res, err := c.Do(req)
  3681  	if res != nil {
  3682  		defer func(Body io.ReadCloser) {
  3683  			_ = Body.Close()
  3684  		}(res.Body)
  3685  	}
  3686  	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
  3687  		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
  3688  	}
  3689  	select {
  3690  	case err := <-readBody:
  3691  		if err == nil {
  3692  			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
  3693  		}
  3694  	case <-time.After(5 * time.Second):
  3695  		t.Error("timeout waiting for server handler to complete")
  3696  	}
  3697  	select {
  3698  	case <-didClose:
  3699  	default:
  3700  		t.Errorf("didn't see Body.Close")
  3701  	}
  3702  }
  3703  
  3704  func TestTransportDialTLS(t *testing.T) {
  3705  	setParallel(t)
  3706  	defer afterTest(t)
  3707  	var mu sync.Mutex // guards following
  3708  	var gotReq, didDial bool
  3709  
  3710  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3711  		mu.Lock()
  3712  		gotReq = true
  3713  		mu.Unlock()
  3714  	}))
  3715  	defer ts.Close()
  3716  	c := ts.Client()
  3717  	c.Transport.(*Transport).DialTLS = func(netw, addr string) (net.Conn, error) {
  3718  		mu.Lock()
  3719  		didDial = true
  3720  		mu.Unlock()
  3721  		c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig)
  3722  		if err != nil {
  3723  			return nil, err
  3724  		}
  3725  		return c, c.Handshake()
  3726  	}
  3727  
  3728  	res, err := c.Get(ts.URL)
  3729  	if err != nil {
  3730  		t.Fatal(err)
  3731  	}
  3732  	_ = res.Body.Close()
  3733  	mu.Lock()
  3734  	if !gotReq {
  3735  		t.Error("didn't get request")
  3736  	}
  3737  	if !didDial {
  3738  		t.Error("didn't use dial hook")
  3739  	}
  3740  }
  3741  
  3742  func TestTransportDialContext(t *testing.T) {
  3743  	setParallel(t)
  3744  	defer afterTest(t)
  3745  	var mu sync.Mutex // guards following
  3746  	var gotReq bool
  3747  	var receivedContext context.Context
  3748  
  3749  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3750  		mu.Lock()
  3751  		gotReq = true
  3752  		mu.Unlock()
  3753  	}))
  3754  	defer ts.Close()
  3755  	c := ts.Client()
  3756  	c.Transport.(*Transport).DialContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
  3757  		mu.Lock()
  3758  		receivedContext = ctx
  3759  		mu.Unlock()
  3760  		return net.Dial(netw, addr)
  3761  	}
  3762  
  3763  	req, err := NewRequest("GET", ts.URL, nil)
  3764  	if err != nil {
  3765  		t.Fatal(err)
  3766  	}
  3767  	ctx := context.WithValue(context.Background(), "some-key", "some-value")
  3768  	res, err := c.Do(req.WithContext(ctx))
  3769  	if err != nil {
  3770  		t.Fatal(err)
  3771  	}
  3772  	_ = res.Body.Close()
  3773  	mu.Lock()
  3774  	if !gotReq {
  3775  		t.Error("didn't get request")
  3776  	}
  3777  	if receivedContext != ctx {
  3778  		t.Error("didn't receive correct context")
  3779  	}
  3780  }
  3781  
  3782  func TestTransportDialTLSContext(t *testing.T) {
  3783  	setParallel(t)
  3784  	defer afterTest(t)
  3785  	var mu sync.Mutex // guards following
  3786  	var gotReq bool
  3787  	var receivedContext context.Context
  3788  
  3789  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3790  		mu.Lock()
  3791  		gotReq = true
  3792  		mu.Unlock()
  3793  	}))
  3794  	defer ts.Close()
  3795  	c := ts.Client()
  3796  	c.Transport.(*Transport).DialTLSContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
  3797  		mu.Lock()
  3798  		receivedContext = ctx
  3799  		mu.Unlock()
  3800  		c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig)
  3801  		if err != nil {
  3802  			return nil, err
  3803  		}
  3804  		return c, c.HandshakeContext(ctx)
  3805  	}
  3806  
  3807  	req, err := NewRequest("GET", ts.URL, nil)
  3808  	if err != nil {
  3809  		t.Fatal(err)
  3810  	}
  3811  	ctx := context.WithValue(context.Background(), "some-key", "some-value")
  3812  	res, err := c.Do(req.WithContext(ctx))
  3813  	if err != nil {
  3814  		t.Fatal(err)
  3815  	}
  3816  	_ = res.Body.Close()
  3817  	mu.Lock()
  3818  	if !gotReq {
  3819  		t.Error("didn't get request")
  3820  	}
  3821  	if receivedContext != ctx {
  3822  		t.Error("didn't receive correct context")
  3823  	}
  3824  }
  3825  
  3826  // Test for issue 8755
  3827  // Ensure that if a proxy returns an error, it is exposed by RoundTrip
  3828  func TestRoundTripReturnsProxyError(t *testing.T) {
  3829  	badProxy := func(*Request) (*url.URL, error) {
  3830  		return nil, errors.New("errorMessage")
  3831  	}
  3832  
  3833  	tr := &Transport{Proxy: badProxy}
  3834  
  3835  	//goland:noinspection HttpUrlsUsage
  3836  	req, _ := NewRequest("GET", "http://example.com", nil)
  3837  
  3838  	_, err := tr.RoundTrip(req)
  3839  
  3840  	if err == nil {
  3841  		t.Error("Expected proxy error to be returned by RoundTrip")
  3842  	}
  3843  }
  3844  
  3845  // tests that putting an idle conn after a call to CloseIdleConns does return it
  3846  func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
  3847  	tr := &Transport{}
  3848  	wantIdle := func(when string, n int) bool {
  3849  		got := tr.IdleConnCountForTesting("http", "example.com") // key used by PutIdleTestConn
  3850  		if got == n {
  3851  			return true
  3852  		}
  3853  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  3854  		return false
  3855  	}
  3856  	wantIdle("start", 0)
  3857  	if !tr.PutIdleTestConn("http", "example.com") {
  3858  		t.Fatal("put failed")
  3859  	}
  3860  	if !tr.PutIdleTestConn("http", "example.com") {
  3861  		t.Fatal("second put failed")
  3862  	}
  3863  	wantIdle("after put", 2)
  3864  	tr.CloseIdleConnections()
  3865  	if !tr.IsIdleForTesting() {
  3866  		t.Error("should be idle after CloseIdleConnections")
  3867  	}
  3868  	wantIdle("after close idle", 0)
  3869  	if tr.PutIdleTestConn("http", "example.com") {
  3870  		t.Fatal("put didn't fail")
  3871  	}
  3872  	wantIdle("after second put", 0)
  3873  
  3874  	tr.QueueForIdleConnForTesting() // should toggle the transport out of idle mode
  3875  	if tr.IsIdleForTesting() {
  3876  		t.Error("shouldn't be idle after QueueForIdleConnForTesting")
  3877  	}
  3878  	if !tr.PutIdleTestConn("http", "example.com") {
  3879  		t.Fatal("after re-activation")
  3880  	}
  3881  	wantIdle("after final put", 1)
  3882  }
  3883  
  3884  // Test for issue 34282
  3885  // Ensure that getConn doesn't call the GotConn trace hook on a HTTP/2 idle conn
  3886  func TestTransportTraceGotConnH2IdleConns(t *testing.T) {
  3887  	tr := &Transport{}
  3888  	wantIdle := func(when string, n int) bool {
  3889  		got := tr.IdleConnCountForTesting("https", "example.com:443") // key used by PutIdleTestConnH2
  3890  		if got == n {
  3891  			return true
  3892  		}
  3893  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  3894  		return false
  3895  	}
  3896  	wantIdle("start", 0)
  3897  	alt := funcRoundTripper(func() {})
  3898  	if !tr.PutIdleTestConnH2("https", "example.com:443", alt) {
  3899  		t.Fatal("put failed")
  3900  	}
  3901  	wantIdle("after put", 1)
  3902  	ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  3903  		GotConn: func(httptrace.GotConnInfo) {
  3904  			// tr.getConn should leave it for the HTTP/2 alt to call GotConn.
  3905  			t.Error("GotConn called")
  3906  		},
  3907  	})
  3908  	req, _ := NewRequestWithContext(ctx, MethodGet, "https://example.com", nil)
  3909  	_, err := tr.RoundTrip(req)
  3910  	if err != errFakeRoundTrip {
  3911  		t.Errorf("got error: %v; want %q", err, errFakeRoundTrip)
  3912  	}
  3913  	wantIdle("after round trip", 1)
  3914  }
  3915  
  3916  func TestTransportRemovesH2ConnsAfterIdle(t *testing.T) {
  3917  	if testing.Short() {
  3918  		t.Skip("skipping in short mode")
  3919  	}
  3920  
  3921  	trFunc := func(tr *Transport) {
  3922  		tr.MaxConnsPerHost = 1
  3923  		tr.MaxIdleConnsPerHost = 1
  3924  		tr.IdleConnTimeout = 10 * time.Millisecond
  3925  	}
  3926  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), trFunc)
  3927  	defer cst.close()
  3928  
  3929  	if _, err := cst.c.Get(cst.ts.URL); err != nil {
  3930  		t.Fatalf("got error: %s", err)
  3931  	}
  3932  
  3933  	time.Sleep(100 * time.Millisecond)
  3934  	got := make(chan error)
  3935  	go func() {
  3936  		if _, err := cst.c.Get(cst.ts.URL); err != nil {
  3937  			got <- err
  3938  		}
  3939  		close(got)
  3940  	}()
  3941  
  3942  	timeout := time.NewTimer(5 * time.Second)
  3943  	defer timeout.Stop()
  3944  	select {
  3945  	case err := <-got:
  3946  		if err != nil {
  3947  			t.Fatalf("got error: %s", err)
  3948  		}
  3949  	case <-timeout.C:
  3950  		t.Fatal("request never completed")
  3951  	}
  3952  }
  3953  
  3954  // This tests that a client requesting a content range won't also
  3955  // implicitly ask for gzip support. If they want that, they need to do it
  3956  // on their own.
  3957  // golang.org/issue/8923
  3958  func TestTransportRangeAndGzip(t *testing.T) {
  3959  	defer afterTest(t)
  3960  	reqc := make(chan *Request, 1)
  3961  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3962  		reqc <- r
  3963  	}))
  3964  	defer ts.Close()
  3965  	c := ts.Client()
  3966  
  3967  	req, _ := NewRequest("GET", ts.URL, nil)
  3968  	req.Header.Set("Range", "bytes=7-11")
  3969  	res, err := c.Do(req)
  3970  	if err != nil {
  3971  		t.Fatal(err)
  3972  	}
  3973  
  3974  	select {
  3975  	case r := <-reqc:
  3976  		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  3977  			t.Error("Transport advertised gzip support in the Accept header")
  3978  		}
  3979  		if r.Header.Get("Range") == "" {
  3980  			t.Error("no Range in request")
  3981  		}
  3982  	case <-time.After(10 * time.Second):
  3983  		t.Fatal("timeout")
  3984  	}
  3985  	_ = res.Body.Close()
  3986  }
  3987  
  3988  // Test for issue 10474
  3989  func TestTransportResponseCancelRace(t *testing.T) {
  3990  	defer afterTest(t)
  3991  
  3992  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3993  		// important that this response has a body.
  3994  		var b [1024]byte
  3995  		_, _ = w.Write(b[:])
  3996  	}))
  3997  	defer ts.Close()
  3998  	tr := ts.Client().Transport.(*Transport)
  3999  
  4000  	req, err := NewRequest("GET", ts.URL, nil)
  4001  	if err != nil {
  4002  		t.Fatal(err)
  4003  	}
  4004  	res, err := tr.RoundTrip(req)
  4005  	if err != nil {
  4006  		t.Fatal(err)
  4007  	}
  4008  	// If we do an early close, Transport just throws the connection away and
  4009  	// doesn't reuse it. In order to trigger the bug, it has to reuse the connection
  4010  	// so read the body
  4011  	if _, err := io.Copy(io.Discard, res.Body); err != nil {
  4012  		t.Fatal(err)
  4013  	}
  4014  
  4015  	req2, err := NewRequest("GET", ts.URL, nil)
  4016  	if err != nil {
  4017  		t.Fatal(err)
  4018  	}
  4019  	tr.CancelRequest(req)
  4020  	res, err = tr.RoundTrip(req2)
  4021  	if err != nil {
  4022  		t.Fatal(err)
  4023  	}
  4024  	_ = res.Body.Close()
  4025  }
  4026  
  4027  // Test for issue 19248: Content-Encoding's value is case insensitive.
  4028  func TestTransportContentEncodingCaseInsensitive(t *testing.T) {
  4029  	setParallel(t)
  4030  	defer afterTest(t)
  4031  	for _, ce := range []string{"gzip", "GZIP"} {
  4032  		ce := ce
  4033  		t.Run(ce, func(t *testing.T) {
  4034  			const encodedString = "Hello Gopher"
  4035  			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4036  				w.Header().Set("Content-Encoding", ce)
  4037  				gz := gzip.NewWriter(w)
  4038  				_, _ = gz.Write([]byte(encodedString))
  4039  				_ = gz.Close()
  4040  			}))
  4041  			defer ts.Close()
  4042  
  4043  			res, err := ts.Client().Get(ts.URL)
  4044  			if err != nil {
  4045  				t.Fatal(err)
  4046  			}
  4047  
  4048  			body, err := io.ReadAll(res.Body)
  4049  			_ = res.Body.Close()
  4050  			if err != nil {
  4051  				t.Fatal(err)
  4052  			}
  4053  
  4054  			if string(body) != encodedString {
  4055  				t.Fatalf("Expected body %q, got: %q\n", encodedString, string(body))
  4056  			}
  4057  		})
  4058  	}
  4059  }
  4060  
  4061  func TestTransportDialCancelRace(t *testing.T) {
  4062  	defer afterTest(t)
  4063  
  4064  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  4065  	defer ts.Close()
  4066  	tr := ts.Client().Transport.(*Transport)
  4067  
  4068  	req, err := NewRequest("GET", ts.URL, nil)
  4069  	if err != nil {
  4070  		t.Fatal(err)
  4071  	}
  4072  	SetEnterRoundTripHook(func() {
  4073  		tr.CancelRequest(req)
  4074  	})
  4075  	defer SetEnterRoundTripHook(nil)
  4076  	res, err := tr.RoundTrip(req)
  4077  	if err != ExportErrRequestCanceled {
  4078  		t.Errorf("expected canceled request error; got %v", err)
  4079  		if err == nil {
  4080  			_ = res.Body.Close()
  4081  		}
  4082  	}
  4083  }
  4084  
  4085  // logWritesConn is a net.Conn that logs each Write call to writes
  4086  // and then proxies to w.
  4087  // It proxies Read calls to a reader it receives from rch.
  4088  type logWritesConn struct {
  4089  	net.Conn // nil. crash on use.
  4090  
  4091  	w io.Writer
  4092  
  4093  	rch <-chan io.Reader
  4094  	r   io.Reader // nil until received by rch
  4095  
  4096  	mu     sync.Mutex
  4097  	writes []string
  4098  }
  4099  
  4100  func (c *logWritesConn) Write(p []byte) (n int, err error) {
  4101  	c.mu.Lock()
  4102  	defer c.mu.Unlock()
  4103  	c.writes = append(c.writes, string(p))
  4104  	return c.w.Write(p)
  4105  }
  4106  
  4107  func (c *logWritesConn) Read(p []byte) (n int, err error) {
  4108  	if c.r == nil {
  4109  		c.r = <-c.rch
  4110  	}
  4111  	return c.r.Read(p)
  4112  }
  4113  
  4114  func (c *logWritesConn) Close() error { return nil }
  4115  
  4116  // Issue 6574
  4117  func TestTransportFlushesBodyChunks(t *testing.T) {
  4118  	defer afterTest(t)
  4119  	resBody := make(chan io.Reader, 1)
  4120  	connr, connw := io.Pipe() // connection pipe pair
  4121  	lw := &logWritesConn{
  4122  		rch: resBody,
  4123  		w:   connw,
  4124  	}
  4125  	tr := &Transport{
  4126  		Dial: func(network, addr string) (net.Conn, error) {
  4127  			return lw, nil
  4128  		},
  4129  	}
  4130  	bodyr, bodyw := io.Pipe() // body pipe pair
  4131  	go func() {
  4132  		defer func(bodyw *io.PipeWriter) {
  4133  			_ = bodyw.Close()
  4134  		}(bodyw)
  4135  		for i := 0; i < 3; i++ {
  4136  			_, _ = fmt.Fprintf(bodyw, "num%d\n", i)
  4137  		}
  4138  	}()
  4139  	resc := make(chan *Response)
  4140  	go func() {
  4141  		req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
  4142  		req.Header.Set("User-Agent", "x") // known value for test
  4143  		res, err := tr.RoundTrip(req)
  4144  		if err != nil {
  4145  			t.Errorf("RoundTrip: %v", err)
  4146  			close(resc)
  4147  			return
  4148  		}
  4149  		resc <- res
  4150  
  4151  	}()
  4152  	// Fully consume the request before checking the Write log vs. want.
  4153  	req, err := ReadRequest(bufio.NewReader(connr))
  4154  	if err != nil {
  4155  		t.Fatal(err)
  4156  	}
  4157  	_, _ = io.Copy(io.Discard, req.Body)
  4158  
  4159  	// Unblock the transport's roundTrip goroutine.
  4160  	resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
  4161  	res, ok := <-resc
  4162  	if !ok {
  4163  		return
  4164  	}
  4165  	defer func(Body io.ReadCloser) {
  4166  		_ = Body.Close()
  4167  	}(res.Body)
  4168  
  4169  	want := []string{
  4170  		"POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n",
  4171  		"5\r\nnum0\n\r\n",
  4172  		"5\r\nnum1\n\r\n",
  4173  		"5\r\nnum2\n\r\n",
  4174  		"0\r\n\r\n",
  4175  	}
  4176  	if !reflect.DeepEqual(lw.writes, want) {
  4177  		t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
  4178  	}
  4179  }
  4180  
  4181  // Issue 22088: flush Transport request headers if we're not sure the body won't block on read.
  4182  func TestTransportFlushesRequestHeader(t *testing.T) {
  4183  	defer afterTest(t)
  4184  	gotReq := make(chan struct{})
  4185  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4186  		close(gotReq)
  4187  	}))
  4188  	defer cst.close()
  4189  
  4190  	pr, pw := io.Pipe()
  4191  	req, err := NewRequest("POST", cst.ts.URL, pr)
  4192  	if err != nil {
  4193  		t.Fatal(err)
  4194  	}
  4195  	gotRes := make(chan struct{})
  4196  	go func() {
  4197  		defer close(gotRes)
  4198  		res, err := cst.tr.RoundTrip(req)
  4199  		if err != nil {
  4200  			t.Error(err)
  4201  			return
  4202  		}
  4203  		_ = res.Body.Close()
  4204  	}()
  4205  
  4206  	select {
  4207  	case <-gotReq:
  4208  		_ = pw.Close()
  4209  	case <-time.After(5 * time.Second):
  4210  		t.Fatal("timeout waiting for handler to get request")
  4211  	}
  4212  	<-gotRes
  4213  }
  4214  
  4215  // Issue 11745.
  4216  func TestTransportPrefersResponseOverWriteError(t *testing.T) {
  4217  	if testing.Short() {
  4218  		t.Skip("skipping in short mode")
  4219  	}
  4220  	defer afterTest(t)
  4221  	const contentLengthLimit = 1024 * 1024 // 1MB
  4222  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4223  		if r.ContentLength >= contentLengthLimit {
  4224  			w.WriteHeader(StatusBadRequest)
  4225  			_ = r.Body.Close()
  4226  			return
  4227  		}
  4228  		w.WriteHeader(StatusOK)
  4229  	}))
  4230  	defer ts.Close()
  4231  	c := ts.Client()
  4232  
  4233  	fail := 0
  4234  	count := 100
  4235  	bigBody := strings.Repeat("a", contentLengthLimit*2)
  4236  	for i := 0; i < count; i++ {
  4237  		req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
  4238  		if err != nil {
  4239  			t.Fatal(err)
  4240  		}
  4241  		resp, err := c.Do(req)
  4242  		if err != nil {
  4243  			fail++
  4244  			t.Logf("%d = %#v", i, err)
  4245  			if ue, ok := err.(*url.Error); ok {
  4246  				t.Logf("urlErr = %#v", ue.Err)
  4247  				if ne, ok := ue.Err.(*net.OpError); ok {
  4248  					t.Logf("netOpError = %#v", ne.Err)
  4249  				}
  4250  			}
  4251  		} else {
  4252  			_ = resp.Body.Close()
  4253  			if resp.StatusCode != 400 {
  4254  				t.Errorf("Expected status code 400, got %v", resp.Status)
  4255  			}
  4256  		}
  4257  	}
  4258  	if fail > 0 {
  4259  		t.Errorf("Failed %v out of %v\n", fail, count)
  4260  	}
  4261  }
  4262  
  4263  func TestTransportAutomaticHTTP2(t *testing.T) {
  4264  	testTransportAutoHTTP(t, &Transport{}, true)
  4265  }
  4266  
  4267  func TestTransportAutomaticHTTP2_DialerAndTLSConfigSupportsHTTP2AndTLSConfig(t *testing.T) {
  4268  	testTransportAutoHTTP(t, &Transport{
  4269  		ForceAttemptHTTP2: true,
  4270  		TLSClientConfig:   new(tls.Config),
  4271  	}, true)
  4272  }
  4273  
  4274  // golang.org/issue/14391: also check DefaultTransport
  4275  func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
  4276  	testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
  4277  }
  4278  
  4279  func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
  4280  	testTransportAutoHTTP(t, &Transport{
  4281  		TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
  4282  	}, false)
  4283  }
  4284  
  4285  func TestTransportAutomaticHTTP2_TLSConfig(t *testing.T) {
  4286  	testTransportAutoHTTP(t, &Transport{
  4287  		TLSClientConfig: new(tls.Config),
  4288  	}, false)
  4289  }
  4290  
  4291  func TestTransportAutomaticHTTP2_ExpectContinueTimeout(t *testing.T) {
  4292  	testTransportAutoHTTP(t, &Transport{
  4293  		ExpectContinueTimeout: 1 * time.Second,
  4294  	}, true)
  4295  }
  4296  
  4297  func TestTransportAutomaticHTTP2_Dial(t *testing.T) {
  4298  	var d net.Dialer
  4299  	testTransportAutoHTTP(t, &Transport{
  4300  		Dial: d.Dial,
  4301  	}, false)
  4302  }
  4303  
  4304  func TestTransportAutomaticHTTP2_DialContext(t *testing.T) {
  4305  	var d net.Dialer
  4306  	testTransportAutoHTTP(t, &Transport{
  4307  		DialContext: d.DialContext,
  4308  	}, false)
  4309  }
  4310  
  4311  func TestTransportAutomaticHTTP2_DialTLS(t *testing.T) {
  4312  	testTransportAutoHTTP(t, &Transport{
  4313  		DialTLS: func(network, addr string) (net.Conn, error) {
  4314  			panic("unused")
  4315  		},
  4316  	}, false)
  4317  }
  4318  
  4319  func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) {
  4320  	CondSkipHTTP2(t)
  4321  	_, err := tr.RoundTrip(new(Request))
  4322  	if err == nil {
  4323  		t.Error("expected error from RoundTrip")
  4324  	}
  4325  	if reg := tr.TLSNextProto["h2"] != nil; reg != wantH2 {
  4326  		t.Errorf("HTTP/2 registered = %v; want %v", reg, wantH2)
  4327  	}
  4328  }
  4329  
  4330  // Issue 13633: there was a race where we returned bodyless responses
  4331  // to callers before recycling the persistent connection, which meant
  4332  // a client doing two subsequent requests could end up on different
  4333  // connections. It's somewhat harmless but enough tests assume it's
  4334  // not true in order to test other things that it's worth fixing.
  4335  // Plus it's nice to be consistent and not have timing-dependent
  4336  // behavior.
  4337  func TestTransportReuseConnEmptyResponseBody(t *testing.T) {
  4338  	defer afterTest(t)
  4339  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4340  		w.Header().Set("X-Addr", r.RemoteAddr)
  4341  		// Empty response body.
  4342  	}))
  4343  	defer cst.close()
  4344  	n := 100
  4345  	if testing.Short() {
  4346  		n = 10
  4347  	}
  4348  	var firstAddr string
  4349  	for i := 0; i < n; i++ {
  4350  		res, err := cst.c.Get(cst.ts.URL)
  4351  		if err != nil {
  4352  			log.Fatal(err)
  4353  		}
  4354  		addr := res.Header.Get("X-Addr")
  4355  		if i == 0 {
  4356  			firstAddr = addr
  4357  		} else if addr != firstAddr {
  4358  			t.Fatalf("On request %d, addr %q != original addr %q", i+1, addr, firstAddr)
  4359  		}
  4360  		_ = res.Body.Close()
  4361  	}
  4362  }
  4363  
  4364  // Issue 13839
  4365  func TestNoCrashReturningTransportAltConn(t *testing.T) {
  4366  	cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
  4367  	if err != nil {
  4368  		t.Fatal(err)
  4369  	}
  4370  	ln := newLocalListener(t)
  4371  	defer func(ln net.Listener) {
  4372  		_ = ln.Close()
  4373  	}(ln)
  4374  
  4375  	var wg sync.WaitGroup
  4376  	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  4377  	defer SetPendingDialHooks(nil, nil)
  4378  
  4379  	testDone := make(chan struct{})
  4380  	defer close(testDone)
  4381  	go func() {
  4382  		tln := tls.NewListener(ln, &tls.Config{
  4383  			NextProtos:   []string{"foo"},
  4384  			Certificates: []tls.Certificate{cert},
  4385  		})
  4386  		sc, err := tln.Accept()
  4387  		if err != nil {
  4388  			t.Error(err)
  4389  			return
  4390  		}
  4391  		if err := sc.(*tls.Conn).Handshake(); err != nil {
  4392  			t.Error(err)
  4393  			return
  4394  		}
  4395  		<-testDone
  4396  		_ = sc.Close()
  4397  	}()
  4398  
  4399  	addr := ln.Addr().String()
  4400  
  4401  	req, _ := NewRequest("GET", "https://fake.tld/", nil)
  4402  	cancel := make(chan struct{})
  4403  	req.Cancel = cancel
  4404  
  4405  	doReturned := make(chan bool, 1)
  4406  	madeRoundTripper := make(chan bool, 1)
  4407  
  4408  	tr := &Transport{
  4409  		DisableKeepAlives: true,
  4410  		TLSNextProto: map[string]func(string, *tls.Conn) RoundTripper{
  4411  			"foo": func(authority string, c *tls.Conn) RoundTripper {
  4412  				madeRoundTripper <- true
  4413  				return funcRoundTripper(func() {
  4414  					t.Error("foo RoundTripper should not be called")
  4415  				})
  4416  			},
  4417  		},
  4418  		Dial: func(_, _ string) (net.Conn, error) {
  4419  			panic("shouldn't be called")
  4420  		},
  4421  		DialTLS: func(_, _ string) (net.Conn, error) {
  4422  			tc, err := tls.Dial("tcp", addr, &tls.Config{
  4423  				InsecureSkipVerify: true,
  4424  				NextProtos:         []string{"foo"},
  4425  			})
  4426  			if err != nil {
  4427  				return nil, err
  4428  			}
  4429  			if err := tc.Handshake(); err != nil {
  4430  				return nil, err
  4431  			}
  4432  			close(cancel)
  4433  			<-doReturned
  4434  			return tc, nil
  4435  		},
  4436  	}
  4437  	c := &Client{Transport: tr}
  4438  
  4439  	_, err = c.Do(req)
  4440  	if ue, ok := err.(*url.Error); !ok || ue.Err != ExportErrRequestCanceledConn {
  4441  		t.Fatalf("Do error = %v; want url.Error with errRequestCanceledConn", err)
  4442  	}
  4443  
  4444  	doReturned <- true
  4445  	<-madeRoundTripper
  4446  	wg.Wait()
  4447  }
  4448  
  4449  func TestTransportReuseConnection_Gzip_Chunked(t *testing.T) {
  4450  	testTransportReuseConnection_Gzip(t, true)
  4451  }
  4452  
  4453  func TestTransportReuseConnection_Gzip_ContentLength(t *testing.T) {
  4454  	testTransportReuseConnection_Gzip(t, false)
  4455  }
  4456  
  4457  // Make sure we re-use underlying TCP connection for gzipped responses too.
  4458  //goland:noinspection GoSnakeCaseUsage
  4459  func testTransportReuseConnection_Gzip(t *testing.T, chunked bool) {
  4460  	setParallel(t)
  4461  	defer afterTest(t)
  4462  	addr := make(chan string, 2)
  4463  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4464  		addr <- r.RemoteAddr
  4465  		w.Header().Set("Content-Encoding", "gzip")
  4466  		if chunked {
  4467  			w.(Flusher).Flush()
  4468  		}
  4469  		_, _ = w.Write(rgz) // arbitrary gzip response
  4470  	}))
  4471  	defer ts.Close()
  4472  	c := ts.Client()
  4473  
  4474  	for i := 0; i < 2; i++ {
  4475  		res, err := c.Get(ts.URL)
  4476  		if err != nil {
  4477  			t.Fatal(err)
  4478  		}
  4479  		buf := make([]byte, len(rgz))
  4480  		if n, err := io.ReadFull(res.Body, buf); err != nil {
  4481  			t.Errorf("%d. ReadFull = %v, %v", i, n, err)
  4482  		}
  4483  		// Note: no res.Body.Close call. It should work without it,
  4484  		// since the flate.Reader's internal buffering will hit EOF
  4485  		// and that should be sufficient.
  4486  	}
  4487  	a1, a2 := <-addr, <-addr
  4488  	if a1 != a2 {
  4489  		t.Fatalf("didn't reuse connection")
  4490  	}
  4491  }
  4492  
  4493  func TestTransportResponseHeaderLength(t *testing.T) {
  4494  	setParallel(t)
  4495  	defer afterTest(t)
  4496  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4497  		if r.URL.Path == "/long" {
  4498  			w.Header().Set("Long", strings.Repeat("a", 1<<20))
  4499  		}
  4500  	}))
  4501  	defer ts.Close()
  4502  	c := ts.Client()
  4503  	c.Transport.(*Transport).MaxResponseHeaderBytes = 512 << 10
  4504  
  4505  	if res, err := c.Get(ts.URL); err != nil {
  4506  		t.Fatal(err)
  4507  	} else {
  4508  		_ = res.Body.Close()
  4509  	}
  4510  
  4511  	res, err := c.Get(ts.URL + "/long")
  4512  	if err == nil {
  4513  		defer func(Body io.ReadCloser) {
  4514  			_ = Body.Close()
  4515  		}(res.Body)
  4516  		var n int64
  4517  		for k, vv := range res.Header {
  4518  			for _, v := range vv {
  4519  				n += int64(len(k)) + int64(len(v))
  4520  			}
  4521  		}
  4522  		t.Fatalf("Unexpected success. Got %v and %d bytes of response headers", res.Status, n)
  4523  	}
  4524  	if want := "server response headers exceeded 524288 bytes"; !strings.Contains(err.Error(), want) {
  4525  		t.Errorf("got error: %v; want %q", err, want)
  4526  	}
  4527  }
  4528  
  4529  // func TestTransportEventTrace(t *testing.T)    { testTransportEventTrace(t, h1Mode, false) }
  4530  // func TestTransportEventTrace_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, false) }
  4531  
  4532  // // test a non-nil httptrace.ClientTrace but with all hooks set to zero.
  4533  // func TestTransportEventTrace_NoHooks(t *testing.T)    { testTransportEventTrace(t, h1Mode, true) }
  4534  // func TestTransportEventTrace_NoHooks_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, true) }
  4535  
  4536  //goland:noinspection GoUnusedFunction
  4537  func testTransportEventTrace(t *testing.T, h2 bool, noHooks bool) {
  4538  	defer afterTest(t)
  4539  	const resBody = "some body"
  4540  	gotWroteReqEvent := make(chan struct{}, 500)
  4541  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  4542  		if r.Method == "GET" {
  4543  			// Do nothing for the second request.
  4544  			return
  4545  		}
  4546  		if _, err := io.ReadAll(r.Body); err != nil {
  4547  			t.Error(err)
  4548  		}
  4549  		if !noHooks {
  4550  			select {
  4551  			case <-gotWroteReqEvent:
  4552  			case <-time.After(5 * time.Second):
  4553  				t.Error("timeout waiting for WroteRequest event")
  4554  			}
  4555  		}
  4556  		_, _ = io.WriteString(w, resBody)
  4557  	}))
  4558  	defer cst.close()
  4559  
  4560  	cst.tr.ExpectContinueTimeout = 1 * time.Second
  4561  
  4562  	var mu sync.Mutex // guards buf
  4563  	var buf bytes.Buffer
  4564  	logf := func(format string, args ...interface{}) {
  4565  		mu.Lock()
  4566  		defer mu.Unlock()
  4567  		_, _ = fmt.Fprintf(&buf, format, args...)
  4568  		buf.WriteByte('\n')
  4569  	}
  4570  
  4571  	addrStr := cst.ts.Listener.Addr().String()
  4572  	ip, port, err := net.SplitHostPort(addrStr)
  4573  	if err != nil {
  4574  		t.Fatal(err)
  4575  	}
  4576  
  4577  	// Install a fake DNS server.
  4578  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, network, host string) ([]net.IPAddr, error) {
  4579  		if host != "dns-is-faked.golang" {
  4580  			t.Errorf("unexpected DNS host lookup for %q/%q", network, host)
  4581  			return nil, nil
  4582  		}
  4583  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  4584  	})
  4585  
  4586  	body := "some body"
  4587  	req, _ := NewRequest("POST", cst.scheme()+"://dns-is-faked.golang:"+port, strings.NewReader(body))
  4588  	req.Header["X-Foo-Multiple-Vals"] = []string{"bar", "baz"}
  4589  	trace := &httptrace.ClientTrace{
  4590  		GetConn:              func(hostPort string) { logf("Getting conn for %v ...", hostPort) },
  4591  		GotConn:              func(ci httptrace.GotConnInfo) { logf("got conn: %+v", ci) },
  4592  		GotFirstResponseByte: func() { logf("first response byte") },
  4593  		PutIdleConn:          func(err error) { logf("PutIdleConn = %v", err) },
  4594  		DNSStart:             func(e httptrace.DNSStartInfo) { logf("DNS start: %+v", e) },
  4595  		DNSDone:              func(e httptrace.DNSDoneInfo) { logf("DNS done: %+v", e) },
  4596  		ConnectStart:         func(network, addr string) { logf("ConnectStart: Connecting to %s %s ...", network, addr) },
  4597  		ConnectDone: func(network, addr string, err error) {
  4598  			if err != nil {
  4599  				t.Errorf("ConnectDone: %v", err)
  4600  			}
  4601  			logf("ConnectDone: connected to %s %s = %v", network, addr, err)
  4602  		},
  4603  		WroteHeaderField: func(key string, value []string) {
  4604  			logf("WroteHeaderField: %s: %v", key, value)
  4605  		},
  4606  		WroteHeaders: func() {
  4607  			logf("WroteHeaders")
  4608  		},
  4609  		Wait100Continue: func() { logf("Wait100Continue") },
  4610  		Got100Continue:  func() { logf("Got100Continue") },
  4611  		WroteRequest: func(e httptrace.WroteRequestInfo) {
  4612  			logf("WroteRequest: %+v", e)
  4613  			gotWroteReqEvent <- struct{}{}
  4614  		},
  4615  	}
  4616  	if h2 {
  4617  		trace.TLSHandshakeStart = func() { logf("tls handshake start") }
  4618  		trace.TLSHandshakeDone = func(s tls.ConnectionState, err error) {
  4619  			logf("tls handshake done. ConnectionState = %v \n err = %v", s, err)
  4620  		}
  4621  	}
  4622  	if noHooks {
  4623  		// zero out all func pointers, trying to get some path to crash
  4624  		*trace = httptrace.ClientTrace{}
  4625  	}
  4626  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  4627  
  4628  	req.Header.Set("Expect", "100-continue")
  4629  	res, err := cst.c.Do(req)
  4630  	if err != nil {
  4631  		t.Fatal(err)
  4632  	}
  4633  	logf("got roundtrip.response")
  4634  	slurp, err := io.ReadAll(res.Body)
  4635  	if err != nil {
  4636  		t.Fatal(err)
  4637  	}
  4638  	logf("consumed body")
  4639  	if string(slurp) != resBody || res.StatusCode != 200 {
  4640  		t.Fatalf("Got %q, %v; want %q, 200 OK", slurp, res.Status, resBody)
  4641  	}
  4642  	_ = res.Body.Close()
  4643  
  4644  	if noHooks {
  4645  		// Done at this point. Just testing a full HTTP
  4646  		// requests can happen with a trace pointing to a zero
  4647  		// ClientTrace, full of nil func pointers.
  4648  		return
  4649  	}
  4650  
  4651  	mu.Lock()
  4652  	got := buf.String()
  4653  	mu.Unlock()
  4654  
  4655  	wantOnce := func(sub string) {
  4656  		if strings.Count(got, sub) != 1 {
  4657  			t.Errorf("expected substring %q exactly once in output.", sub)
  4658  		}
  4659  	}
  4660  	wantOnceOrMore := func(sub string) {
  4661  		if strings.Count(got, sub) == 0 {
  4662  			t.Errorf("expected substring %q at least once in output.", sub)
  4663  		}
  4664  	}
  4665  	wantOnce("Getting conn for dns-is-faked.golang:" + port)
  4666  	wantOnce("DNS start: {Host:dns-is-faked.golang}")
  4667  	wantOnce("DNS done: {Addrs:[{IP:" + ip + " Zone:}] Err:<nil> Coalesced:false}")
  4668  	wantOnce("got conn: {")
  4669  	wantOnceOrMore("Connecting to tcp " + addrStr)
  4670  	wantOnceOrMore("connected to tcp " + addrStr + " = <nil>")
  4671  	wantOnce("Reused:false WasIdle:false IdleTime:0s")
  4672  	wantOnce("first response byte")
  4673  	if h2 {
  4674  		wantOnce("tls handshake start")
  4675  		wantOnce("tls handshake done")
  4676  	} else {
  4677  		wantOnce("PutIdleConn = <nil>")
  4678  		wantOnce("WroteHeaderField: User-Agent: [Go-http-client/1.1]")
  4679  		// TODO(meirf): issue 19761. Make these agnostic to h1/h2. (These are not h1 specific, but the
  4680  		// WroteHeaderField hook is not yet implemented in h2.)
  4681  		wantOnce(fmt.Sprintf("WroteHeaderField: Host: [dns-is-faked.golang:%s]", port))
  4682  		wantOnce(fmt.Sprintf("WroteHeaderField: Content-Length: [%d]", len(body)))
  4683  		wantOnce("WroteHeaderField: X-Foo-Multiple-Vals: [bar baz]")
  4684  		wantOnce("WroteHeaderField: Accept-Encoding: [gzip]")
  4685  	}
  4686  	wantOnce("WroteHeaders")
  4687  	wantOnce("Wait100Continue")
  4688  	wantOnce("Got100Continue")
  4689  	wantOnce("WroteRequest: {Err:<nil>}")
  4690  	if strings.Contains(got, " to udp ") {
  4691  		t.Errorf("should not see UDP (DNS) connections")
  4692  	}
  4693  	if t.Failed() {
  4694  		t.Errorf("Output:\n%s", got)
  4695  	}
  4696  
  4697  	// And do a second request:
  4698  	req, _ = NewRequest("GET", cst.scheme()+"://dns-is-faked.golang:"+port, nil)
  4699  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  4700  	res, err = cst.c.Do(req)
  4701  	if err != nil {
  4702  		t.Fatal(err)
  4703  	}
  4704  	if res.StatusCode != 200 {
  4705  		t.Fatal(res.Status)
  4706  	}
  4707  	_ = res.Body.Close()
  4708  
  4709  	mu.Lock()
  4710  	got = buf.String()
  4711  	mu.Unlock()
  4712  
  4713  	sub := "Getting conn for dns-is-faked.golang:"
  4714  	if gotn, want := strings.Count(got, sub), 2; gotn != want {
  4715  		t.Errorf("substring %q appeared %d times; want %d. Log:\n%s", sub, gotn, want, got)
  4716  	}
  4717  
  4718  }
  4719  
  4720  func TestTransportEventTraceTLSVerify(t *testing.T) {
  4721  	var mu sync.Mutex
  4722  	var buf bytes.Buffer
  4723  	logf := func(format string, args ...interface{}) {
  4724  		mu.Lock()
  4725  		defer mu.Unlock()
  4726  		_, _ = fmt.Fprintf(&buf, format, args...)
  4727  		buf.WriteByte('\n')
  4728  	}
  4729  
  4730  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4731  		t.Error("Unexpected request")
  4732  	}))
  4733  	defer ts.Close()
  4734  	ts.Config.ErrorLog = log.New(funcWriter(func(p []byte) (int, error) {
  4735  		logf("%s", p)
  4736  		return len(p), nil
  4737  	}), "", 0)
  4738  
  4739  	certpool := x509.NewCertPool()
  4740  	certpool.AddCert(ts.Certificate())
  4741  
  4742  	c := &Client{Transport: &Transport{
  4743  		TLSClientConfig: &tls.Config{
  4744  			ServerName: "dns-is-faked.golang",
  4745  			RootCAs:    certpool,
  4746  		},
  4747  	}}
  4748  
  4749  	trace := &httptrace.ClientTrace{
  4750  		TLSHandshakeStart: func() { logf("TLSHandshakeStart") },
  4751  		TLSHandshakeDone: func(s tls.ConnectionState, err error) {
  4752  			logf("TLSHandshakeDone: ConnectionState = %v \n err = %v", s, err)
  4753  		},
  4754  	}
  4755  
  4756  	req, _ := NewRequest("GET", ts.URL, nil)
  4757  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  4758  	_, err := c.Do(req)
  4759  	if err == nil {
  4760  		t.Error("Expected request to fail TLS verification")
  4761  	}
  4762  
  4763  	mu.Lock()
  4764  	got := buf.String()
  4765  	mu.Unlock()
  4766  
  4767  	wantOnce := func(sub string) {
  4768  		if strings.Count(got, sub) != 1 {
  4769  			t.Errorf("expected substring %q exactly once in output.", sub)
  4770  		}
  4771  	}
  4772  
  4773  	wantOnce("TLSHandshakeStart")
  4774  	wantOnce("TLSHandshakeDone")
  4775  	wantOnce("err = x509: certificate is valid for example.com")
  4776  
  4777  	if t.Failed() {
  4778  		t.Errorf("Output:\n%s", got)
  4779  	}
  4780  }
  4781  
  4782  var (
  4783  	isDNSHijackedOnce sync.Once
  4784  	isDNSHijacked     bool
  4785  )
  4786  
  4787  //goland:noinspection GoUnusedFunction
  4788  func skipIfDNSHijacked(t *testing.T) {
  4789  	// Skip this test if the user is using a shady/ISP
  4790  	// DNS server hijacking queries.
  4791  	// See issues 16732, 16716.
  4792  	isDNSHijackedOnce.Do(func() {
  4793  		addrs, _ := net.LookupHost("dns-should-not-resolve.golang")
  4794  		isDNSHijacked = len(addrs) != 0
  4795  	})
  4796  	if isDNSHijacked {
  4797  		t.Skip("skipping; test requires non-hijacking DNS server")
  4798  	}
  4799  }
  4800  
  4801  // func TestTransportEventTraceRealDNS(t *testing.T) {
  4802  // 	skipIfDNSHijacked(t)
  4803  // 	defer afterTest(t)
  4804  // 	tr := &Transport{}
  4805  // 	defer tr.CloseIdleConnections()
  4806  // 	c := &Client{Transport: tr}
  4807  
  4808  // 	var mu sync.Mutex // guards buf
  4809  // 	var buf bytes.Buffer
  4810  // 	logf := func(format string, args ...interface{}) {
  4811  // 		mu.Lock()
  4812  // 		defer mu.Unlock()
  4813  // 		fmt.Fprintf(&buf, format, args...)
  4814  // 		buf.WriteByte('\n')
  4815  // 	}
  4816  
  4817  // 	req, _ := NewRequest("GET", "http://dns-should-not-resolve.golang:80", nil)
  4818  // 	trace := &httptrace.ClientTrace{
  4819  // 		DNSStart:     func(e httptrace.DNSStartInfo) { logf("DNSStart: %+v", e) },
  4820  // 		DNSDone:      func(e httptrace.DNSDoneInfo) { logf("DNSDone: %+v", e) },
  4821  // 		ConnectStart: func(network, addr string) { logf("ConnectStart: %s %s", network, addr) },
  4822  // 		ConnectDone:  func(network, addr string, err error) { logf("ConnectDone: %s %s %v", network, addr, err) },
  4823  // 	}
  4824  // 	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  4825  
  4826  // 	resp, err := c.Do(req)
  4827  // 	if err == nil {
  4828  // 		resp.Body.Close()
  4829  // 		t.Fatal("expected error during DNS lookup")
  4830  // 	}
  4831  
  4832  // 	mu.Lock()
  4833  // 	got := buf.String()
  4834  // 	mu.Unlock()
  4835  
  4836  // 	wantSub := func(sub string) {
  4837  // 		if !strings.Contains(got, sub) {
  4838  // 			t.Errorf("expected substring %q in output.", sub)
  4839  // 		}
  4840  // 	}
  4841  // 	wantSub("DNSStart: {Host:dns-should-not-resolve.golang}")
  4842  // 	wantSub("DNSDone: {Addrs:[] Err:")
  4843  // 	if strings.Contains(got, "ConnectStart") || strings.Contains(got, "ConnectDone") {
  4844  // 		t.Errorf("should not see Connect events")
  4845  // 	}
  4846  // 	if t.Failed() {
  4847  // 		t.Errorf("Output:\n%s", got)
  4848  // 	}
  4849  // }
  4850  
  4851  // Issue 14353: port can only contain digits.
  4852  func TestTransportRejectsAlphaPort(t *testing.T) {
  4853  	//goland:noinspection HttpUrlsUsage
  4854  	res, err := Get("http://dummy.tld:123foo/bar")
  4855  	if err == nil {
  4856  		_ = res.Body.Close()
  4857  		t.Fatal("unexpected success")
  4858  	}
  4859  	ue, ok := err.(*url.Error)
  4860  	if !ok {
  4861  		t.Fatalf("got %#v; want *url.Error", err)
  4862  	}
  4863  	got := ue.Err.Error()
  4864  	want := `invalid port ":123foo" after host`
  4865  	if got != want {
  4866  		t.Errorf("got error %q; want %q", got, want)
  4867  	}
  4868  }
  4869  
  4870  // Test the httptrace.TLSHandshake{Start,Done} hooks with a https http1
  4871  // connections. The http2 test is done in TestTransportEventTrace_h2
  4872  func TestTLSHandshakeTrace(t *testing.T) {
  4873  	defer afterTest(t)
  4874  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  4875  	defer ts.Close()
  4876  
  4877  	var mu sync.Mutex
  4878  	var start, done bool
  4879  	trace := &httptrace.ClientTrace{
  4880  		TLSHandshakeStart: func() {
  4881  			mu.Lock()
  4882  			defer mu.Unlock()
  4883  			start = true
  4884  		},
  4885  		TLSHandshakeDone: func(s tls.ConnectionState, err error) {
  4886  			mu.Lock()
  4887  			defer mu.Unlock()
  4888  			done = true
  4889  			if err != nil {
  4890  				t.Fatal("Expected error to be nil but was:", err)
  4891  			}
  4892  		},
  4893  	}
  4894  
  4895  	c := ts.Client()
  4896  	req, err := NewRequest("GET", ts.URL, nil)
  4897  	if err != nil {
  4898  		t.Fatal("Unable to construct test request:", err)
  4899  	}
  4900  	req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
  4901  
  4902  	r, err := c.Do(req)
  4903  	if err != nil {
  4904  		t.Fatal("Unexpected error making request:", err)
  4905  	}
  4906  	_ = r.Body.Close()
  4907  	mu.Lock()
  4908  	defer mu.Unlock()
  4909  	if !start {
  4910  		t.Fatal("Expected TLSHandshakeStart to be called, but wasn't")
  4911  	}
  4912  	if !done {
  4913  		t.Fatal("Expected TLSHandshakeDone to be called, but wasnt't")
  4914  	}
  4915  }
  4916  
  4917  // func TestTransportMaxIdleConns(t *testing.T) {
  4918  // 	defer afterTest(t)
  4919  // 	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4920  // 		// No body for convenience.
  4921  // 	}))
  4922  // 	defer ts.Close()
  4923  // 	c := ts.Client()
  4924  // 	tr := c.Transport.(*Transport)
  4925  // 	tr.MaxIdleConns = 4
  4926  
  4927  // 	ip, port, err := net.SplitHostPort(ts.Listener.Addr().String())
  4928  // 	if err != nil {
  4929  // 		t.Fatal(err)
  4930  // 	}
  4931  // 	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, _, host string) ([]net.IPAddr, error) {
  4932  // 		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  4933  // 	})
  4934  
  4935  // 	hitHost := func(n int) {
  4936  // 		req, _ := NewRequest("GET", fmt.Sprintf("http://host-%d.dns-is-faked.golang:"+port, n), nil)
  4937  // 		req = req.WithContext(ctx)
  4938  // 		res, err := c.Do(req)
  4939  // 		if err != nil {
  4940  // 			t.Fatal(err)
  4941  // 		}
  4942  // 		res.Body.Close()
  4943  // 	}
  4944  // 	for i := 0; i < 4; i++ {
  4945  // 		hitHost(i)
  4946  // 	}
  4947  // 	want := []string{
  4948  // 		"|http|host-0.dns-is-faked.golang:" + port,
  4949  // 		"|http|host-1.dns-is-faked.golang:" + port,
  4950  // 		"|http|host-2.dns-is-faked.golang:" + port,
  4951  // 		"|http|host-3.dns-is-faked.golang:" + port,
  4952  // 	}
  4953  // 	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  4954  // 		t.Fatalf("idle conn keys mismatch.\n got: %q\nwant: %q\n", got, want)
  4955  // 	}
  4956  
  4957  // 	// Now hitting the 5th host should kick out the first host:
  4958  // 	hitHost(4)
  4959  // 	want = []string{
  4960  // 		"|http|host-1.dns-is-faked.golang:" + port,
  4961  // 		"|http|host-2.dns-is-faked.golang:" + port,
  4962  // 		"|http|host-3.dns-is-faked.golang:" + port,
  4963  // 		"|http|host-4.dns-is-faked.golang:" + port,
  4964  // 	}
  4965  // 	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  4966  // 		t.Fatalf("idle conn keys mismatch after 5th host.\n got: %q\nwant: %q\n", got, want)
  4967  // 	}
  4968  // }
  4969  
  4970  func TestTransportIdleConnTimeout_h1(t *testing.T) { testTransportIdleConnTimeout(t, h1Mode) }
  4971  func TestTransportIdleConnTimeout_h2(t *testing.T) { testTransportIdleConnTimeout(t, h2Mode) }
  4972  func testTransportIdleConnTimeout(t *testing.T, h2 bool) {
  4973  	if testing.Short() {
  4974  		t.Skip("skipping in short mode")
  4975  	}
  4976  	defer afterTest(t)
  4977  
  4978  	const timeout = 1 * time.Second
  4979  
  4980  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  4981  		// No body for convenience.
  4982  	}))
  4983  	defer cst.close()
  4984  	tr := cst.tr
  4985  	tr.IdleConnTimeout = timeout
  4986  	defer tr.CloseIdleConnections()
  4987  	c := &Client{Transport: tr}
  4988  
  4989  	idleConns := func() []string {
  4990  		if h2 {
  4991  			return tr.IdleConnStrsForTesting_h2()
  4992  		} else {
  4993  			return tr.IdleConnStrsForTesting()
  4994  		}
  4995  	}
  4996  
  4997  	var conn string
  4998  	doReq := func(n int) {
  4999  		req, _ := NewRequest("GET", cst.ts.URL, nil)
  5000  		req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  5001  			PutIdleConn: func(err error) {
  5002  				if err != nil {
  5003  					t.Errorf("failed to keep idle conn: %v", err)
  5004  				}
  5005  			},
  5006  		}))
  5007  		res, err := c.Do(req)
  5008  		if err != nil {
  5009  			t.Fatal(err)
  5010  		}
  5011  		_ = res.Body.Close()
  5012  		conns := idleConns()
  5013  		if len(conns) != 1 {
  5014  			t.Fatalf("req %v: unexpected number of idle conns: %q", n, conns)
  5015  		}
  5016  		if conn == "" {
  5017  			conn = conns[0]
  5018  		}
  5019  		if conn != conns[0] {
  5020  			t.Fatalf("req %v: cached connection changed; expected the same one throughout the test", n)
  5021  		}
  5022  	}
  5023  	for i := 0; i < 3; i++ {
  5024  		doReq(i)
  5025  		time.Sleep(timeout / 2)
  5026  	}
  5027  	time.Sleep(timeout * 3 / 2)
  5028  	if got := idleConns(); len(got) != 0 {
  5029  		t.Errorf("idle conns = %q; want none", got)
  5030  	}
  5031  }
  5032  
  5033  // Issue 16208: Go 1.7 crashed after Transport.IdleConnTimeout if an
  5034  // HTTP/2 connection was established but its caller no longer
  5035  // wanted it. (Assuming the connection cache was enabled, which it is
  5036  // by default)
  5037  //
  5038  // This test reproduced the crash by setting the IdleConnTimeout low
  5039  // (to make the test reasonable) and then making a request which is
  5040  // canceled by the DialTLS hook, which then also waits to return the
  5041  // real connection until after the RoundTrip saw the error.  Then we
  5042  // know the successful tls.Dial from DialTLS will need to go into the
  5043  // idle pool. Then we give it a of time to explode.
  5044  func TestIdleConnH2Crash(t *testing.T) {
  5045  	setParallel(t)
  5046  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5047  		// nothing
  5048  	}))
  5049  	defer cst.close()
  5050  
  5051  	ctx, cancel := context.WithCancel(context.Background())
  5052  	defer cancel()
  5053  
  5054  	sawDoErr := make(chan bool, 1)
  5055  	testDone := make(chan struct{})
  5056  	defer close(testDone)
  5057  
  5058  	cst.tr.IdleConnTimeout = 5 * time.Millisecond
  5059  	cst.tr.DialTLS = func(network, addr string) (net.Conn, error) {
  5060  		c, err := tls.Dial(network, addr, &tls.Config{
  5061  			InsecureSkipVerify: true,
  5062  			NextProtos:         []string{"h2"},
  5063  		})
  5064  		if err != nil {
  5065  			t.Error(err)
  5066  			return nil, err
  5067  		}
  5068  		if cs := c.ConnectionState(); cs.NegotiatedProtocol != "h2" {
  5069  			t.Errorf("protocol = %q; want %q", cs.NegotiatedProtocol, "h2")
  5070  			_ = c.Close()
  5071  			return nil, errors.New("bogus")
  5072  		}
  5073  
  5074  		cancel()
  5075  
  5076  		failTimer := time.NewTimer(5 * time.Second)
  5077  		defer failTimer.Stop()
  5078  		select {
  5079  		case <-sawDoErr:
  5080  		case <-testDone:
  5081  		case <-failTimer.C:
  5082  			t.Error("timeout in DialTLS, waiting too long for cst.c.Do to fail")
  5083  		}
  5084  		return c, nil
  5085  	}
  5086  
  5087  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  5088  	req = req.WithContext(ctx)
  5089  	res, err := cst.c.Do(req)
  5090  	if err == nil {
  5091  		_ = res.Body.Close()
  5092  		t.Fatal("unexpected success")
  5093  	}
  5094  	sawDoErr <- true
  5095  
  5096  	// Wait for the explosion.
  5097  	time.Sleep(cst.tr.IdleConnTimeout * 10)
  5098  }
  5099  
  5100  type funcConn struct {
  5101  	net.Conn
  5102  	read  func([]byte) (int, error)
  5103  	write func([]byte) (int, error)
  5104  }
  5105  
  5106  func (c funcConn) Read(p []byte) (int, error)  { return c.read(p) }
  5107  func (c funcConn) Write(p []byte) (int, error) { return c.write(p) }
  5108  func (c funcConn) Close() error                { return nil }
  5109  
  5110  // Issue 16465: Transport.RoundTrip should return the raw net.Conn.Read error from Peek
  5111  // back to the caller.
  5112  func TestTransportReturnsPeekError(t *testing.T) {
  5113  	errValue := errors.New("specific error value")
  5114  
  5115  	wrote := make(chan struct{})
  5116  	var wroteOnce sync.Once
  5117  
  5118  	tr := &Transport{
  5119  		Dial: func(network, addr string) (net.Conn, error) {
  5120  			c := funcConn{
  5121  				read: func([]byte) (int, error) {
  5122  					<-wrote
  5123  					return 0, errValue
  5124  				},
  5125  				write: func(p []byte) (int, error) {
  5126  					wroteOnce.Do(func() { close(wrote) })
  5127  					return len(p), nil
  5128  				},
  5129  			}
  5130  			return c, nil
  5131  		},
  5132  	}
  5133  	_, err := tr.RoundTrip(httptest.NewRequest("GET", "http://fake.tld/", nil))
  5134  	if err != errValue {
  5135  		t.Errorf("error = %#v; want %v", err, errValue)
  5136  	}
  5137  }
  5138  
  5139  // Issue 13835: international domain names should work
  5140  // func TestTransportIDNA_h1(t *testing.T) { testTransportIDNA(t, h1Mode) }
  5141  // func TestTransportIDNA_h2(t *testing.T) { testTransportIDNA(t, h2Mode) }
  5142  //goland:noinspection GoUnusedFunction
  5143  func testTransportIDNA(t *testing.T, h2 bool) {
  5144  	defer afterTest(t)
  5145  
  5146  	const uniDomain = "гофер.го"
  5147  	const punyDomain = "xn--c1ae0ajs.xn--c1aw"
  5148  
  5149  	var port string
  5150  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  5151  		want := punyDomain + ":" + port
  5152  		if r.Host != want {
  5153  			t.Errorf("Host header = %q; want %q", r.Host, want)
  5154  		}
  5155  		if h2 {
  5156  			if r.TLS == nil {
  5157  				t.Errorf("r.TLS == nil")
  5158  			} else if r.TLS.ServerName != punyDomain {
  5159  				t.Errorf("TLS.ServerName = %q; want %q", r.TLS.ServerName, punyDomain)
  5160  			}
  5161  		}
  5162  		w.Header().Set("Hit-Handler", "1")
  5163  	}))
  5164  	defer cst.close()
  5165  
  5166  	ip, port, err := net.SplitHostPort(cst.ts.Listener.Addr().String())
  5167  	if err != nil {
  5168  		t.Fatal(err)
  5169  	}
  5170  
  5171  	// Install a fake DNS server.
  5172  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, network, host string) ([]net.IPAddr, error) {
  5173  		if host != punyDomain {
  5174  			t.Errorf("got DNS host lookup for %q/%q; want %q", network, host, punyDomain)
  5175  			return nil, nil
  5176  		}
  5177  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  5178  	})
  5179  
  5180  	req, _ := NewRequest("GET", cst.scheme()+"://"+uniDomain+":"+port, nil)
  5181  	trace := &httptrace.ClientTrace{
  5182  		GetConn: func(hostPort string) {
  5183  			want := net.JoinHostPort(punyDomain, port)
  5184  			if hostPort != want {
  5185  				t.Errorf("getting conn for %q; want %q", hostPort, want)
  5186  			}
  5187  		},
  5188  		DNSStart: func(e httptrace.DNSStartInfo) {
  5189  			if e.Host != punyDomain {
  5190  				t.Errorf("DNSStart Host = %q; want %q", e.Host, punyDomain)
  5191  			}
  5192  		},
  5193  	}
  5194  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  5195  
  5196  	res, err := cst.tr.RoundTrip(req)
  5197  	if err != nil {
  5198  		t.Fatal(err)
  5199  	}
  5200  	defer func(Body io.ReadCloser) {
  5201  		_ = Body.Close()
  5202  	}(res.Body)
  5203  	if res.Header.Get("Hit-Handler") != "1" {
  5204  		out, err := httputil.DumpResponse(res, true)
  5205  		if err != nil {
  5206  			t.Fatal(err)
  5207  		}
  5208  		t.Errorf("Response body wasn't from Handler. Got:\n%s\n", out)
  5209  	}
  5210  }
  5211  
  5212  // Issue 13290: send User-Agent in proxy CONNECT
  5213  func TestTransportProxyConnectHeader(t *testing.T) {
  5214  	defer afterTest(t)
  5215  	reqc := make(chan *Request, 1)
  5216  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  5217  		if r.Method != "CONNECT" {
  5218  			t.Errorf("method = %q; want CONNECT", r.Method)
  5219  		}
  5220  		reqc <- r
  5221  		c, _, err := w.(Hijacker).Hijack()
  5222  		if err != nil {
  5223  			t.Errorf("Hijack: %v", err)
  5224  			return
  5225  		}
  5226  		_ = c.Close()
  5227  	}))
  5228  	defer ts.Close()
  5229  
  5230  	c := ts.Client()
  5231  	c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) {
  5232  		return url.Parse(ts.URL)
  5233  	}
  5234  	c.Transport.(*Transport).ProxyConnectHeader = Header{
  5235  		"User-Agent": {"foo"},
  5236  		"Other":      {"bar"},
  5237  	}
  5238  
  5239  	res, err := c.Get("https://dummy.tld/") // https to force a CONNECT
  5240  	if err == nil {
  5241  		_ = res.Body.Close()
  5242  		t.Errorf("unexpected success")
  5243  	}
  5244  	select {
  5245  	case <-time.After(3 * time.Second):
  5246  		t.Fatal("timeout")
  5247  	case r := <-reqc:
  5248  		if got, want := r.Header.Get("User-Agent"), "foo"; got != want {
  5249  			t.Errorf("CONNECT request User-Agent = %q; want %q", got, want)
  5250  		}
  5251  		if got, want := r.Header.Get("Other"), "bar"; got != want {
  5252  			t.Errorf("CONNECT request Other = %q; want %q", got, want)
  5253  		}
  5254  	}
  5255  }
  5256  
  5257  func TestTransportProxyGetConnectHeader(t *testing.T) {
  5258  	defer afterTest(t)
  5259  	reqc := make(chan *Request, 1)
  5260  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  5261  		if r.Method != "CONNECT" {
  5262  			t.Errorf("method = %q; want CONNECT", r.Method)
  5263  		}
  5264  		reqc <- r
  5265  		c, _, err := w.(Hijacker).Hijack()
  5266  		if err != nil {
  5267  			t.Errorf("Hijack: %v", err)
  5268  			return
  5269  		}
  5270  		_ = c.Close()
  5271  	}))
  5272  	defer ts.Close()
  5273  
  5274  	c := ts.Client()
  5275  	c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) {
  5276  		return url.Parse(ts.URL)
  5277  	}
  5278  	// These should be ignored:
  5279  	c.Transport.(*Transport).ProxyConnectHeader = Header{
  5280  		"User-Agent": {"foo"},
  5281  		"Other":      {"bar"},
  5282  	}
  5283  	c.Transport.(*Transport).GetProxyConnectHeader = func(ctx context.Context, proxyURL *url.URL, target string) (Header, error) {
  5284  		return Header{
  5285  			"User-Agent": {"foo2"},
  5286  			"Other":      {"bar2"},
  5287  		}, nil
  5288  	}
  5289  
  5290  	res, err := c.Get("https://dummy.tld/") // https to force a CONNECT
  5291  	if err == nil {
  5292  		_ = res.Body.Close()
  5293  		t.Errorf("unexpected success")
  5294  	}
  5295  	select {
  5296  	case <-time.After(3 * time.Second):
  5297  		t.Fatal("timeout")
  5298  	case r := <-reqc:
  5299  		if got, want := r.Header.Get("User-Agent"), "foo2"; got != want {
  5300  			t.Errorf("CONNECT request User-Agent = %q; want %q", got, want)
  5301  		}
  5302  		if got, want := r.Header.Get("Other"), "bar2"; got != want {
  5303  			t.Errorf("CONNECT request Other = %q; want %q", got, want)
  5304  		}
  5305  	}
  5306  }
  5307  
  5308  var errFakeRoundTrip = errors.New("fake roundtrip")
  5309  
  5310  type funcRoundTripper func()
  5311  
  5312  func (fn funcRoundTripper) RoundTrip(*Request) (*Response, error) {
  5313  	fn()
  5314  	return nil, errFakeRoundTrip
  5315  }
  5316  
  5317  func wantBody(res *Response, err error, want string) error {
  5318  	if err != nil {
  5319  		return err
  5320  	}
  5321  	slurp, err := io.ReadAll(res.Body)
  5322  	if err != nil {
  5323  		return fmt.Errorf("error reading body: %v", err)
  5324  	}
  5325  	if string(slurp) != want {
  5326  		return fmt.Errorf("body = %q; want %q", slurp, want)
  5327  	}
  5328  	if err := res.Body.Close(); err != nil {
  5329  		return fmt.Errorf("body Close = %v", err)
  5330  	}
  5331  	return nil
  5332  }
  5333  
  5334  func newLocalListener(t *testing.T) net.Listener {
  5335  	ln, err := net.Listen("tcp", "127.0.0.1:0")
  5336  	if err != nil {
  5337  		ln, err = net.Listen("tcp6", "[::1]:0")
  5338  	}
  5339  	if err != nil {
  5340  		t.Fatal(err)
  5341  	}
  5342  	return ln
  5343  }
  5344  
  5345  type countCloseReader struct {
  5346  	n *int
  5347  	io.Reader
  5348  }
  5349  
  5350  func (cr countCloseReader) Close() error {
  5351  	*cr.n++
  5352  	return nil
  5353  }
  5354  
  5355  // rgz is a gzip quine that uncompresses to itself.
  5356  var rgz = []byte{
  5357  	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  5358  	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  5359  	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  5360  	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  5361  	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  5362  	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  5363  	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  5364  	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  5365  	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  5366  	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  5367  	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  5368  	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  5369  	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  5370  	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  5371  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  5372  	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  5373  	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  5374  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  5375  	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  5376  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  5377  	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  5378  	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  5379  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  5380  	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  5381  	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  5382  	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  5383  	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  5384  	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  5385  	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  5386  	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  5387  	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  5388  	0x00, 0x00,
  5389  }
  5390  
  5391  // Ensure that a missing status doesn't make the server panic
  5392  // See Issue https://golang.org/issues/21701
  5393  func TestMissingStatusNoPanic(t *testing.T) {
  5394  	t.Parallel()
  5395  
  5396  	const want = "unknown status code"
  5397  
  5398  	ln := newLocalListener(t)
  5399  	addr := ln.Addr().String()
  5400  	done := make(chan bool)
  5401  	//goland:noinspection HttpUrlsUsage
  5402  	fullAddrURL := fmt.Sprintf("http://%s", addr)
  5403  	raw := "HTTP/1.1 400\r\n" +
  5404  		"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
  5405  		"Content-Type: text/html; charset=utf-8\r\n" +
  5406  		"Content-Length: 10\r\n" +
  5407  		"Last-Modified: Wed, 30 Aug 2017 19:02:02 GMT\r\n" +
  5408  		"Vary: Accept-Encoding\r\n\r\n" +
  5409  		"Aloha Olaa"
  5410  
  5411  	go func() {
  5412  		defer close(done)
  5413  
  5414  		conn, _ := ln.Accept()
  5415  		if conn != nil {
  5416  			_, _ = io.WriteString(conn, raw)
  5417  			_, _ = io.ReadAll(conn)
  5418  			_ = conn.Close()
  5419  		}
  5420  	}()
  5421  
  5422  	proxyURL, err := url.Parse(fullAddrURL)
  5423  	if err != nil {
  5424  		t.Fatalf("proxyURL: %v", err)
  5425  	}
  5426  
  5427  	tr := &Transport{Proxy: ProxyURL(proxyURL)}
  5428  
  5429  	req, _ := NewRequest("GET", "https://golang.org/", nil)
  5430  	res, err, panicked := doFetchCheckPanic(tr, req)
  5431  	if panicked {
  5432  		t.Error("panicked, expecting an error")
  5433  	}
  5434  	if res != nil && res.Body != nil {
  5435  		_, _ = io.Copy(io.Discard, res.Body)
  5436  		_ = res.Body.Close()
  5437  	}
  5438  
  5439  	if err == nil || !strings.Contains(err.Error(), want) {
  5440  		t.Errorf("got=%v want=%q", err, want)
  5441  	}
  5442  
  5443  	_ = ln.Close()
  5444  	<-done
  5445  }
  5446  
  5447  func doFetchCheckPanic(tr *Transport, req *Request) (res *Response, err error, panicked bool) {
  5448  	defer func() {
  5449  		if r := recover(); r != nil {
  5450  			panicked = true
  5451  		}
  5452  	}()
  5453  	res, err = tr.RoundTrip(req)
  5454  	return
  5455  }
  5456  
  5457  // Issue 22330: do not allow the response body to be read when the status code
  5458  // forbids a response body.
  5459  func TestNoBodyOnChunked304Response(t *testing.T) {
  5460  	defer afterTest(t)
  5461  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5462  		conn, buf, _ := w.(Hijacker).Hijack()
  5463  		_, _ = buf.Write([]byte("HTTP/1.1 304 NOT MODIFIED\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"))
  5464  		_ = buf.Flush()
  5465  		_ = conn.Close()
  5466  	}))
  5467  	defer cst.close()
  5468  
  5469  	// Our test server above is sending back bogus data after the
  5470  	// response (the "0\r\n\r\n" part), which causes the Transport
  5471  	// code to log spam. Disable keep-alives so we never even try
  5472  	// to reuse the connection.
  5473  	cst.tr.DisableKeepAlives = true
  5474  
  5475  	res, err := cst.c.Get(cst.ts.URL)
  5476  	if err != nil {
  5477  		t.Fatal(err)
  5478  	}
  5479  
  5480  	if res.Body != NoBody {
  5481  		t.Errorf("Unexpected body on 304 response")
  5482  	}
  5483  }
  5484  
  5485  type funcWriter func([]byte) (int, error)
  5486  
  5487  func (f funcWriter) Write(p []byte) (int, error) { return f(p) }
  5488  
  5489  type doneContext struct {
  5490  	context.Context
  5491  	err error
  5492  }
  5493  
  5494  func (doneContext) Done() <-chan struct{} {
  5495  	c := make(chan struct{})
  5496  	close(c)
  5497  	return c
  5498  }
  5499  
  5500  func (d doneContext) Err() error { return d.err }
  5501  
  5502  // Issue 25852: Transport should check whether Context is done early.
  5503  func TestTransportCheckContextDoneEarly(t *testing.T) {
  5504  	tr := &Transport{}
  5505  	req, _ := NewRequest("GET", "http://fake.example/", nil)
  5506  	wantErr := errors.New("some error")
  5507  	req = req.WithContext(doneContext{context.Background(), wantErr})
  5508  	_, err := tr.RoundTrip(req)
  5509  	if err != wantErr {
  5510  		t.Errorf("error = %v; want %v", err, wantErr)
  5511  	}
  5512  }
  5513  
  5514  // Issue 23399: verify that if a client request times out, the Transport's
  5515  // conn is closed so that it's not reused.
  5516  //
  5517  // This is the test variant that times out before the server replies with
  5518  // any response headers.
  5519  func TestClientTimeoutKillsConn_BeforeHeaders(t *testing.T) {
  5520  	setParallel(t)
  5521  	defer afterTest(t)
  5522  	inHandler := make(chan net.Conn, 1)
  5523  	handlerReadReturned := make(chan bool, 1)
  5524  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5525  		conn, _, err := w.(Hijacker).Hijack()
  5526  		if err != nil {
  5527  			t.Error(err)
  5528  			return
  5529  		}
  5530  		inHandler <- conn
  5531  		n, err := conn.Read([]byte{0})
  5532  		if n != 0 || err != io.EOF {
  5533  			t.Errorf("unexpected Read result: %v, %v", n, err)
  5534  		}
  5535  		handlerReadReturned <- true
  5536  	}))
  5537  	defer cst.close()
  5538  
  5539  	const timeout = 50 * time.Millisecond
  5540  	cst.c.Timeout = timeout
  5541  
  5542  	_, err := cst.c.Get(cst.ts.URL)
  5543  	if err == nil {
  5544  		t.Fatal("unexpected Get succeess")
  5545  	}
  5546  
  5547  	select {
  5548  	case c := <-inHandler:
  5549  		select {
  5550  		case <-handlerReadReturned:
  5551  			// Success.
  5552  			return
  5553  		case <-time.After(5 * time.Second):
  5554  			t.Error("Handler's conn.Read seems to be stuck in Read")
  5555  			_ = c.Close() // close it to unblock Handler
  5556  		}
  5557  	case <-time.After(timeout * 10):
  5558  		// If we didn't get into the Handler in 50ms, that probably means
  5559  		// the builder was just slow and the Get failed in that time
  5560  		// but never made it to the server. That's fine. We'll usually
  5561  		// test the part above on faster machines.
  5562  		t.Skip("skipping test on slow builder")
  5563  	}
  5564  }
  5565  
  5566  // Issue 23399: verify that if a client request times out, the Transport's
  5567  // conn is closed so that it's not reused.
  5568  //
  5569  // This is the test variant that has the server send response headers
  5570  // first, and time out during the write of the response body.
  5571  func TestClientTimeoutKillsConn_AfterHeaders(t *testing.T) {
  5572  	setParallel(t)
  5573  	defer afterTest(t)
  5574  	inHandler := make(chan net.Conn, 1)
  5575  	handlerResult := make(chan error, 1)
  5576  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5577  		w.Header().Set("Content-Length", "100")
  5578  		w.(Flusher).Flush()
  5579  		conn, _, err := w.(Hijacker).Hijack()
  5580  		if err != nil {
  5581  			t.Error(err)
  5582  			return
  5583  		}
  5584  		_, _ = conn.Write([]byte("foo"))
  5585  		inHandler <- conn
  5586  		n, err := conn.Read([]byte{0})
  5587  		// The error should be io.EOF or "read tcp
  5588  		// 127.0.0.1:35827->127.0.0.1:40290: read: connection
  5589  		// reset by peer" depending on timing. Really we just
  5590  		// care that it returns at all. But if it returns with
  5591  		// data, that's weird.
  5592  		if n != 0 || err == nil {
  5593  			handlerResult <- fmt.Errorf("unexpected Read result: %v, %v", n, err)
  5594  			return
  5595  		}
  5596  		handlerResult <- nil
  5597  	}))
  5598  	defer cst.close()
  5599  
  5600  	// Set Timeout to something very long but non-zero to exercise
  5601  	// the codepaths that check for it. But rather than wait for it to fire
  5602  	// (which would make the test slow), we send on the req.Cancel channel instead,
  5603  	// which happens to exercise the same code paths.
  5604  	cst.c.Timeout = time.Minute // just to be non-zero, not to hit it.
  5605  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  5606  	cancel := make(chan struct{})
  5607  	req.Cancel = cancel
  5608  
  5609  	res, err := cst.c.Do(req)
  5610  	if err != nil {
  5611  		select {
  5612  		case <-inHandler:
  5613  			t.Fatalf("Get error: %v", err)
  5614  		default:
  5615  			// Failed before entering handler. Ignore result.
  5616  			t.Skip("skipping test on slow builder")
  5617  		}
  5618  	}
  5619  
  5620  	close(cancel)
  5621  	got, err := io.ReadAll(res.Body)
  5622  	if err == nil {
  5623  		t.Fatalf("unexpected success; read %q, nil", got)
  5624  	}
  5625  
  5626  	select {
  5627  	case c := <-inHandler:
  5628  		select {
  5629  		case err := <-handlerResult:
  5630  			if err != nil {
  5631  				t.Errorf("handler: %v", err)
  5632  			}
  5633  			return
  5634  		case <-time.After(5 * time.Second):
  5635  			t.Error("Handler's conn.Read seems to be stuck in Read")
  5636  			_ = c.Close() // close it to unblock Handler
  5637  		}
  5638  	case <-time.After(5 * time.Second):
  5639  		t.Fatal("timeout")
  5640  	}
  5641  }
  5642  
  5643  func TestTransportResponseBodyWritableOnProtocolSwitch(t *testing.T) {
  5644  	setParallel(t)
  5645  	defer afterTest(t)
  5646  	done := make(chan struct{})
  5647  	defer close(done)
  5648  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5649  		conn, _, err := w.(Hijacker).Hijack()
  5650  		if err != nil {
  5651  			t.Error(err)
  5652  			return
  5653  		}
  5654  		defer func(conn net.Conn) {
  5655  			_ = conn.Close()
  5656  		}(conn)
  5657  		_, _ = io.WriteString(conn, "HTTP/1.1 101 Switching Protocols Hi\r\nConnection: upgRADe\r\nUpgrade: foo\r\n\r\nSome buffered data\n")
  5658  		bs := bufio.NewScanner(conn)
  5659  		bs.Scan()
  5660  		_, _ = fmt.Fprintf(conn, "%s\n", strings.ToUpper(bs.Text()))
  5661  		<-done
  5662  	}))
  5663  	defer cst.close()
  5664  
  5665  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  5666  	req.Header.Set("Upgrade", "foo")
  5667  	req.Header.Set("Connection", "upgrade")
  5668  	res, err := cst.c.Do(req)
  5669  	if err != nil {
  5670  		t.Fatal(err)
  5671  	}
  5672  	if res.StatusCode != 101 {
  5673  		t.Fatalf("expected 101 switching protocols; got %v, %v", res.Status, res.Header)
  5674  	}
  5675  	rwc, ok := res.Body.(io.ReadWriteCloser)
  5676  	if !ok {
  5677  		t.Fatalf("expected a ReadWriteCloser; got a %T", res.Body)
  5678  	}
  5679  	defer func(rwc io.ReadWriteCloser) {
  5680  		_ = rwc.Close()
  5681  	}(rwc)
  5682  	bs := bufio.NewScanner(rwc)
  5683  	if !bs.Scan() {
  5684  		t.Fatalf("expected readable input")
  5685  	}
  5686  	if got, want := bs.Text(), "Some buffered data"; got != want {
  5687  		t.Errorf("read %q; want %q", got, want)
  5688  	}
  5689  	_, _ = io.WriteString(rwc, "echo\n")
  5690  	if !bs.Scan() {
  5691  		t.Fatalf("expected another line")
  5692  	}
  5693  	if got, want := bs.Text(), "ECHO"; got != want {
  5694  		t.Errorf("read %q; want %q", got, want)
  5695  	}
  5696  }
  5697  
  5698  func TestTransportCONNECTBidi(t *testing.T) {
  5699  	defer afterTest(t)
  5700  	const target = "backend:443"
  5701  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  5702  		if r.Method != "CONNECT" {
  5703  			t.Errorf("unexpected method %q", r.Method)
  5704  			w.WriteHeader(500)
  5705  			return
  5706  		}
  5707  		if r.RequestURI != target {
  5708  			t.Errorf("unexpected CONNECT target %q", r.RequestURI)
  5709  			w.WriteHeader(500)
  5710  			return
  5711  		}
  5712  		nc, brw, err := w.(Hijacker).Hijack()
  5713  		if err != nil {
  5714  			t.Error(err)
  5715  			return
  5716  		}
  5717  		defer func(nc net.Conn) {
  5718  			_ = nc.Close()
  5719  		}(nc)
  5720  		_, _ = nc.Write([]byte("HTTP/1.1 200 OK\r\n\r\n"))
  5721  		// Switch to a little protocol that capitalize its input lines:
  5722  		for {
  5723  			line, err := brw.ReadString('\n')
  5724  			if err != nil {
  5725  				if err != io.EOF {
  5726  					t.Error(err)
  5727  				}
  5728  				return
  5729  			}
  5730  			_, _ = io.WriteString(brw, strings.ToUpper(line))
  5731  			_ = brw.Flush()
  5732  		}
  5733  	}))
  5734  	defer cst.close()
  5735  	pr, pw := io.Pipe()
  5736  	defer func(pw *io.PipeWriter) {
  5737  		_ = pw.Close()
  5738  	}(pw)
  5739  	req, err := NewRequest("CONNECT", cst.ts.URL, pr)
  5740  	if err != nil {
  5741  		t.Fatal(err)
  5742  	}
  5743  	req.URL.Opaque = target
  5744  	res, err := cst.c.Do(req)
  5745  	if err != nil {
  5746  		t.Fatal(err)
  5747  	}
  5748  	defer func(Body io.ReadCloser) {
  5749  		_ = Body.Close()
  5750  	}(res.Body)
  5751  	if res.StatusCode != 200 {
  5752  		t.Fatalf("status code = %d; want 200", res.StatusCode)
  5753  	}
  5754  	br := bufio.NewReader(res.Body)
  5755  	for _, str := range []string{"foo", "bar", "baz"} {
  5756  		_, _ = fmt.Fprintf(pw, "%s\n", str)
  5757  		got, err := br.ReadString('\n')
  5758  		if err != nil {
  5759  			t.Fatal(err)
  5760  		}
  5761  		got = strings.TrimSpace(got)
  5762  		want := strings.ToUpper(str)
  5763  		if got != want {
  5764  			t.Fatalf("got %q; want %q", got, want)
  5765  		}
  5766  	}
  5767  }
  5768  
  5769  func TestTransportRequestReplayable(t *testing.T) {
  5770  	someBody := io.NopCloser(strings.NewReader(""))
  5771  	tests := []struct {
  5772  		name string
  5773  		req  *Request
  5774  		want bool
  5775  	}{
  5776  		{
  5777  			name: "GET",
  5778  			req:  &Request{Method: "GET"},
  5779  			want: true,
  5780  		},
  5781  		{
  5782  			name: "GET_http.NoBody",
  5783  			req:  &Request{Method: "GET", Body: NoBody},
  5784  			want: true,
  5785  		},
  5786  		{
  5787  			name: "GET_body",
  5788  			req:  &Request{Method: "GET", Body: someBody},
  5789  			want: false,
  5790  		},
  5791  		{
  5792  			name: "POST",
  5793  			req:  &Request{Method: "POST"},
  5794  			want: false,
  5795  		},
  5796  		{
  5797  			name: "POST_idempotency-key",
  5798  			req:  &Request{Method: "POST", Header: Header{"Idempotency-Key": {"x"}}},
  5799  			want: true,
  5800  		},
  5801  		{
  5802  			name: "POST_x-idempotency-key",
  5803  			req:  &Request{Method: "POST", Header: Header{"X-Idempotency-Key": {"x"}}},
  5804  			want: true,
  5805  		},
  5806  		{
  5807  			name: "POST_body",
  5808  			req:  &Request{Method: "POST", Header: Header{"Idempotency-Key": {"x"}}, Body: someBody},
  5809  			want: false,
  5810  		},
  5811  	}
  5812  	for _, tt := range tests {
  5813  		t.Run(tt.name, func(t *testing.T) {
  5814  			got := tt.req.ExportIsReplayable()
  5815  			if got != tt.want {
  5816  				t.Errorf("replyable = %v; want %v", got, tt.want)
  5817  			}
  5818  		})
  5819  	}
  5820  }
  5821  
  5822  // testMockTCPConn is a mock TCP connection used to test that
  5823  // ReadFrom is called when sending the request body.
  5824  type testMockTCPConn struct {
  5825  	*net.TCPConn
  5826  
  5827  	ReadFromCalled bool
  5828  }
  5829  
  5830  func (c *testMockTCPConn) ReadFrom(r io.Reader) (int64, error) {
  5831  	c.ReadFromCalled = true
  5832  	return c.TCPConn.ReadFrom(r)
  5833  }
  5834  
  5835  func TestTransportRequestWriteRoundTrip(t *testing.T) {
  5836  	nBytes := int64(1 << 10)
  5837  	newFileFunc := func() (r io.Reader, done func(), err error) {
  5838  		f, err := os.CreateTemp("", "net-http-newfilefunc")
  5839  		if err != nil {
  5840  			return nil, nil, err
  5841  		}
  5842  
  5843  		// Write some bytes to the file to enable reading.
  5844  		if _, err := io.CopyN(f, rand.Reader, nBytes); err != nil {
  5845  			return nil, nil, fmt.Errorf("failed to write data to file: %v", err)
  5846  		}
  5847  		if _, err := f.Seek(0, 0); err != nil {
  5848  			return nil, nil, fmt.Errorf("failed to seek to front: %v", err)
  5849  		}
  5850  
  5851  		done = func() {
  5852  			_ = f.Close()
  5853  			_ = os.Remove(f.Name())
  5854  		}
  5855  
  5856  		return f, done, nil
  5857  	}
  5858  
  5859  	newBufferFunc := func() (io.Reader, func(), error) {
  5860  		return bytes.NewBuffer(make([]byte, nBytes)), func() {}, nil
  5861  	}
  5862  
  5863  	cases := []struct {
  5864  		name             string
  5865  		readerFunc       func() (io.Reader, func(), error)
  5866  		contentLength    int64
  5867  		expectedReadFrom bool
  5868  	}{
  5869  		{
  5870  			name:             "file, length",
  5871  			readerFunc:       newFileFunc,
  5872  			contentLength:    nBytes,
  5873  			expectedReadFrom: true,
  5874  		},
  5875  		{
  5876  			name:       "file, no length",
  5877  			readerFunc: newFileFunc,
  5878  		},
  5879  		{
  5880  			name:          "file, negative length",
  5881  			readerFunc:    newFileFunc,
  5882  			contentLength: -1,
  5883  		},
  5884  		{
  5885  			name:          "buffer",
  5886  			contentLength: nBytes,
  5887  			readerFunc:    newBufferFunc,
  5888  		},
  5889  		{
  5890  			name:       "buffer, no length",
  5891  			readerFunc: newBufferFunc,
  5892  		},
  5893  		{
  5894  			name:          "buffer, length -1",
  5895  			contentLength: -1,
  5896  			readerFunc:    newBufferFunc,
  5897  		},
  5898  	}
  5899  
  5900  	for _, tc := range cases {
  5901  		t.Run(tc.name, func(t *testing.T) {
  5902  			r, cleanup, err := tc.readerFunc()
  5903  			if err != nil {
  5904  				t.Fatal(err)
  5905  			}
  5906  			defer cleanup()
  5907  
  5908  			tConn := &testMockTCPConn{}
  5909  			trFunc := func(tr *Transport) {
  5910  				tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
  5911  					var d net.Dialer
  5912  					conn, err := d.DialContext(ctx, network, addr)
  5913  					if err != nil {
  5914  						return nil, err
  5915  					}
  5916  
  5917  					tcpConn, ok := conn.(*net.TCPConn)
  5918  					if !ok {
  5919  						return nil, fmt.Errorf("%s/%s does not provide a *net.TCPConn", network, addr)
  5920  					}
  5921  
  5922  					tConn.TCPConn = tcpConn
  5923  					return tConn, nil
  5924  				}
  5925  			}
  5926  
  5927  			cst := newClientServerTest(
  5928  				t,
  5929  				h1Mode,
  5930  				HandlerFunc(func(w ResponseWriter, r *Request) {
  5931  					_, _ = io.Copy(io.Discard, r.Body)
  5932  					_ = r.Body.Close()
  5933  					w.WriteHeader(200)
  5934  				}),
  5935  				trFunc,
  5936  			)
  5937  			defer cst.close()
  5938  
  5939  			req, err := NewRequest("PUT", cst.ts.URL, r)
  5940  			if err != nil {
  5941  				t.Fatal(err)
  5942  			}
  5943  			req.ContentLength = tc.contentLength
  5944  			req.Header.Set("Content-Type", "application/octet-stream")
  5945  			resp, err := cst.c.Do(req)
  5946  			if err != nil {
  5947  				t.Fatal(err)
  5948  			}
  5949  			defer func(Body io.ReadCloser) {
  5950  				_ = Body.Close()
  5951  			}(resp.Body)
  5952  			if resp.StatusCode != 200 {
  5953  				t.Fatalf("status code = %d; want 200", resp.StatusCode)
  5954  			}
  5955  
  5956  			if !tConn.ReadFromCalled && tc.expectedReadFrom {
  5957  				t.Fatalf("did not call ReadFrom")
  5958  			}
  5959  
  5960  			if tConn.ReadFromCalled && !tc.expectedReadFrom {
  5961  				t.Fatalf("ReadFrom was unexpectedly invoked")
  5962  			}
  5963  		})
  5964  	}
  5965  }
  5966  
  5967  func TestTransportClone(t *testing.T) {
  5968  	tr := &Transport{
  5969  		Proxy:                  func(*Request) (*url.URL, error) { panic("") },
  5970  		DialContext:            func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") },
  5971  		Dial:                   func(network, addr string) (net.Conn, error) { panic("") },
  5972  		DialTLS:                func(network, addr string) (net.Conn, error) { panic("") },
  5973  		DialTLSContext:         func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") },
  5974  		TLSClientConfig:        new(tls.Config),
  5975  		TLSHandshakeTimeout:    time.Second,
  5976  		DisableKeepAlives:      true,
  5977  		DisableCompression:     true,
  5978  		MaxIdleConns:           1,
  5979  		MaxIdleConnsPerHost:    1,
  5980  		MaxConnsPerHost:        1,
  5981  		IdleConnTimeout:        time.Second,
  5982  		ResponseHeaderTimeout:  time.Second,
  5983  		ExpectContinueTimeout:  time.Second,
  5984  		ProxyConnectHeader:     Header{},
  5985  		GetProxyConnectHeader:  func(context.Context, *url.URL, string) (Header, error) { return nil, nil },
  5986  		MaxResponseHeaderBytes: 1,
  5987  		ForceAttemptHTTP2:      true,
  5988  		TLSNextProto: map[string]func(authority string, c *tls.Conn) RoundTripper{
  5989  			"foo": func(authority string, c *tls.Conn) RoundTripper { panic("") },
  5990  		},
  5991  		ReadBufferSize:  1,
  5992  		WriteBufferSize: 1,
  5993  	}
  5994  	tr2 := tr.Clone()
  5995  	rv := reflect.ValueOf(tr2).Elem()
  5996  	rt := rv.Type()
  5997  	for i := 0; i < rt.NumField(); i++ {
  5998  		sf := rt.Field(i)
  5999  		if !token.IsExported(sf.Name) {
  6000  			continue
  6001  		}
  6002  		if rv.Field(i).IsZero() {
  6003  			t.Errorf("cloned field t2.%s is zero", sf.Name)
  6004  		}
  6005  	}
  6006  
  6007  	if _, ok := tr2.TLSNextProto["foo"]; !ok {
  6008  		t.Errorf("cloned Transport lacked TLSNextProto 'foo' key")
  6009  	}
  6010  
  6011  	// But test that a nil TLSNextProto is kept nil:
  6012  	tr = new(Transport)
  6013  	tr2 = tr.Clone()
  6014  	if tr2.TLSNextProto != nil {
  6015  		t.Errorf("Transport.TLSNextProto unexpected non-nil")
  6016  	}
  6017  }
  6018  
  6019  func TestIs408(t *testing.T) {
  6020  	tests := []struct {
  6021  		in   string
  6022  		want bool
  6023  	}{
  6024  		{"HTTP/1.0 408", true},
  6025  		{"HTTP/1.1 408", true},
  6026  		{"HTTP/1.8 408", true},
  6027  		{"HTTP/2.0 408", false}, // maybe h2c would do this? but false for now.
  6028  		{"HTTP/1.1 408 ", true},
  6029  		{"HTTP/1.1 40", false},
  6030  		{"http/1.0 408", false},
  6031  		{"HTTP/1-1 408", false},
  6032  	}
  6033  	for _, tt := range tests {
  6034  		if got := Export_is408Message([]byte(tt.in)); got != tt.want {
  6035  			t.Errorf("is408Message(%q) = %v; want %v", tt.in, got, tt.want)
  6036  		}
  6037  	}
  6038  }
  6039  
  6040  func TestTransportIgnores408(t *testing.T) {
  6041  	// Not parallel. Relies on mutating the log package's global Output.
  6042  	defer log.SetOutput(log.Writer())
  6043  
  6044  	var logout bytes.Buffer
  6045  	log.SetOutput(&logout)
  6046  
  6047  	defer afterTest(t)
  6048  	//goland:noinspection GoUnusedConst
  6049  	const target = "backend:443"
  6050  
  6051  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  6052  		nc, _, err := w.(Hijacker).Hijack()
  6053  		if err != nil {
  6054  			t.Error(err)
  6055  			return
  6056  		}
  6057  		defer func(nc net.Conn) {
  6058  			_ = nc.Close()
  6059  		}(nc)
  6060  		_, _ = nc.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok"))
  6061  		_, _ = nc.Write([]byte("HTTP/1.1 408 bye\r\n")) // changing 408 to 409 makes test fail
  6062  	}))
  6063  	defer cst.close()
  6064  	req, err := NewRequest("GET", cst.ts.URL, nil)
  6065  	if err != nil {
  6066  		t.Fatal(err)
  6067  	}
  6068  	res, err := cst.c.Do(req)
  6069  	if err != nil {
  6070  		t.Fatal(err)
  6071  	}
  6072  	slurp, err := io.ReadAll(res.Body)
  6073  	if err != nil {
  6074  		t.Fatal(err)
  6075  	}
  6076  	if err != nil {
  6077  		t.Fatal(err)
  6078  	}
  6079  	if string(slurp) != "ok" {
  6080  		t.Fatalf("got %q; want ok", slurp)
  6081  	}
  6082  
  6083  	t0 := time.Now()
  6084  	for i := 0; i < 50; i++ {
  6085  		time.Sleep(time.Duration(i) * 5 * time.Millisecond)
  6086  		if cst.tr.IdleConnKeyCountForTesting() == 0 {
  6087  			if got := logout.String(); got != "" {
  6088  				t.Fatalf("expected no log output; got: %s", got)
  6089  			}
  6090  			return
  6091  		}
  6092  	}
  6093  	t.Fatalf("timeout after %v waiting for Transport connections to die off", time.Since(t0))
  6094  }
  6095  
  6096  func TestInvalidHeaderResponse(t *testing.T) {
  6097  	setParallel(t)
  6098  	defer afterTest(t)
  6099  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  6100  		conn, buf, _ := w.(Hijacker).Hijack()
  6101  		_, _ = buf.Write([]byte("HTTP/1.1 200 OK\r\n" +
  6102  			"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
  6103  			"Content-Type: text/html; charset=utf-8\r\n" +
  6104  			"Content-Length: 0\r\n" +
  6105  			"Foo : bar\r\n\r\n"))
  6106  		_ = buf.Flush()
  6107  		_ = conn.Close()
  6108  	}))
  6109  	defer cst.close()
  6110  	res, err := cst.c.Get(cst.ts.URL)
  6111  	if err != nil {
  6112  		t.Fatal(err)
  6113  	}
  6114  	defer func(Body io.ReadCloser) {
  6115  		_ = Body.Close()
  6116  	}(res.Body)
  6117  	if v := res.Header.Get("Foo"); v != "" {
  6118  		t.Errorf(`unexpected "Foo" header: %q`, v)
  6119  	}
  6120  	if v := res.Header.Get("Foo "); v != "bar" {
  6121  		t.Errorf(`bad "Foo " header value: %q, want %q`, v, "bar")
  6122  	}
  6123  }
  6124  
  6125  type bodyCloser bool
  6126  
  6127  func (bc *bodyCloser) Close() error {
  6128  	*bc = true
  6129  	return nil
  6130  }
  6131  
  6132  //goland:noinspection GoUnusedParameter
  6133  func (bc *bodyCloser) Read(b []byte) (n int, err error) {
  6134  	return 0, io.EOF
  6135  }
  6136  
  6137  // Issue 35015: ensure that Transport closes the body on any error
  6138  // with an invalid request, as promised by Client.Do docs.
  6139  func TestTransportClosesBodyOnInvalidRequests(t *testing.T) {
  6140  	cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  6141  		t.Errorf("Should not have been invoked")
  6142  	}))
  6143  	defer cst.Close()
  6144  
  6145  	u, _ := url.Parse(cst.URL)
  6146  
  6147  	tests := []struct {
  6148  		name    string
  6149  		req     *Request
  6150  		wantErr string
  6151  	}{
  6152  		{
  6153  			name: "invalid method",
  6154  			req: &Request{
  6155  				Method: " ",
  6156  				URL:    u,
  6157  			},
  6158  			wantErr: "invalid method",
  6159  		},
  6160  		{
  6161  			name: "nil URL",
  6162  			req: &Request{
  6163  				Method: "GET",
  6164  			},
  6165  			wantErr: "nil Request.URL",
  6166  		},
  6167  		{
  6168  			name: "invalid header key",
  6169  			req: &Request{
  6170  				Method: "GET",
  6171  				Header: Header{"💡": {"emoji"}},
  6172  				URL:    u,
  6173  			},
  6174  			wantErr: "invalid header field name",
  6175  		},
  6176  		{
  6177  			name: "invalid header value",
  6178  			req: &Request{
  6179  				Method: "POST",
  6180  				Header: Header{"key": {"\x19"}},
  6181  				URL:    u,
  6182  			},
  6183  			wantErr: "invalid header field value",
  6184  		},
  6185  		{
  6186  			name: "non HTTP(s) scheme",
  6187  			req: &Request{
  6188  				Method: "POST",
  6189  				URL:    &url.URL{Scheme: "faux"},
  6190  			},
  6191  			wantErr: "unsupported protocol scheme",
  6192  		},
  6193  		{
  6194  			name: "no Host in URL",
  6195  			req: &Request{
  6196  				Method: "POST",
  6197  				URL:    &url.URL{Scheme: "http"},
  6198  			},
  6199  			wantErr: "no Host",
  6200  		},
  6201  	}
  6202  
  6203  	for _, tt := range tests {
  6204  		t.Run(tt.name, func(t *testing.T) {
  6205  			var bc bodyCloser
  6206  			req := tt.req
  6207  			req.Body = &bc
  6208  			_, err := DefaultClient.Do(tt.req)
  6209  			if err == nil {
  6210  				t.Fatal("Expected an error")
  6211  			}
  6212  			if !bc {
  6213  				t.Fatal("Expected body to have been closed")
  6214  			}
  6215  			if g, w := err.Error(), tt.wantErr; !strings.Contains(g, w) {
  6216  				t.Fatalf("Error mismatch\n\t%q\ndoes not contain\n\t%q", g, w)
  6217  			}
  6218  		})
  6219  	}
  6220  }
  6221  
  6222  // breakableConn is a net.Conn wrapper with a Write method
  6223  // that will fail when its brokenState is true.
  6224  type breakableConn struct {
  6225  	net.Conn
  6226  	*brokenState
  6227  }
  6228  
  6229  type brokenState struct {
  6230  	sync.Mutex
  6231  	broken bool
  6232  }
  6233  
  6234  func (w *breakableConn) Write(b []byte) (n int, err error) {
  6235  	w.Lock()
  6236  	defer w.Unlock()
  6237  	if w.broken {
  6238  		return 0, errors.New("some write error")
  6239  	}
  6240  	return w.Conn.Write(b)
  6241  }
  6242  
  6243  // Issue 34978: don't cache a broken HTTP/2 connection
  6244  func TestDontCacheBrokenHTTP2Conn(t *testing.T) {
  6245  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), optQuietLog)
  6246  	defer cst.close()
  6247  
  6248  	var brokenState brokenState
  6249  
  6250  	const numReqs = 5
  6251  	var numDials, gotConns uint32 // atomic
  6252  
  6253  	cst.tr.Dial = func(netw, addr string) (net.Conn, error) {
  6254  		atomic.AddUint32(&numDials, 1)
  6255  		c, err := net.Dial(netw, addr)
  6256  		if err != nil {
  6257  			t.Errorf("unexpected Dial error: %v", err)
  6258  			return nil, err
  6259  		}
  6260  		return &breakableConn{c, &brokenState}, err
  6261  	}
  6262  
  6263  	for i := 1; i <= numReqs; i++ {
  6264  		brokenState.Lock()
  6265  		brokenState.broken = false
  6266  		brokenState.Unlock()
  6267  
  6268  		// doBreak controls whether we break the TCP connection after the TLS
  6269  		// handshake (before the HTTP/2 handshake). We test a few failures
  6270  		// in a row followed by a final success.
  6271  		doBreak := i != numReqs
  6272  
  6273  		ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  6274  			GotConn: func(info httptrace.GotConnInfo) {
  6275  				t.Logf("got conn: %v, reused=%v, wasIdle=%v, idleTime=%v", info.Conn.LocalAddr(), info.Reused, info.WasIdle, info.IdleTime)
  6276  				atomic.AddUint32(&gotConns, 1)
  6277  			},
  6278  			TLSHandshakeDone: func(cfg tls.ConnectionState, err error) {
  6279  				brokenState.Lock()
  6280  				defer brokenState.Unlock()
  6281  				if doBreak {
  6282  					brokenState.broken = true
  6283  				}
  6284  			},
  6285  		})
  6286  		req, err := NewRequestWithContext(ctx, "GET", cst.ts.URL, nil)
  6287  		if err != nil {
  6288  			t.Fatal(err)
  6289  		}
  6290  		_, err = cst.c.Do(req)
  6291  		if doBreak != (err != nil) {
  6292  			t.Errorf("for iteration %d, doBreak=%v; unexpected error %v", i, doBreak, err)
  6293  		}
  6294  	}
  6295  	if got, want := atomic.LoadUint32(&gotConns), 1; int(got) != want {
  6296  		t.Errorf("GotConn calls = %v; want %v", got, want)
  6297  	}
  6298  	if got, want := atomic.LoadUint32(&numDials), numReqs; int(got) != want {
  6299  		t.Errorf("Dials = %v; want %v", got, want)
  6300  	}
  6301  }
  6302  
  6303  // Issue 34941
  6304  // When the client has too many concurrent requests on a single connection,
  6305  // http.http2noCachedConnError is reported on multiple requests. There should
  6306  // only be one decrement regardless of the number of failures.
  6307  func TestTransportDecrementConnWhenIdleConnRemoved(t *testing.T) {
  6308  	defer afterTest(t)
  6309  	CondSkipHTTP2(t)
  6310  
  6311  	h := HandlerFunc(func(w ResponseWriter, r *Request) {
  6312  		_, err := w.Write([]byte("foo"))
  6313  		if err != nil {
  6314  			t.Fatalf("Write: %v", err)
  6315  		}
  6316  	})
  6317  
  6318  	ts := httptest.NewUnstartedServer(h)
  6319  	ts.EnableHTTP2 = true
  6320  	ts.StartTLS()
  6321  	defer ts.Close()
  6322  
  6323  	c := ts.Client()
  6324  	tr := c.Transport.(*Transport)
  6325  	tr.MaxConnsPerHost = 1
  6326  	if err := ExportHttp2ConfigureTransport(tr); err != nil {
  6327  		t.Fatalf("ExportHttp2ConfigureTransport: %v", err)
  6328  	}
  6329  
  6330  	errCh := make(chan error, 300)
  6331  	doReq := func() {
  6332  		resp, err := c.Get(ts.URL)
  6333  		if err != nil {
  6334  			errCh <- fmt.Errorf("request failed: %v", err)
  6335  			return
  6336  		}
  6337  		defer func(Body io.ReadCloser) {
  6338  			_ = Body.Close()
  6339  		}(resp.Body)
  6340  		_, err = io.ReadAll(resp.Body)
  6341  		if err != nil {
  6342  			errCh <- fmt.Errorf("read body failed: %v", err)
  6343  		}
  6344  	}
  6345  
  6346  	var wg sync.WaitGroup
  6347  	for i := 0; i < 300; i++ {
  6348  		wg.Add(1)
  6349  		go func() {
  6350  			defer wg.Done()
  6351  			doReq()
  6352  		}()
  6353  	}
  6354  	wg.Wait()
  6355  	close(errCh)
  6356  
  6357  	for err := range errCh {
  6358  		t.Errorf("error occurred: %v", err)
  6359  	}
  6360  }
  6361  
  6362  // Issue 36820
  6363  // Test that we use the older backward compatible cancellation protocol
  6364  // when a RoundTripper is registered via RegisterProtocol.
  6365  func TestAltProtoCancellation(t *testing.T) {
  6366  	defer afterTest(t)
  6367  	tr := &Transport{}
  6368  	c := &Client{
  6369  		Transport: tr,
  6370  		Timeout:   time.Millisecond,
  6371  	}
  6372  	tr.RegisterProtocol("timeout", timeoutProto{})
  6373  	_, err := c.Get("timeout://bar.com/path")
  6374  	if err == nil {
  6375  		t.Error("request unexpectedly succeeded")
  6376  	} else if !strings.Contains(err.Error(), timeoutProtoErr.Error()) {
  6377  		t.Errorf("got error %q, does not contain expected string %q", err, timeoutProtoErr)
  6378  	}
  6379  }
  6380  
  6381  var timeoutProtoErr = errors.New("canceled as expected")
  6382  
  6383  type timeoutProto struct{}
  6384  
  6385  func (timeoutProto) RoundTrip(req *Request) (*Response, error) {
  6386  	select {
  6387  	case <-req.Cancel:
  6388  		return nil, timeoutProtoErr
  6389  	case <-time.After(5 * time.Second):
  6390  		return nil, errors.New("request was not canceled")
  6391  	}
  6392  }
  6393  
  6394  type roundTripFunc func(r *Request) (*Response, error)
  6395  
  6396  func (f roundTripFunc) RoundTrip(r *Request) (*Response, error) { return f(r) }
  6397  
  6398  // Issue 32441: body is not reset after ErrSkipAltProtocol
  6399  func TestIssue32441(t *testing.T) {
  6400  	defer afterTest(t)
  6401  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  6402  		if n, _ := io.Copy(io.Discard, r.Body); n == 0 {
  6403  			t.Error("body length is zero")
  6404  		}
  6405  	}))
  6406  	defer ts.Close()
  6407  	c := ts.Client()
  6408  	c.Transport.(*Transport).RegisterProtocol("http", roundTripFunc(func(r *Request) (*Response, error) {
  6409  		// Draining body to trigger failure condition on actual request to server.
  6410  		if n, _ := io.Copy(io.Discard, r.Body); n == 0 {
  6411  			t.Error("body length is zero during round trip")
  6412  		}
  6413  		return nil, ErrSkipAltProtocol
  6414  	}))
  6415  	if _, err := c.Post(ts.URL, "application/octet-stream", bytes.NewBufferString("data")); err != nil {
  6416  		t.Error(err)
  6417  	}
  6418  }
  6419  
  6420  // Issue 39017. Ensure that HTTP/1 transports reject Content-Length headers
  6421  // that contain a sign (eg. "+3"), per RFC 2616, Section 14.13.
  6422  func TestTransportRejectsSignInContentLength(t *testing.T) {
  6423  	cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  6424  		w.Header().Set("Content-Length", "+3")
  6425  		_, _ = w.Write([]byte("abc"))
  6426  	}))
  6427  	defer cst.Close()
  6428  
  6429  	c := cst.Client()
  6430  	res, err := c.Get(cst.URL)
  6431  	if err == nil || res != nil {
  6432  		t.Fatal("Expected a non-nil error and a nil http.Response")
  6433  	}
  6434  	if got, want := err.Error(), `bad Content-Length "+3"`; !strings.Contains(got, want) {
  6435  		t.Fatalf("Error mismatch\nGot: %q\nWanted substring: %q", got, want)
  6436  	}
  6437  }
  6438  
  6439  // dumpConn is a net.Conn which writes to Writer and reads from Reader
  6440  type dumpConn struct {
  6441  	io.Writer
  6442  	io.Reader
  6443  }
  6444  
  6445  func (c *dumpConn) Close() error         { return nil }
  6446  func (c *dumpConn) LocalAddr() net.Addr  { return nil }
  6447  func (c *dumpConn) RemoteAddr() net.Addr { return nil }
  6448  
  6449  //goland:noinspection GoUnusedParameter
  6450  func (c *dumpConn) SetDeadline(t time.Time) error { return nil }
  6451  
  6452  //goland:noinspection GoUnusedParameter
  6453  func (c *dumpConn) SetReadDeadline(t time.Time) error { return nil }
  6454  
  6455  //goland:noinspection GoUnusedParameter
  6456  func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil }
  6457  
  6458  // delegateReader is a reader that delegates to another reader,
  6459  // once it arrives on a channel.
  6460  type delegateReader struct {
  6461  	c chan io.Reader
  6462  	r io.Reader // nil until received from c
  6463  }
  6464  
  6465  func (r *delegateReader) Read(p []byte) (int, error) {
  6466  	if r.r == nil {
  6467  		var ok bool
  6468  		if r.r, ok = <-r.c; !ok {
  6469  			return 0, errors.New("delegate closed")
  6470  		}
  6471  	}
  6472  	return r.r.Read(p)
  6473  }
  6474  
  6475  func testTransportRace(req *Request) {
  6476  	save := req.Body
  6477  	pr, pw := io.Pipe()
  6478  	defer func(pr *io.PipeReader) {
  6479  		_ = pr.Close()
  6480  	}(pr)
  6481  	defer func(pw *io.PipeWriter) {
  6482  		_ = pw.Close()
  6483  	}(pw)
  6484  	dr := &delegateReader{c: make(chan io.Reader)}
  6485  
  6486  	t := &Transport{
  6487  		Dial: func(net, addr string) (net.Conn, error) {
  6488  			return &dumpConn{pw, dr}, nil
  6489  		},
  6490  	}
  6491  	defer t.CloseIdleConnections()
  6492  
  6493  	quitReadCh := make(chan struct{})
  6494  	// Wait for the request before replying with a dummy response:
  6495  	go func() {
  6496  		defer close(quitReadCh)
  6497  
  6498  		req, err := ReadRequest(bufio.NewReader(pr))
  6499  		if err == nil {
  6500  			// Ensure all the body is read; otherwise
  6501  			// we'll get a partial dump.
  6502  			_, _ = io.Copy(io.Discard, req.Body)
  6503  			_ = req.Body.Close()
  6504  		}
  6505  		select {
  6506  		case dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n"):
  6507  		case quitReadCh <- struct{}{}:
  6508  			// Ensure delegate is closed so Read doesn't block forever.
  6509  			close(dr.c)
  6510  		}
  6511  	}()
  6512  
  6513  	_, _ = t.RoundTrip(req)
  6514  
  6515  	// Ensure the reader returns before we reset req.Body to prevent
  6516  	// a data race on req.Body.
  6517  	_ = pw.Close()
  6518  	<-quitReadCh
  6519  
  6520  	req.Body = save
  6521  }
  6522  
  6523  // Issue 37669
  6524  // Test that a cancellation doesn't result in a data race due to the writeLoop
  6525  // goroutine being left running, if the caller mutates the processed Request
  6526  // upon completion.
  6527  func TestErrorWriteLoopRace(t *testing.T) {
  6528  	if testing.Short() {
  6529  		return
  6530  	}
  6531  	t.Parallel()
  6532  	for i := 0; i < 1000; i++ {
  6533  		delay := time.Duration(mrand.Intn(5)) * time.Millisecond
  6534  		ctx, cancel := context.WithTimeout(context.Background(), delay)
  6535  		//goland:noinspection GoDeferInLoop
  6536  		defer cancel()
  6537  
  6538  		r := bytes.NewBuffer(make([]byte, 10000))
  6539  		//goland:noinspection HttpUrlsUsage
  6540  		req, err := NewRequestWithContext(ctx, MethodPost, "http://example.com", r)
  6541  		if err != nil {
  6542  			t.Fatal(err)
  6543  		}
  6544  
  6545  		testTransportRace(req)
  6546  	}
  6547  }
  6548  
  6549  // Issue 41600
  6550  // Test that a new request which uses the connection of an active request
  6551  // cannot cause it to be canceled as well.
  6552  func TestCancelRequestWhenSharingConnection(t *testing.T) {
  6553  	reqc := make(chan chan struct{}, 2)
  6554  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, req *Request) {
  6555  		ch := make(chan struct{}, 1)
  6556  		reqc <- ch
  6557  		<-ch
  6558  		w.Header().Add("Content-Length", "0")
  6559  	}))
  6560  	defer ts.Close()
  6561  
  6562  	client := ts.Client()
  6563  	transport := client.Transport.(*Transport)
  6564  	transport.MaxIdleConns = 1
  6565  	transport.MaxConnsPerHost = 1
  6566  
  6567  	var wg sync.WaitGroup
  6568  
  6569  	wg.Add(1)
  6570  	putidlec := make(chan chan struct{})
  6571  	go func() {
  6572  		defer wg.Done()
  6573  		ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  6574  			PutIdleConn: func(error) {
  6575  				// Signal that the idle conn has been returned to the pool,
  6576  				// and wait for the order to proceed.
  6577  				ch := make(chan struct{})
  6578  				putidlec <- ch
  6579  				<-ch
  6580  			},
  6581  		})
  6582  		req, _ := NewRequestWithContext(ctx, "GET", ts.URL, nil)
  6583  		res, err := client.Do(req)
  6584  		if err == nil {
  6585  			_ = res.Body.Close()
  6586  		}
  6587  		if err != nil {
  6588  			t.Errorf("request 1: got err %v, want nil", err)
  6589  		}
  6590  	}()
  6591  
  6592  	// Wait for the first request to receive a response and return the
  6593  	// connection to the idle pool.
  6594  	r1c := <-reqc
  6595  	close(r1c)
  6596  	idlec := <-putidlec
  6597  
  6598  	wg.Add(1)
  6599  	cancelctx, cancel := context.WithCancel(context.Background())
  6600  	go func() {
  6601  		defer wg.Done()
  6602  		req, _ := NewRequestWithContext(cancelctx, "GET", ts.URL, nil)
  6603  		res, err := client.Do(req)
  6604  		if err == nil {
  6605  			_ = res.Body.Close()
  6606  		}
  6607  		if !errors.Is(err, context.Canceled) {
  6608  			t.Errorf("request 2: got err %v, want Canceled", err)
  6609  		}
  6610  	}()
  6611  
  6612  	// Wait for the second request to arrive at the server, and then cancel
  6613  	// the request context.
  6614  	r2c := <-reqc
  6615  	cancel()
  6616  
  6617  	// Give the cancelation a moment to take effect, and then unblock the first request.
  6618  	time.Sleep(1 * time.Millisecond)
  6619  	close(idlec)
  6620  
  6621  	close(r2c)
  6622  	wg.Wait()
  6623  }