Source file src/net/http/transport_test.go

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

View as plain text