Help us shape the future of Go! Take the 2026 Go Developer Survey

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

View as plain text