github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/net/http/transport_test.go (about)

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