Source file src/net/http/transport_test.go

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

View as plain text