...
Run Format

Source file src/net/http/transport_test.go

Documentation: net/http

     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  	"encoding/binary"
    20  	"errors"
    21  	"fmt"
    22  	"internal/nettrace"
    23  	"internal/testenv"
    24  	"io"
    25  	"io/ioutil"
    26  	"log"
    27  	"net"
    28  	. "net/http"
    29  	"net/http/httptest"
    30  	"net/http/httptrace"
    31  	"net/http/httputil"
    32  	"net/http/internal"
    33  	"net/url"
    34  	"os"
    35  	"reflect"
    36  	"runtime"
    37  	"strconv"
    38  	"strings"
    39  	"sync"
    40  	"sync/atomic"
    41  	"testing"
    42  	"time"
    43  )
    44  
    45  // TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
    46  //       and then verify that the final 2 responses get errors back.
    47  
    48  // hostPortHandler writes back the client's "host:port".
    49  var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
    50  	if r.FormValue("close") == "true" {
    51  		w.Header().Set("Connection", "close")
    52  	}
    53  	w.Header().Set("X-Saw-Close", fmt.Sprint(r.Close))
    54  	w.Write([]byte(r.RemoteAddr))
    55  })
    56  
    57  // testCloseConn is a net.Conn tracked by a testConnSet.
    58  type testCloseConn struct {
    59  	net.Conn
    60  	set *testConnSet
    61  }
    62  
    63  func (c *testCloseConn) Close() error {
    64  	c.set.remove(c)
    65  	return c.Conn.Close()
    66  }
    67  
    68  // testConnSet tracks a set of TCP connections and whether they've
    69  // been closed.
    70  type testConnSet struct {
    71  	t      *testing.T
    72  	mu     sync.Mutex // guards closed and list
    73  	closed map[net.Conn]bool
    74  	list   []net.Conn // in order created
    75  }
    76  
    77  func (tcs *testConnSet) insert(c net.Conn) {
    78  	tcs.mu.Lock()
    79  	defer tcs.mu.Unlock()
    80  	tcs.closed[c] = false
    81  	tcs.list = append(tcs.list, c)
    82  }
    83  
    84  func (tcs *testConnSet) remove(c net.Conn) {
    85  	tcs.mu.Lock()
    86  	defer tcs.mu.Unlock()
    87  	tcs.closed[c] = true
    88  }
    89  
    90  // some tests use this to manage raw tcp connections for later inspection
    91  func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) {
    92  	connSet := &testConnSet{
    93  		t:      t,
    94  		closed: make(map[net.Conn]bool),
    95  	}
    96  	dial := func(n, addr string) (net.Conn, error) {
    97  		c, err := net.Dial(n, addr)
    98  		if err != nil {
    99  			return nil, err
   100  		}
   101  		tc := &testCloseConn{c, connSet}
   102  		connSet.insert(tc)
   103  		return tc, nil
   104  	}
   105  	return connSet, dial
   106  }
   107  
   108  func (tcs *testConnSet) check(t *testing.T) {
   109  	tcs.mu.Lock()
   110  	defer tcs.mu.Unlock()
   111  	for i := 4; i >= 0; i-- {
   112  		for i, c := range tcs.list {
   113  			if tcs.closed[c] {
   114  				continue
   115  			}
   116  			if i != 0 {
   117  				tcs.mu.Unlock()
   118  				time.Sleep(50 * time.Millisecond)
   119  				tcs.mu.Lock()
   120  				continue
   121  			}
   122  			t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list))
   123  		}
   124  	}
   125  }
   126  
   127  func TestReuseRequest(t *testing.T) {
   128  	defer afterTest(t)
   129  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   130  		w.Write([]byte("{}"))
   131  	}))
   132  	defer ts.Close()
   133  
   134  	c := ts.Client()
   135  	req, _ := NewRequest("GET", ts.URL, nil)
   136  	res, err := c.Do(req)
   137  	if err != nil {
   138  		t.Fatal(err)
   139  	}
   140  	err = res.Body.Close()
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  
   145  	res, err = c.Do(req)
   146  	if err != nil {
   147  		t.Fatal(err)
   148  	}
   149  	err = res.Body.Close()
   150  	if err != nil {
   151  		t.Fatal(err)
   152  	}
   153  }
   154  
   155  // Two subsequent requests and verify their response is the same.
   156  // The response from the server is our own IP:port
   157  func TestTransportKeepAlives(t *testing.T) {
   158  	defer afterTest(t)
   159  	ts := httptest.NewServer(hostPortHandler)
   160  	defer ts.Close()
   161  
   162  	c := ts.Client()
   163  	for _, disableKeepAlive := range []bool{false, true} {
   164  		c.Transport.(*Transport).DisableKeepAlives = disableKeepAlive
   165  		fetch := func(n int) string {
   166  			res, err := c.Get(ts.URL)
   167  			if err != nil {
   168  				t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
   169  			}
   170  			body, err := ioutil.ReadAll(res.Body)
   171  			if err != nil {
   172  				t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
   173  			}
   174  			return string(body)
   175  		}
   176  
   177  		body1 := fetch(1)
   178  		body2 := fetch(2)
   179  
   180  		bodiesDiffer := body1 != body2
   181  		if bodiesDiffer != disableKeepAlive {
   182  			t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   183  				disableKeepAlive, bodiesDiffer, body1, body2)
   184  		}
   185  	}
   186  }
   187  
   188  func TestTransportConnectionCloseOnResponse(t *testing.T) {
   189  	defer afterTest(t)
   190  	ts := httptest.NewServer(hostPortHandler)
   191  	defer ts.Close()
   192  
   193  	connSet, testDial := makeTestDial(t)
   194  
   195  	c := ts.Client()
   196  	tr := c.Transport.(*Transport)
   197  	tr.Dial = testDial
   198  
   199  	for _, connectionClose := range []bool{false, true} {
   200  		fetch := func(n int) string {
   201  			req := new(Request)
   202  			var err error
   203  			req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
   204  			if err != nil {
   205  				t.Fatalf("URL parse error: %v", err)
   206  			}
   207  			req.Method = "GET"
   208  			req.Proto = "HTTP/1.1"
   209  			req.ProtoMajor = 1
   210  			req.ProtoMinor = 1
   211  
   212  			res, err := c.Do(req)
   213  			if err != nil {
   214  				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
   215  			}
   216  			defer res.Body.Close()
   217  			body, err := ioutil.ReadAll(res.Body)
   218  			if err != nil {
   219  				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
   220  			}
   221  			return string(body)
   222  		}
   223  
   224  		body1 := fetch(1)
   225  		body2 := fetch(2)
   226  		bodiesDiffer := body1 != body2
   227  		if bodiesDiffer != connectionClose {
   228  			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   229  				connectionClose, bodiesDiffer, body1, body2)
   230  		}
   231  
   232  		tr.CloseIdleConnections()
   233  	}
   234  
   235  	connSet.check(t)
   236  }
   237  
   238  func TestTransportConnectionCloseOnRequest(t *testing.T) {
   239  	defer afterTest(t)
   240  	ts := httptest.NewServer(hostPortHandler)
   241  	defer ts.Close()
   242  
   243  	connSet, testDial := makeTestDial(t)
   244  
   245  	c := ts.Client()
   246  	tr := c.Transport.(*Transport)
   247  	tr.Dial = testDial
   248  	for _, connectionClose := range []bool{false, true} {
   249  		fetch := func(n int) string {
   250  			req := new(Request)
   251  			var err error
   252  			req.URL, err = url.Parse(ts.URL)
   253  			if err != nil {
   254  				t.Fatalf("URL parse error: %v", err)
   255  			}
   256  			req.Method = "GET"
   257  			req.Proto = "HTTP/1.1"
   258  			req.ProtoMajor = 1
   259  			req.ProtoMinor = 1
   260  			req.Close = connectionClose
   261  
   262  			res, err := c.Do(req)
   263  			if err != nil {
   264  				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
   265  			}
   266  			if got, want := res.Header.Get("X-Saw-Close"), fmt.Sprint(connectionClose); got != want {
   267  				t.Errorf("For connectionClose = %v; handler's X-Saw-Close was %v; want %v",
   268  					connectionClose, got, !connectionClose)
   269  			}
   270  			body, err := ioutil.ReadAll(res.Body)
   271  			if err != nil {
   272  				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
   273  			}
   274  			return string(body)
   275  		}
   276  
   277  		body1 := fetch(1)
   278  		body2 := fetch(2)
   279  		bodiesDiffer := body1 != body2
   280  		if bodiesDiffer != connectionClose {
   281  			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   282  				connectionClose, bodiesDiffer, body1, body2)
   283  		}
   284  
   285  		tr.CloseIdleConnections()
   286  	}
   287  
   288  	connSet.check(t)
   289  }
   290  
   291  // if the Transport's DisableKeepAlives is set, all requests should
   292  // send Connection: close.
   293  // HTTP/1-only (Connection: close doesn't exist in h2)
   294  func TestTransportConnectionCloseOnRequestDisableKeepAlive(t *testing.T) {
   295  	defer afterTest(t)
   296  	ts := httptest.NewServer(hostPortHandler)
   297  	defer ts.Close()
   298  
   299  	c := ts.Client()
   300  	c.Transport.(*Transport).DisableKeepAlives = true
   301  
   302  	res, err := c.Get(ts.URL)
   303  	if err != nil {
   304  		t.Fatal(err)
   305  	}
   306  	res.Body.Close()
   307  	if res.Header.Get("X-Saw-Close") != "true" {
   308  		t.Errorf("handler didn't see Connection: close ")
   309  	}
   310  }
   311  
   312  func TestTransportIdleCacheKeys(t *testing.T) {
   313  	defer afterTest(t)
   314  	ts := httptest.NewServer(hostPortHandler)
   315  	defer ts.Close()
   316  	c := ts.Client()
   317  	tr := c.Transport.(*Transport)
   318  
   319  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   320  		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
   321  	}
   322  
   323  	resp, err := c.Get(ts.URL)
   324  	if err != nil {
   325  		t.Error(err)
   326  	}
   327  	ioutil.ReadAll(resp.Body)
   328  
   329  	keys := tr.IdleConnKeysForTesting()
   330  	if e, g := 1, len(keys); e != g {
   331  		t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
   332  	}
   333  
   334  	if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
   335  		t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
   336  	}
   337  
   338  	tr.CloseIdleConnections()
   339  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   340  		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
   341  	}
   342  }
   343  
   344  // Tests that the HTTP transport re-uses connections when a client
   345  // reads to the end of a response Body without closing it.
   346  func TestTransportReadToEndReusesConn(t *testing.T) {
   347  	defer afterTest(t)
   348  	const msg = "foobar"
   349  
   350  	var addrSeen map[string]int
   351  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   352  		addrSeen[r.RemoteAddr]++
   353  		if r.URL.Path == "/chunked/" {
   354  			w.WriteHeader(200)
   355  			w.(Flusher).Flush()
   356  		} else {
   357  			w.Header().Set("Content-Type", strconv.Itoa(len(msg)))
   358  			w.WriteHeader(200)
   359  		}
   360  		w.Write([]byte(msg))
   361  	}))
   362  	defer ts.Close()
   363  
   364  	buf := make([]byte, len(msg))
   365  
   366  	for pi, path := range []string{"/content-length/", "/chunked/"} {
   367  		wantLen := []int{len(msg), -1}[pi]
   368  		addrSeen = make(map[string]int)
   369  		for i := 0; i < 3; i++ {
   370  			res, err := Get(ts.URL + path)
   371  			if err != nil {
   372  				t.Errorf("Get %s: %v", path, err)
   373  				continue
   374  			}
   375  			// We want to close this body eventually (before the
   376  			// defer afterTest at top runs), but not before the
   377  			// len(addrSeen) check at the bottom of this test,
   378  			// since Closing this early in the loop would risk
   379  			// making connections be re-used for the wrong reason.
   380  			defer res.Body.Close()
   381  
   382  			if res.ContentLength != int64(wantLen) {
   383  				t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen)
   384  			}
   385  			n, err := res.Body.Read(buf)
   386  			if n != len(msg) || err != io.EOF {
   387  				t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg))
   388  			}
   389  		}
   390  		if len(addrSeen) != 1 {
   391  			t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen))
   392  		}
   393  	}
   394  }
   395  
   396  func TestTransportMaxPerHostIdleConns(t *testing.T) {
   397  	defer afterTest(t)
   398  	resch := make(chan string)
   399  	gotReq := make(chan bool)
   400  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   401  		gotReq <- true
   402  		msg := <-resch
   403  		_, err := w.Write([]byte(msg))
   404  		if err != nil {
   405  			t.Fatalf("Write: %v", err)
   406  		}
   407  	}))
   408  	defer ts.Close()
   409  
   410  	c := ts.Client()
   411  	tr := c.Transport.(*Transport)
   412  	maxIdleConnsPerHost := 2
   413  	tr.MaxIdleConnsPerHost = maxIdleConnsPerHost
   414  
   415  	// Start 3 outstanding requests and wait for the server to get them.
   416  	// Their responses will hang until we write to resch, though.
   417  	donech := make(chan bool)
   418  	doReq := func() {
   419  		resp, err := c.Get(ts.URL)
   420  		if err != nil {
   421  			t.Error(err)
   422  			return
   423  		}
   424  		if _, err := ioutil.ReadAll(resp.Body); err != nil {
   425  			t.Errorf("ReadAll: %v", err)
   426  			return
   427  		}
   428  		donech <- true
   429  	}
   430  	go doReq()
   431  	<-gotReq
   432  	go doReq()
   433  	<-gotReq
   434  	go doReq()
   435  	<-gotReq
   436  
   437  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   438  		t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
   439  	}
   440  
   441  	resch <- "res1"
   442  	<-donech
   443  	keys := tr.IdleConnKeysForTesting()
   444  	if e, g := 1, len(keys); e != g {
   445  		t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
   446  	}
   447  	cacheKey := "|http|" + ts.Listener.Addr().String()
   448  	if keys[0] != cacheKey {
   449  		t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
   450  	}
   451  	if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
   452  		t.Errorf("after first response, expected %d idle conns; got %d", e, g)
   453  	}
   454  
   455  	resch <- "res2"
   456  	<-donech
   457  	if g, w := tr.IdleConnCountForTesting(cacheKey), 2; g != w {
   458  		t.Errorf("after second response, idle conns = %d; want %d", g, w)
   459  	}
   460  
   461  	resch <- "res3"
   462  	<-donech
   463  	if g, w := tr.IdleConnCountForTesting(cacheKey), maxIdleConnsPerHost; g != w {
   464  		t.Errorf("after third response, idle conns = %d; want %d", g, w)
   465  	}
   466  }
   467  
   468  func TestTransportRemovesDeadIdleConnections(t *testing.T) {
   469  	setParallel(t)
   470  	defer afterTest(t)
   471  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   472  		io.WriteString(w, r.RemoteAddr)
   473  	}))
   474  	defer ts.Close()
   475  
   476  	c := ts.Client()
   477  	tr := c.Transport.(*Transport)
   478  
   479  	doReq := func(name string) string {
   480  		// Do a POST instead of a GET to prevent the Transport's
   481  		// idempotent request retry logic from kicking in...
   482  		res, err := c.Post(ts.URL, "", nil)
   483  		if err != nil {
   484  			t.Fatalf("%s: %v", name, err)
   485  		}
   486  		if res.StatusCode != 200 {
   487  			t.Fatalf("%s: %v", name, res.Status)
   488  		}
   489  		defer res.Body.Close()
   490  		slurp, err := ioutil.ReadAll(res.Body)
   491  		if err != nil {
   492  			t.Fatalf("%s: %v", name, err)
   493  		}
   494  		return string(slurp)
   495  	}
   496  
   497  	first := doReq("first")
   498  	keys1 := tr.IdleConnKeysForTesting()
   499  
   500  	ts.CloseClientConnections()
   501  
   502  	var keys2 []string
   503  	if !waitCondition(3*time.Second, 50*time.Millisecond, func() bool {
   504  		keys2 = tr.IdleConnKeysForTesting()
   505  		return len(keys2) == 0
   506  	}) {
   507  		t.Fatalf("Transport didn't notice idle connection's death.\nbefore: %q\n after: %q\n", keys1, keys2)
   508  	}
   509  
   510  	second := doReq("second")
   511  	if first == second {
   512  		t.Errorf("expected a different connection between requests. got %q both times", first)
   513  	}
   514  }
   515  
   516  func TestTransportServerClosingUnexpectedly(t *testing.T) {
   517  	setParallel(t)
   518  	defer afterTest(t)
   519  	ts := httptest.NewServer(hostPortHandler)
   520  	defer ts.Close()
   521  	c := ts.Client()
   522  
   523  	fetch := func(n, retries int) string {
   524  		condFatalf := func(format string, arg ...interface{}) {
   525  			if retries <= 0 {
   526  				t.Fatalf(format, arg...)
   527  			}
   528  			t.Logf("retrying shortly after expected error: "+format, arg...)
   529  			time.Sleep(time.Second / time.Duration(retries))
   530  		}
   531  		for retries >= 0 {
   532  			retries--
   533  			res, err := c.Get(ts.URL)
   534  			if err != nil {
   535  				condFatalf("error in req #%d, GET: %v", n, err)
   536  				continue
   537  			}
   538  			body, err := ioutil.ReadAll(res.Body)
   539  			if err != nil {
   540  				condFatalf("error in req #%d, ReadAll: %v", n, err)
   541  				continue
   542  			}
   543  			res.Body.Close()
   544  			return string(body)
   545  		}
   546  		panic("unreachable")
   547  	}
   548  
   549  	body1 := fetch(1, 0)
   550  	body2 := fetch(2, 0)
   551  
   552  	ts.CloseClientConnections() // surprise!
   553  
   554  	// This test has an expected race. Sleeping for 25 ms prevents
   555  	// it on most fast machines, causing the next fetch() call to
   556  	// succeed quickly. But if we do get errors, fetch() will retry 5
   557  	// times with some delays between.
   558  	time.Sleep(25 * time.Millisecond)
   559  
   560  	body3 := fetch(3, 5)
   561  
   562  	if body1 != body2 {
   563  		t.Errorf("expected body1 and body2 to be equal")
   564  	}
   565  	if body2 == body3 {
   566  		t.Errorf("expected body2 and body3 to be different")
   567  	}
   568  }
   569  
   570  // Test for https://golang.org/issue/2616 (appropriate issue number)
   571  // This fails pretty reliably with GOMAXPROCS=100 or something high.
   572  func TestStressSurpriseServerCloses(t *testing.T) {
   573  	defer afterTest(t)
   574  	if testing.Short() {
   575  		t.Skip("skipping test in short mode")
   576  	}
   577  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   578  		w.Header().Set("Content-Length", "5")
   579  		w.Header().Set("Content-Type", "text/plain")
   580  		w.Write([]byte("Hello"))
   581  		w.(Flusher).Flush()
   582  		conn, buf, _ := w.(Hijacker).Hijack()
   583  		buf.Flush()
   584  		conn.Close()
   585  	}))
   586  	defer ts.Close()
   587  	c := ts.Client()
   588  
   589  	// Do a bunch of traffic from different goroutines. Send to activityc
   590  	// after each request completes, regardless of whether it failed.
   591  	// If these are too high, OS X exhausts its ephemeral ports
   592  	// and hangs waiting for them to transition TCP states. That's
   593  	// not what we want to test. TODO(bradfitz): use an io.Pipe
   594  	// dialer for this test instead?
   595  	const (
   596  		numClients    = 20
   597  		reqsPerClient = 25
   598  	)
   599  	activityc := make(chan bool)
   600  	for i := 0; i < numClients; i++ {
   601  		go func() {
   602  			for i := 0; i < reqsPerClient; i++ {
   603  				res, err := c.Get(ts.URL)
   604  				if err == nil {
   605  					// We expect errors since the server is
   606  					// hanging up on us after telling us to
   607  					// send more requests, so we don't
   608  					// actually care what the error is.
   609  					// But we want to close the body in cases
   610  					// where we won the race.
   611  					res.Body.Close()
   612  				}
   613  				activityc <- true
   614  			}
   615  		}()
   616  	}
   617  
   618  	// Make sure all the request come back, one way or another.
   619  	for i := 0; i < numClients*reqsPerClient; i++ {
   620  		select {
   621  		case <-activityc:
   622  		case <-time.After(5 * time.Second):
   623  			t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
   624  		}
   625  	}
   626  }
   627  
   628  // TestTransportHeadResponses verifies that we deal with Content-Lengths
   629  // with no bodies properly
   630  func TestTransportHeadResponses(t *testing.T) {
   631  	defer afterTest(t)
   632  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   633  		if r.Method != "HEAD" {
   634  			panic("expected HEAD; got " + r.Method)
   635  		}
   636  		w.Header().Set("Content-Length", "123")
   637  		w.WriteHeader(200)
   638  	}))
   639  	defer ts.Close()
   640  	c := ts.Client()
   641  
   642  	for i := 0; i < 2; i++ {
   643  		res, err := c.Head(ts.URL)
   644  		if err != nil {
   645  			t.Errorf("error on loop %d: %v", i, err)
   646  			continue
   647  		}
   648  		if e, g := "123", res.Header.Get("Content-Length"); e != g {
   649  			t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
   650  		}
   651  		if e, g := int64(123), res.ContentLength; e != g {
   652  			t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
   653  		}
   654  		if all, err := ioutil.ReadAll(res.Body); err != nil {
   655  			t.Errorf("loop %d: Body ReadAll: %v", i, err)
   656  		} else if len(all) != 0 {
   657  			t.Errorf("Bogus body %q", all)
   658  		}
   659  	}
   660  }
   661  
   662  // TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
   663  // on responses to HEAD requests.
   664  func TestTransportHeadChunkedResponse(t *testing.T) {
   665  	defer afterTest(t)
   666  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   667  		if r.Method != "HEAD" {
   668  			panic("expected HEAD; got " + r.Method)
   669  		}
   670  		w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
   671  		w.Header().Set("x-client-ipport", r.RemoteAddr)
   672  		w.WriteHeader(200)
   673  	}))
   674  	defer ts.Close()
   675  	c := ts.Client()
   676  
   677  	// Ensure that we wait for the readLoop to complete before
   678  	// calling Head again
   679  	didRead := make(chan bool)
   680  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
   681  	defer SetReadLoopBeforeNextReadHook(nil)
   682  
   683  	res1, err := c.Head(ts.URL)
   684  	<-didRead
   685  
   686  	if err != nil {
   687  		t.Fatalf("request 1 error: %v", err)
   688  	}
   689  
   690  	res2, err := c.Head(ts.URL)
   691  	<-didRead
   692  
   693  	if err != nil {
   694  		t.Fatalf("request 2 error: %v", err)
   695  	}
   696  	if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
   697  		t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
   698  	}
   699  }
   700  
   701  var roundTripTests = []struct {
   702  	accept       string
   703  	expectAccept string
   704  	compressed   bool
   705  }{
   706  	// Requests with no accept-encoding header use transparent compression
   707  	{"", "gzip", false},
   708  	// Requests with other accept-encoding should pass through unmodified
   709  	{"foo", "foo", false},
   710  	// Requests with accept-encoding == gzip should be passed through
   711  	{"gzip", "gzip", true},
   712  }
   713  
   714  // Test that the modification made to the Request by the RoundTripper is cleaned up
   715  func TestRoundTripGzip(t *testing.T) {
   716  	setParallel(t)
   717  	defer afterTest(t)
   718  	const responseBody = "test response body"
   719  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   720  		accept := req.Header.Get("Accept-Encoding")
   721  		if expect := req.FormValue("expect_accept"); accept != expect {
   722  			t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
   723  				req.FormValue("testnum"), accept, expect)
   724  		}
   725  		if accept == "gzip" {
   726  			rw.Header().Set("Content-Encoding", "gzip")
   727  			gz := gzip.NewWriter(rw)
   728  			gz.Write([]byte(responseBody))
   729  			gz.Close()
   730  		} else {
   731  			rw.Header().Set("Content-Encoding", accept)
   732  			rw.Write([]byte(responseBody))
   733  		}
   734  	}))
   735  	defer ts.Close()
   736  	tr := ts.Client().Transport.(*Transport)
   737  
   738  	for i, test := range roundTripTests {
   739  		// Test basic request (no accept-encoding)
   740  		req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
   741  		if test.accept != "" {
   742  			req.Header.Set("Accept-Encoding", test.accept)
   743  		}
   744  		res, err := tr.RoundTrip(req)
   745  		var body []byte
   746  		if test.compressed {
   747  			var r *gzip.Reader
   748  			r, err = gzip.NewReader(res.Body)
   749  			if err != nil {
   750  				t.Errorf("%d. gzip NewReader: %v", i, err)
   751  				continue
   752  			}
   753  			body, err = ioutil.ReadAll(r)
   754  			res.Body.Close()
   755  		} else {
   756  			body, err = ioutil.ReadAll(res.Body)
   757  		}
   758  		if err != nil {
   759  			t.Errorf("%d. Error: %q", i, err)
   760  			continue
   761  		}
   762  		if g, e := string(body), responseBody; g != e {
   763  			t.Errorf("%d. body = %q; want %q", i, g, e)
   764  		}
   765  		if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
   766  			t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
   767  		}
   768  		if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
   769  			t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
   770  		}
   771  	}
   772  
   773  }
   774  
   775  func TestTransportGzip(t *testing.T) {
   776  	setParallel(t)
   777  	defer afterTest(t)
   778  	const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
   779  	const nRandBytes = 1024 * 1024
   780  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   781  		if req.Method == "HEAD" {
   782  			if g := req.Header.Get("Accept-Encoding"); g != "" {
   783  				t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g)
   784  			}
   785  			return
   786  		}
   787  		if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
   788  			t.Errorf("Accept-Encoding = %q, want %q", g, e)
   789  		}
   790  		rw.Header().Set("Content-Encoding", "gzip")
   791  
   792  		var w io.Writer = rw
   793  		var buf bytes.Buffer
   794  		if req.FormValue("chunked") == "0" {
   795  			w = &buf
   796  			defer io.Copy(rw, &buf)
   797  			defer func() {
   798  				rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
   799  			}()
   800  		}
   801  		gz := gzip.NewWriter(w)
   802  		gz.Write([]byte(testString))
   803  		if req.FormValue("body") == "large" {
   804  			io.CopyN(gz, rand.Reader, nRandBytes)
   805  		}
   806  		gz.Close()
   807  	}))
   808  	defer ts.Close()
   809  	c := ts.Client()
   810  
   811  	for _, chunked := range []string{"1", "0"} {
   812  		// First fetch something large, but only read some of it.
   813  		res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
   814  		if err != nil {
   815  			t.Fatalf("large get: %v", err)
   816  		}
   817  		buf := make([]byte, len(testString))
   818  		n, err := io.ReadFull(res.Body, buf)
   819  		if err != nil {
   820  			t.Fatalf("partial read of large response: size=%d, %v", n, err)
   821  		}
   822  		if e, g := testString, string(buf); e != g {
   823  			t.Errorf("partial read got %q, expected %q", g, e)
   824  		}
   825  		res.Body.Close()
   826  		// Read on the body, even though it's closed
   827  		n, err = res.Body.Read(buf)
   828  		if n != 0 || err == nil {
   829  			t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
   830  		}
   831  
   832  		// Then something small.
   833  		res, err = c.Get(ts.URL + "/?chunked=" + chunked)
   834  		if err != nil {
   835  			t.Fatal(err)
   836  		}
   837  		body, err := ioutil.ReadAll(res.Body)
   838  		if err != nil {
   839  			t.Fatal(err)
   840  		}
   841  		if g, e := string(body), testString; g != e {
   842  			t.Fatalf("body = %q; want %q", g, e)
   843  		}
   844  		if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
   845  			t.Fatalf("Content-Encoding = %q; want %q", g, e)
   846  		}
   847  
   848  		// Read on the body after it's been fully read:
   849  		n, err = res.Body.Read(buf)
   850  		if n != 0 || err == nil {
   851  			t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
   852  		}
   853  		res.Body.Close()
   854  		n, err = res.Body.Read(buf)
   855  		if n != 0 || err == nil {
   856  			t.Errorf("expected Read error after Close; got %d, %v", n, err)
   857  		}
   858  	}
   859  
   860  	// And a HEAD request too, because they're always weird.
   861  	res, err := c.Head(ts.URL)
   862  	if err != nil {
   863  		t.Fatalf("Head: %v", err)
   864  	}
   865  	if res.StatusCode != 200 {
   866  		t.Errorf("Head status=%d; want=200", res.StatusCode)
   867  	}
   868  }
   869  
   870  // If a request has Expect:100-continue header, the request blocks sending body until the first response.
   871  // Premature consumption of the request body should not be occurred.
   872  func TestTransportExpect100Continue(t *testing.T) {
   873  	setParallel(t)
   874  	defer afterTest(t)
   875  
   876  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   877  		switch req.URL.Path {
   878  		case "/100":
   879  			// This endpoint implicitly responds 100 Continue and reads body.
   880  			if _, err := io.Copy(ioutil.Discard, req.Body); err != nil {
   881  				t.Error("Failed to read Body", err)
   882  			}
   883  			rw.WriteHeader(StatusOK)
   884  		case "/200":
   885  			// Go 1.5 adds Connection: close header if the client expect
   886  			// continue but not entire request body is consumed.
   887  			rw.WriteHeader(StatusOK)
   888  		case "/500":
   889  			rw.WriteHeader(StatusInternalServerError)
   890  		case "/keepalive":
   891  			// This hijacked endpoint responds error without Connection:close.
   892  			_, bufrw, err := rw.(Hijacker).Hijack()
   893  			if err != nil {
   894  				log.Fatal(err)
   895  			}
   896  			bufrw.WriteString("HTTP/1.1 500 Internal Server Error\r\n")
   897  			bufrw.WriteString("Content-Length: 0\r\n\r\n")
   898  			bufrw.Flush()
   899  		case "/timeout":
   900  			// This endpoint tries to read body without 100 (Continue) response.
   901  			// After ExpectContinueTimeout, the reading will be started.
   902  			conn, bufrw, err := rw.(Hijacker).Hijack()
   903  			if err != nil {
   904  				log.Fatal(err)
   905  			}
   906  			if _, err := io.CopyN(ioutil.Discard, bufrw, req.ContentLength); err != nil {
   907  				t.Error("Failed to read Body", err)
   908  			}
   909  			bufrw.WriteString("HTTP/1.1 200 OK\r\n\r\n")
   910  			bufrw.Flush()
   911  			conn.Close()
   912  		}
   913  
   914  	}))
   915  	defer ts.Close()
   916  
   917  	tests := []struct {
   918  		path   string
   919  		body   []byte
   920  		sent   int
   921  		status int
   922  	}{
   923  		{path: "/100", body: []byte("hello"), sent: 5, status: 200},       // Got 100 followed by 200, entire body is sent.
   924  		{path: "/200", body: []byte("hello"), sent: 0, status: 200},       // Got 200 without 100. body isn't sent.
   925  		{path: "/500", body: []byte("hello"), sent: 0, status: 500},       // Got 500 without 100. body isn't sent.
   926  		{path: "/keepalive", body: []byte("hello"), sent: 0, status: 500}, // Although without Connection:close, body isn't sent.
   927  		{path: "/timeout", body: []byte("hello"), sent: 5, status: 200},   // Timeout exceeded and entire body is sent.
   928  	}
   929  
   930  	c := ts.Client()
   931  	for i, v := range tests {
   932  		tr := &Transport{
   933  			ExpectContinueTimeout: 2 * time.Second,
   934  		}
   935  		defer tr.CloseIdleConnections()
   936  		c.Transport = tr
   937  		body := bytes.NewReader(v.body)
   938  		req, err := NewRequest("PUT", ts.URL+v.path, body)
   939  		if err != nil {
   940  			t.Fatal(err)
   941  		}
   942  		req.Header.Set("Expect", "100-continue")
   943  		req.ContentLength = int64(len(v.body))
   944  
   945  		resp, err := c.Do(req)
   946  		if err != nil {
   947  			t.Fatal(err)
   948  		}
   949  		resp.Body.Close()
   950  
   951  		sent := len(v.body) - body.Len()
   952  		if v.status != resp.StatusCode {
   953  			t.Errorf("test %d: status code should be %d but got %d. (%s)", i, v.status, resp.StatusCode, v.path)
   954  		}
   955  		if v.sent != sent {
   956  			t.Errorf("test %d: sent body should be %d but sent %d. (%s)", i, v.sent, sent, v.path)
   957  		}
   958  	}
   959  }
   960  
   961  func TestSocks5Proxy(t *testing.T) {
   962  	defer afterTest(t)
   963  	ch := make(chan string, 1)
   964  	l := newLocalListener(t)
   965  	defer l.Close()
   966  	defer close(ch)
   967  	proxy := func(t *testing.T) {
   968  		s, err := l.Accept()
   969  		if err != nil {
   970  			t.Errorf("socks5 proxy Accept(): %v", err)
   971  			return
   972  		}
   973  		defer s.Close()
   974  		var buf [22]byte
   975  		if _, err := io.ReadFull(s, buf[:3]); err != nil {
   976  			t.Errorf("socks5 proxy initial read: %v", err)
   977  			return
   978  		}
   979  		if want := []byte{5, 1, 0}; !bytes.Equal(buf[:3], want) {
   980  			t.Errorf("socks5 proxy initial read: got %v, want %v", buf[:3], want)
   981  			return
   982  		}
   983  		if _, err := s.Write([]byte{5, 0}); err != nil {
   984  			t.Errorf("socks5 proxy initial write: %v", err)
   985  			return
   986  		}
   987  		if _, err := io.ReadFull(s, buf[:4]); err != nil {
   988  			t.Errorf("socks5 proxy second read: %v", err)
   989  			return
   990  		}
   991  		if want := []byte{5, 1, 0}; !bytes.Equal(buf[:3], want) {
   992  			t.Errorf("socks5 proxy second read: got %v, want %v", buf[:3], want)
   993  			return
   994  		}
   995  		var ipLen int
   996  		switch buf[3] {
   997  		case 1:
   998  			ipLen = 4
   999  		case 4:
  1000  			ipLen = 16
  1001  		default:
  1002  			t.Errorf("socks5 proxy second read: unexpected address type %v", buf[4])
  1003  			return
  1004  		}
  1005  		if _, err := io.ReadFull(s, buf[4:ipLen+6]); err != nil {
  1006  			t.Errorf("socks5 proxy address read: %v", err)
  1007  			return
  1008  		}
  1009  		ip := net.IP(buf[4 : ipLen+4])
  1010  		port := binary.BigEndian.Uint16(buf[ipLen+4 : ipLen+6])
  1011  		copy(buf[:3], []byte{5, 0, 0})
  1012  		if _, err := s.Write(buf[:ipLen+6]); err != nil {
  1013  			t.Errorf("socks5 proxy connect write: %v", err)
  1014  			return
  1015  		}
  1016  		ch <- fmt.Sprintf("proxy for %s:%d", ip, port)
  1017  
  1018  		// Implement proxying.
  1019  		targetHost := net.JoinHostPort(ip.String(), strconv.Itoa(int(port)))
  1020  		targetConn, err := net.Dial("tcp", targetHost)
  1021  		if err != nil {
  1022  			t.Errorf("net.Dial failed")
  1023  			return
  1024  		}
  1025  		go io.Copy(targetConn, s)
  1026  		io.Copy(s, targetConn) // Wait for the client to close the socket.
  1027  		targetConn.Close()
  1028  	}
  1029  
  1030  	pu, err := url.Parse("socks5://" + l.Addr().String())
  1031  	if err != nil {
  1032  		t.Fatal(err)
  1033  	}
  1034  
  1035  	sentinelHeader := "X-Sentinel"
  1036  	sentinelValue := "12345"
  1037  	h := HandlerFunc(func(w ResponseWriter, r *Request) {
  1038  		w.Header().Set(sentinelHeader, sentinelValue)
  1039  	})
  1040  	for _, useTLS := range []bool{false, true} {
  1041  		t.Run(fmt.Sprintf("useTLS=%v", useTLS), func(t *testing.T) {
  1042  			var ts *httptest.Server
  1043  			if useTLS {
  1044  				ts = httptest.NewTLSServer(h)
  1045  			} else {
  1046  				ts = httptest.NewServer(h)
  1047  			}
  1048  			go proxy(t)
  1049  			c := ts.Client()
  1050  			c.Transport.(*Transport).Proxy = ProxyURL(pu)
  1051  			r, err := c.Head(ts.URL)
  1052  			if err != nil {
  1053  				t.Fatal(err)
  1054  			}
  1055  			if r.Header.Get(sentinelHeader) != sentinelValue {
  1056  				t.Errorf("Failed to retrieve sentinel value")
  1057  			}
  1058  			var got string
  1059  			select {
  1060  			case got = <-ch:
  1061  			case <-time.After(5 * time.Second):
  1062  				t.Fatal("timeout connecting to socks5 proxy")
  1063  			}
  1064  			ts.Close()
  1065  			tsu, err := url.Parse(ts.URL)
  1066  			if err != nil {
  1067  				t.Fatal(err)
  1068  			}
  1069  			want := "proxy for " + tsu.Host
  1070  			if got != want {
  1071  				t.Errorf("got %q, want %q", got, want)
  1072  			}
  1073  		})
  1074  	}
  1075  }
  1076  
  1077  func TestTransportProxy(t *testing.T) {
  1078  	defer afterTest(t)
  1079  	testCases := []struct{ httpsSite, httpsProxy bool }{
  1080  		{false, false},
  1081  		{false, true},
  1082  		{true, false},
  1083  		{true, true},
  1084  	}
  1085  	for _, testCase := range testCases {
  1086  		httpsSite := testCase.httpsSite
  1087  		httpsProxy := testCase.httpsProxy
  1088  		t.Run(fmt.Sprintf("httpsSite=%v, httpsProxy=%v", httpsSite, httpsProxy), func(t *testing.T) {
  1089  			siteCh := make(chan *Request, 1)
  1090  			h1 := HandlerFunc(func(w ResponseWriter, r *Request) {
  1091  				siteCh <- r
  1092  			})
  1093  			proxyCh := make(chan *Request, 1)
  1094  			h2 := HandlerFunc(func(w ResponseWriter, r *Request) {
  1095  				proxyCh <- r
  1096  				// Implement an entire CONNECT proxy
  1097  				if r.Method == "CONNECT" {
  1098  					hijacker, ok := w.(Hijacker)
  1099  					if !ok {
  1100  						t.Errorf("hijack not allowed")
  1101  						return
  1102  					}
  1103  					clientConn, _, err := hijacker.Hijack()
  1104  					if err != nil {
  1105  						t.Errorf("hijacking failed")
  1106  						return
  1107  					}
  1108  					res := &Response{
  1109  						StatusCode: StatusOK,
  1110  						Proto:      "HTTP/1.1",
  1111  						ProtoMajor: 1,
  1112  						ProtoMinor: 1,
  1113  						Header:     make(Header),
  1114  					}
  1115  
  1116  					targetConn, err := net.Dial("tcp", r.URL.Host)
  1117  					if err != nil {
  1118  						t.Errorf("net.Dial(%q) failed: %v", r.URL.Host, err)
  1119  						return
  1120  					}
  1121  
  1122  					if err := res.Write(clientConn); err != nil {
  1123  						t.Errorf("Writing 200 OK failed: %v", err)
  1124  						return
  1125  					}
  1126  
  1127  					go io.Copy(targetConn, clientConn)
  1128  					go func() {
  1129  						io.Copy(clientConn, targetConn)
  1130  						targetConn.Close()
  1131  					}()
  1132  				}
  1133  			})
  1134  			var ts *httptest.Server
  1135  			if httpsSite {
  1136  				ts = httptest.NewTLSServer(h1)
  1137  			} else {
  1138  				ts = httptest.NewServer(h1)
  1139  			}
  1140  			var proxy *httptest.Server
  1141  			if httpsProxy {
  1142  				proxy = httptest.NewTLSServer(h2)
  1143  			} else {
  1144  				proxy = httptest.NewServer(h2)
  1145  			}
  1146  
  1147  			pu, err := url.Parse(proxy.URL)
  1148  			if err != nil {
  1149  				t.Fatal(err)
  1150  			}
  1151  
  1152  			// If neither server is HTTPS or both are, then c may be derived from either.
  1153  			// If only one server is HTTPS, c must be derived from that server in order
  1154  			// to ensure that it is configured to use the fake root CA from testcert.go.
  1155  			c := proxy.Client()
  1156  			if httpsSite {
  1157  				c = ts.Client()
  1158  			}
  1159  
  1160  			c.Transport.(*Transport).Proxy = ProxyURL(pu)
  1161  			if _, err := c.Head(ts.URL); err != nil {
  1162  				t.Error(err)
  1163  			}
  1164  			var got *Request
  1165  			select {
  1166  			case got = <-proxyCh:
  1167  			case <-time.After(5 * time.Second):
  1168  				t.Fatal("timeout connecting to http proxy")
  1169  			}
  1170  			c.Transport.(*Transport).CloseIdleConnections()
  1171  			ts.Close()
  1172  			proxy.Close()
  1173  			if httpsSite {
  1174  				// First message should be a CONNECT, asking for a socket to the real server,
  1175  				if got.Method != "CONNECT" {
  1176  					t.Errorf("Wrong method for secure proxying: %q", got.Method)
  1177  				}
  1178  				gotHost := got.URL.Host
  1179  				pu, err := url.Parse(ts.URL)
  1180  				if err != nil {
  1181  					t.Fatal("Invalid site URL")
  1182  				}
  1183  				if wantHost := pu.Host; gotHost != wantHost {
  1184  					t.Errorf("Got CONNECT host %q, want %q", gotHost, wantHost)
  1185  				}
  1186  
  1187  				// The next message on the channel should be from the site's server.
  1188  				next := <-siteCh
  1189  				if next.Method != "HEAD" {
  1190  					t.Errorf("Wrong method at destination: %s", next.Method)
  1191  				}
  1192  				if nextURL := next.URL.String(); nextURL != "/" {
  1193  					t.Errorf("Wrong URL at destination: %s", nextURL)
  1194  				}
  1195  			} else {
  1196  				if got.Method != "HEAD" {
  1197  					t.Errorf("Wrong method for destination: %q", got.Method)
  1198  				}
  1199  				gotURL := got.URL.String()
  1200  				wantURL := ts.URL + "/"
  1201  				if gotURL != wantURL {
  1202  					t.Errorf("Got URL %q, want %q", gotURL, wantURL)
  1203  				}
  1204  			}
  1205  		})
  1206  	}
  1207  }
  1208  
  1209  // Issue 16997: test transport dial preserves typed errors
  1210  func TestTransportDialPreservesNetOpProxyError(t *testing.T) {
  1211  	defer afterTest(t)
  1212  
  1213  	var errDial = errors.New("some dial error")
  1214  
  1215  	tr := &Transport{
  1216  		Proxy: func(*Request) (*url.URL, error) {
  1217  			return url.Parse("http://proxy.fake.tld/")
  1218  		},
  1219  		Dial: func(string, string) (net.Conn, error) {
  1220  			return nil, errDial
  1221  		},
  1222  	}
  1223  	defer tr.CloseIdleConnections()
  1224  
  1225  	c := &Client{Transport: tr}
  1226  	req, _ := NewRequest("GET", "http://fake.tld", nil)
  1227  	res, err := c.Do(req)
  1228  	if err == nil {
  1229  		res.Body.Close()
  1230  		t.Fatal("wanted a non-nil error")
  1231  	}
  1232  
  1233  	uerr, ok := err.(*url.Error)
  1234  	if !ok {
  1235  		t.Fatalf("got %T, want *url.Error", err)
  1236  	}
  1237  	oe, ok := uerr.Err.(*net.OpError)
  1238  	if !ok {
  1239  		t.Fatalf("url.Error.Err =  %T; want *net.OpError", uerr.Err)
  1240  	}
  1241  	want := &net.OpError{
  1242  		Op:  "proxyconnect",
  1243  		Net: "tcp",
  1244  		Err: errDial, // original error, unwrapped.
  1245  	}
  1246  	if !reflect.DeepEqual(oe, want) {
  1247  		t.Errorf("Got error %#v; want %#v", oe, want)
  1248  	}
  1249  }
  1250  
  1251  // TestTransportGzipRecursive sends a gzip quine and checks that the
  1252  // client gets the same value back. This is more cute than anything,
  1253  // but checks that we don't recurse forever, and checks that
  1254  // Content-Encoding is removed.
  1255  func TestTransportGzipRecursive(t *testing.T) {
  1256  	defer afterTest(t)
  1257  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1258  		w.Header().Set("Content-Encoding", "gzip")
  1259  		w.Write(rgz)
  1260  	}))
  1261  	defer ts.Close()
  1262  
  1263  	c := ts.Client()
  1264  	res, err := c.Get(ts.URL)
  1265  	if err != nil {
  1266  		t.Fatal(err)
  1267  	}
  1268  	body, err := ioutil.ReadAll(res.Body)
  1269  	if err != nil {
  1270  		t.Fatal(err)
  1271  	}
  1272  	if !bytes.Equal(body, rgz) {
  1273  		t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
  1274  			body, rgz)
  1275  	}
  1276  	if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
  1277  		t.Fatalf("Content-Encoding = %q; want %q", g, e)
  1278  	}
  1279  }
  1280  
  1281  // golang.org/issue/7750: request fails when server replies with
  1282  // a short gzip body
  1283  func TestTransportGzipShort(t *testing.T) {
  1284  	defer afterTest(t)
  1285  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1286  		w.Header().Set("Content-Encoding", "gzip")
  1287  		w.Write([]byte{0x1f, 0x8b})
  1288  	}))
  1289  	defer ts.Close()
  1290  
  1291  	c := ts.Client()
  1292  	res, err := c.Get(ts.URL)
  1293  	if err != nil {
  1294  		t.Fatal(err)
  1295  	}
  1296  	defer res.Body.Close()
  1297  	_, err = ioutil.ReadAll(res.Body)
  1298  	if err == nil {
  1299  		t.Fatal("Expect an error from reading a body.")
  1300  	}
  1301  	if err != io.ErrUnexpectedEOF {
  1302  		t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err)
  1303  	}
  1304  }
  1305  
  1306  // Wait until number of goroutines is no greater than nmax, or time out.
  1307  func waitNumGoroutine(nmax int) int {
  1308  	nfinal := runtime.NumGoroutine()
  1309  	for ntries := 10; ntries > 0 && nfinal > nmax; ntries-- {
  1310  		time.Sleep(50 * time.Millisecond)
  1311  		runtime.GC()
  1312  		nfinal = runtime.NumGoroutine()
  1313  	}
  1314  	return nfinal
  1315  }
  1316  
  1317  // tests that persistent goroutine connections shut down when no longer desired.
  1318  func TestTransportPersistConnLeak(t *testing.T) {
  1319  	// Not parallel: counts goroutines
  1320  	defer afterTest(t)
  1321  
  1322  	const numReq = 25
  1323  	gotReqCh := make(chan bool, numReq)
  1324  	unblockCh := make(chan bool, numReq)
  1325  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1326  		gotReqCh <- true
  1327  		<-unblockCh
  1328  		w.Header().Set("Content-Length", "0")
  1329  		w.WriteHeader(204)
  1330  	}))
  1331  	defer ts.Close()
  1332  	c := ts.Client()
  1333  	tr := c.Transport.(*Transport)
  1334  
  1335  	n0 := runtime.NumGoroutine()
  1336  
  1337  	didReqCh := make(chan bool, numReq)
  1338  	failed := make(chan bool, numReq)
  1339  	for i := 0; i < numReq; i++ {
  1340  		go func() {
  1341  			res, err := c.Get(ts.URL)
  1342  			didReqCh <- true
  1343  			if err != nil {
  1344  				t.Errorf("client fetch error: %v", err)
  1345  				failed <- true
  1346  				return
  1347  			}
  1348  			res.Body.Close()
  1349  		}()
  1350  	}
  1351  
  1352  	// Wait for all goroutines to be stuck in the Handler.
  1353  	for i := 0; i < numReq; i++ {
  1354  		select {
  1355  		case <-gotReqCh:
  1356  			// ok
  1357  		case <-failed:
  1358  			close(unblockCh)
  1359  			return
  1360  		}
  1361  	}
  1362  
  1363  	nhigh := runtime.NumGoroutine()
  1364  
  1365  	// Tell all handlers to unblock and reply.
  1366  	for i := 0; i < numReq; i++ {
  1367  		unblockCh <- true
  1368  	}
  1369  
  1370  	// Wait for all HTTP clients to be done.
  1371  	for i := 0; i < numReq; i++ {
  1372  		<-didReqCh
  1373  	}
  1374  
  1375  	tr.CloseIdleConnections()
  1376  	nfinal := waitNumGoroutine(n0 + 5)
  1377  
  1378  	growth := nfinal - n0
  1379  
  1380  	// We expect 0 or 1 extra goroutine, empirically. Allow up to 5.
  1381  	// Previously we were leaking one per numReq.
  1382  	if int(growth) > 5 {
  1383  		t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
  1384  		t.Error("too many new goroutines")
  1385  	}
  1386  }
  1387  
  1388  // golang.org/issue/4531: Transport leaks goroutines when
  1389  // request.ContentLength is explicitly short
  1390  func TestTransportPersistConnLeakShortBody(t *testing.T) {
  1391  	// Not parallel: measures goroutines.
  1392  	defer afterTest(t)
  1393  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1394  	}))
  1395  	defer ts.Close()
  1396  	c := ts.Client()
  1397  	tr := c.Transport.(*Transport)
  1398  
  1399  	n0 := runtime.NumGoroutine()
  1400  	body := []byte("Hello")
  1401  	for i := 0; i < 20; i++ {
  1402  		req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
  1403  		if err != nil {
  1404  			t.Fatal(err)
  1405  		}
  1406  		req.ContentLength = int64(len(body) - 2) // explicitly short
  1407  		_, err = c.Do(req)
  1408  		if err == nil {
  1409  			t.Fatal("Expect an error from writing too long of a body.")
  1410  		}
  1411  	}
  1412  	nhigh := runtime.NumGoroutine()
  1413  	tr.CloseIdleConnections()
  1414  	nfinal := waitNumGoroutine(n0 + 5)
  1415  
  1416  	growth := nfinal - n0
  1417  
  1418  	// We expect 0 or 1 extra goroutine, empirically. Allow up to 5.
  1419  	// Previously we were leaking one per numReq.
  1420  	t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
  1421  	if int(growth) > 5 {
  1422  		t.Error("too many new goroutines")
  1423  	}
  1424  }
  1425  
  1426  // This used to crash; https://golang.org/issue/3266
  1427  func TestTransportIdleConnCrash(t *testing.T) {
  1428  	defer afterTest(t)
  1429  	var tr *Transport
  1430  
  1431  	unblockCh := make(chan bool, 1)
  1432  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1433  		<-unblockCh
  1434  		tr.CloseIdleConnections()
  1435  	}))
  1436  	defer ts.Close()
  1437  	c := ts.Client()
  1438  	tr = c.Transport.(*Transport)
  1439  
  1440  	didreq := make(chan bool)
  1441  	go func() {
  1442  		res, err := c.Get(ts.URL)
  1443  		if err != nil {
  1444  			t.Error(err)
  1445  		} else {
  1446  			res.Body.Close() // returns idle conn
  1447  		}
  1448  		didreq <- true
  1449  	}()
  1450  	unblockCh <- true
  1451  	<-didreq
  1452  }
  1453  
  1454  // Test that the transport doesn't close the TCP connection early,
  1455  // before the response body has been read. This was a regression
  1456  // which sadly lacked a triggering test. The large response body made
  1457  // the old race easier to trigger.
  1458  func TestIssue3644(t *testing.T) {
  1459  	defer afterTest(t)
  1460  	const numFoos = 5000
  1461  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1462  		w.Header().Set("Connection", "close")
  1463  		for i := 0; i < numFoos; i++ {
  1464  			w.Write([]byte("foo "))
  1465  		}
  1466  	}))
  1467  	defer ts.Close()
  1468  	c := ts.Client()
  1469  	res, err := c.Get(ts.URL)
  1470  	if err != nil {
  1471  		t.Fatal(err)
  1472  	}
  1473  	defer res.Body.Close()
  1474  	bs, err := ioutil.ReadAll(res.Body)
  1475  	if err != nil {
  1476  		t.Fatal(err)
  1477  	}
  1478  	if len(bs) != numFoos*len("foo ") {
  1479  		t.Errorf("unexpected response length")
  1480  	}
  1481  }
  1482  
  1483  // Test that a client receives a server's reply, even if the server doesn't read
  1484  // the entire request body.
  1485  func TestIssue3595(t *testing.T) {
  1486  	setParallel(t)
  1487  	defer afterTest(t)
  1488  	const deniedMsg = "sorry, denied."
  1489  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1490  		Error(w, deniedMsg, StatusUnauthorized)
  1491  	}))
  1492  	defer ts.Close()
  1493  	c := ts.Client()
  1494  	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
  1495  	if err != nil {
  1496  		t.Errorf("Post: %v", err)
  1497  		return
  1498  	}
  1499  	got, err := ioutil.ReadAll(res.Body)
  1500  	if err != nil {
  1501  		t.Fatalf("Body ReadAll: %v", err)
  1502  	}
  1503  	if !strings.Contains(string(got), deniedMsg) {
  1504  		t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
  1505  	}
  1506  }
  1507  
  1508  // From https://golang.org/issue/4454 ,
  1509  // "client fails to handle requests with no body and chunked encoding"
  1510  func TestChunkedNoContent(t *testing.T) {
  1511  	defer afterTest(t)
  1512  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1513  		w.WriteHeader(StatusNoContent)
  1514  	}))
  1515  	defer ts.Close()
  1516  
  1517  	c := ts.Client()
  1518  	for _, closeBody := range []bool{true, false} {
  1519  		const n = 4
  1520  		for i := 1; i <= n; i++ {
  1521  			res, err := c.Get(ts.URL)
  1522  			if err != nil {
  1523  				t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
  1524  			} else {
  1525  				if closeBody {
  1526  					res.Body.Close()
  1527  				}
  1528  			}
  1529  		}
  1530  	}
  1531  }
  1532  
  1533  func TestTransportConcurrency(t *testing.T) {
  1534  	// Not parallel: uses global test hooks.
  1535  	defer afterTest(t)
  1536  	maxProcs, numReqs := 16, 500
  1537  	if testing.Short() {
  1538  		maxProcs, numReqs = 4, 50
  1539  	}
  1540  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
  1541  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1542  		fmt.Fprintf(w, "%v", r.FormValue("echo"))
  1543  	}))
  1544  	defer ts.Close()
  1545  
  1546  	var wg sync.WaitGroup
  1547  	wg.Add(numReqs)
  1548  
  1549  	// Due to the Transport's "socket late binding" (see
  1550  	// idleConnCh in transport.go), the numReqs HTTP requests
  1551  	// below can finish with a dial still outstanding. To keep
  1552  	// the leak checker happy, keep track of pending dials and
  1553  	// wait for them to finish (and be closed or returned to the
  1554  	// idle pool) before we close idle connections.
  1555  	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
  1556  	defer SetPendingDialHooks(nil, nil)
  1557  
  1558  	c := ts.Client()
  1559  	reqs := make(chan string)
  1560  	defer close(reqs)
  1561  
  1562  	for i := 0; i < maxProcs*2; i++ {
  1563  		go func() {
  1564  			for req := range reqs {
  1565  				res, err := c.Get(ts.URL + "/?echo=" + req)
  1566  				if err != nil {
  1567  					t.Errorf("error on req %s: %v", req, err)
  1568  					wg.Done()
  1569  					continue
  1570  				}
  1571  				all, err := ioutil.ReadAll(res.Body)
  1572  				if err != nil {
  1573  					t.Errorf("read error on req %s: %v", req, err)
  1574  					wg.Done()
  1575  					continue
  1576  				}
  1577  				if string(all) != req {
  1578  					t.Errorf("body of req %s = %q; want %q", req, all, req)
  1579  				}
  1580  				res.Body.Close()
  1581  				wg.Done()
  1582  			}
  1583  		}()
  1584  	}
  1585  	for i := 0; i < numReqs; i++ {
  1586  		reqs <- fmt.Sprintf("request-%d", i)
  1587  	}
  1588  	wg.Wait()
  1589  }
  1590  
  1591  func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
  1592  	setParallel(t)
  1593  	defer afterTest(t)
  1594  	const debug = false
  1595  	mux := NewServeMux()
  1596  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1597  		io.Copy(w, neverEnding('a'))
  1598  	})
  1599  	ts := httptest.NewServer(mux)
  1600  	defer ts.Close()
  1601  	timeout := 100 * time.Millisecond
  1602  
  1603  	c := ts.Client()
  1604  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  1605  		conn, err := net.Dial(n, addr)
  1606  		if err != nil {
  1607  			return nil, err
  1608  		}
  1609  		conn.SetDeadline(time.Now().Add(timeout))
  1610  		if debug {
  1611  			conn = NewLoggingConn("client", conn)
  1612  		}
  1613  		return conn, nil
  1614  	}
  1615  
  1616  	getFailed := false
  1617  	nRuns := 5
  1618  	if testing.Short() {
  1619  		nRuns = 1
  1620  	}
  1621  	for i := 0; i < nRuns; i++ {
  1622  		if debug {
  1623  			println("run", i+1, "of", nRuns)
  1624  		}
  1625  		sres, err := c.Get(ts.URL + "/get")
  1626  		if err != nil {
  1627  			if !getFailed {
  1628  				// Make the timeout longer, once.
  1629  				getFailed = true
  1630  				t.Logf("increasing timeout")
  1631  				i--
  1632  				timeout *= 10
  1633  				continue
  1634  			}
  1635  			t.Errorf("Error issuing GET: %v", err)
  1636  			break
  1637  		}
  1638  		_, err = io.Copy(ioutil.Discard, sres.Body)
  1639  		if err == nil {
  1640  			t.Errorf("Unexpected successful copy")
  1641  			break
  1642  		}
  1643  	}
  1644  	if debug {
  1645  		println("tests complete; waiting for handlers to finish")
  1646  	}
  1647  }
  1648  
  1649  func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
  1650  	setParallel(t)
  1651  	defer afterTest(t)
  1652  	const debug = false
  1653  	mux := NewServeMux()
  1654  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1655  		io.Copy(w, neverEnding('a'))
  1656  	})
  1657  	mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
  1658  		defer r.Body.Close()
  1659  		io.Copy(ioutil.Discard, r.Body)
  1660  	})
  1661  	ts := httptest.NewServer(mux)
  1662  	timeout := 100 * time.Millisecond
  1663  
  1664  	c := ts.Client()
  1665  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  1666  		conn, err := net.Dial(n, addr)
  1667  		if err != nil {
  1668  			return nil, err
  1669  		}
  1670  		conn.SetDeadline(time.Now().Add(timeout))
  1671  		if debug {
  1672  			conn = NewLoggingConn("client", conn)
  1673  		}
  1674  		return conn, nil
  1675  	}
  1676  
  1677  	getFailed := false
  1678  	nRuns := 5
  1679  	if testing.Short() {
  1680  		nRuns = 1
  1681  	}
  1682  	for i := 0; i < nRuns; i++ {
  1683  		if debug {
  1684  			println("run", i+1, "of", nRuns)
  1685  		}
  1686  		sres, err := c.Get(ts.URL + "/get")
  1687  		if err != nil {
  1688  			if !getFailed {
  1689  				// Make the timeout longer, once.
  1690  				getFailed = true
  1691  				t.Logf("increasing timeout")
  1692  				i--
  1693  				timeout *= 10
  1694  				continue
  1695  			}
  1696  			t.Errorf("Error issuing GET: %v", err)
  1697  			break
  1698  		}
  1699  		req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
  1700  		_, err = c.Do(req)
  1701  		if err == nil {
  1702  			sres.Body.Close()
  1703  			t.Errorf("Unexpected successful PUT")
  1704  			break
  1705  		}
  1706  		sres.Body.Close()
  1707  	}
  1708  	if debug {
  1709  		println("tests complete; waiting for handlers to finish")
  1710  	}
  1711  	ts.Close()
  1712  }
  1713  
  1714  func TestTransportResponseHeaderTimeout(t *testing.T) {
  1715  	setParallel(t)
  1716  	defer afterTest(t)
  1717  	if testing.Short() {
  1718  		t.Skip("skipping timeout test in -short mode")
  1719  	}
  1720  	inHandler := make(chan bool, 1)
  1721  	mux := NewServeMux()
  1722  	mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {
  1723  		inHandler <- true
  1724  	})
  1725  	mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
  1726  		inHandler <- true
  1727  		time.Sleep(2 * time.Second)
  1728  	})
  1729  	ts := httptest.NewServer(mux)
  1730  	defer ts.Close()
  1731  
  1732  	c := ts.Client()
  1733  	c.Transport.(*Transport).ResponseHeaderTimeout = 500 * time.Millisecond
  1734  
  1735  	tests := []struct {
  1736  		path    string
  1737  		want    int
  1738  		wantErr string
  1739  	}{
  1740  		{path: "/fast", want: 200},
  1741  		{path: "/slow", wantErr: "timeout awaiting response headers"},
  1742  		{path: "/fast", want: 200},
  1743  	}
  1744  	for i, tt := range tests {
  1745  		req, _ := NewRequest("GET", ts.URL+tt.path, nil)
  1746  		req = req.WithT(t)
  1747  		res, err := c.Do(req)
  1748  		select {
  1749  		case <-inHandler:
  1750  		case <-time.After(5 * time.Second):
  1751  			t.Errorf("never entered handler for test index %d, %s", i, tt.path)
  1752  			continue
  1753  		}
  1754  		if err != nil {
  1755  			uerr, ok := err.(*url.Error)
  1756  			if !ok {
  1757  				t.Errorf("error is not an url.Error; got: %#v", err)
  1758  				continue
  1759  			}
  1760  			nerr, ok := uerr.Err.(net.Error)
  1761  			if !ok {
  1762  				t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
  1763  				continue
  1764  			}
  1765  			if !nerr.Timeout() {
  1766  				t.Errorf("want timeout error; got: %q", nerr)
  1767  				continue
  1768  			}
  1769  			if strings.Contains(err.Error(), tt.wantErr) {
  1770  				continue
  1771  			}
  1772  			t.Errorf("%d. unexpected error: %v", i, err)
  1773  			continue
  1774  		}
  1775  		if tt.wantErr != "" {
  1776  			t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
  1777  			continue
  1778  		}
  1779  		if res.StatusCode != tt.want {
  1780  			t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
  1781  		}
  1782  	}
  1783  }
  1784  
  1785  func TestTransportCancelRequest(t *testing.T) {
  1786  	setParallel(t)
  1787  	defer afterTest(t)
  1788  	if testing.Short() {
  1789  		t.Skip("skipping test in -short mode")
  1790  	}
  1791  	unblockc := make(chan bool)
  1792  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1793  		fmt.Fprintf(w, "Hello")
  1794  		w.(Flusher).Flush() // send headers and some body
  1795  		<-unblockc
  1796  	}))
  1797  	defer ts.Close()
  1798  	defer close(unblockc)
  1799  
  1800  	c := ts.Client()
  1801  	tr := c.Transport.(*Transport)
  1802  
  1803  	req, _ := NewRequest("GET", ts.URL, nil)
  1804  	res, err := c.Do(req)
  1805  	if err != nil {
  1806  		t.Fatal(err)
  1807  	}
  1808  	go func() {
  1809  		time.Sleep(1 * time.Second)
  1810  		tr.CancelRequest(req)
  1811  	}()
  1812  	t0 := time.Now()
  1813  	body, err := ioutil.ReadAll(res.Body)
  1814  	d := time.Since(t0)
  1815  
  1816  	if err != ExportErrRequestCanceled {
  1817  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  1818  	}
  1819  	if string(body) != "Hello" {
  1820  		t.Errorf("Body = %q; want Hello", body)
  1821  	}
  1822  	if d < 500*time.Millisecond {
  1823  		t.Errorf("expected ~1 second delay; got %v", d)
  1824  	}
  1825  	// Verify no outstanding requests after readLoop/writeLoop
  1826  	// goroutines shut down.
  1827  	for tries := 5; tries > 0; tries-- {
  1828  		n := tr.NumPendingRequestsForTesting()
  1829  		if n == 0 {
  1830  			break
  1831  		}
  1832  		time.Sleep(100 * time.Millisecond)
  1833  		if tries == 1 {
  1834  			t.Errorf("pending requests = %d; want 0", n)
  1835  		}
  1836  	}
  1837  }
  1838  
  1839  func TestTransportCancelRequestInDial(t *testing.T) {
  1840  	defer afterTest(t)
  1841  	if testing.Short() {
  1842  		t.Skip("skipping test in -short mode")
  1843  	}
  1844  	var logbuf bytes.Buffer
  1845  	eventLog := log.New(&logbuf, "", 0)
  1846  
  1847  	unblockDial := make(chan bool)
  1848  	defer close(unblockDial)
  1849  
  1850  	inDial := make(chan bool)
  1851  	tr := &Transport{
  1852  		Dial: func(network, addr string) (net.Conn, error) {
  1853  			eventLog.Println("dial: blocking")
  1854  			inDial <- true
  1855  			<-unblockDial
  1856  			return nil, errors.New("nope")
  1857  		},
  1858  	}
  1859  	cl := &Client{Transport: tr}
  1860  	gotres := make(chan bool)
  1861  	req, _ := NewRequest("GET", "http://something.no-network.tld/", nil)
  1862  	go func() {
  1863  		_, err := cl.Do(req)
  1864  		eventLog.Printf("Get = %v", err)
  1865  		gotres <- true
  1866  	}()
  1867  
  1868  	select {
  1869  	case <-inDial:
  1870  	case <-time.After(5 * time.Second):
  1871  		t.Fatal("timeout; never saw blocking dial")
  1872  	}
  1873  
  1874  	eventLog.Printf("canceling")
  1875  	tr.CancelRequest(req)
  1876  	tr.CancelRequest(req) // used to panic on second call
  1877  
  1878  	select {
  1879  	case <-gotres:
  1880  	case <-time.After(5 * time.Second):
  1881  		panic("hang. events are: " + logbuf.String())
  1882  	}
  1883  
  1884  	got := logbuf.String()
  1885  	want := `dial: blocking
  1886  canceling
  1887  Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection
  1888  `
  1889  	if got != want {
  1890  		t.Errorf("Got events:\n%s\nWant:\n%s", got, want)
  1891  	}
  1892  }
  1893  
  1894  func TestCancelRequestWithChannel(t *testing.T) {
  1895  	setParallel(t)
  1896  	defer afterTest(t)
  1897  	if testing.Short() {
  1898  		t.Skip("skipping test in -short mode")
  1899  	}
  1900  	unblockc := make(chan bool)
  1901  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1902  		fmt.Fprintf(w, "Hello")
  1903  		w.(Flusher).Flush() // send headers and some body
  1904  		<-unblockc
  1905  	}))
  1906  	defer ts.Close()
  1907  	defer close(unblockc)
  1908  
  1909  	c := ts.Client()
  1910  	tr := c.Transport.(*Transport)
  1911  
  1912  	req, _ := NewRequest("GET", ts.URL, nil)
  1913  	ch := make(chan struct{})
  1914  	req.Cancel = ch
  1915  
  1916  	res, err := c.Do(req)
  1917  	if err != nil {
  1918  		t.Fatal(err)
  1919  	}
  1920  	go func() {
  1921  		time.Sleep(1 * time.Second)
  1922  		close(ch)
  1923  	}()
  1924  	t0 := time.Now()
  1925  	body, err := ioutil.ReadAll(res.Body)
  1926  	d := time.Since(t0)
  1927  
  1928  	if err != ExportErrRequestCanceled {
  1929  		t.Errorf("Body.Read error = %v; want errRequestCanceled", err)
  1930  	}
  1931  	if string(body) != "Hello" {
  1932  		t.Errorf("Body = %q; want Hello", body)
  1933  	}
  1934  	if d < 500*time.Millisecond {
  1935  		t.Errorf("expected ~1 second delay; got %v", d)
  1936  	}
  1937  	// Verify no outstanding requests after readLoop/writeLoop
  1938  	// goroutines shut down.
  1939  	for tries := 5; tries > 0; tries-- {
  1940  		n := tr.NumPendingRequestsForTesting()
  1941  		if n == 0 {
  1942  			break
  1943  		}
  1944  		time.Sleep(100 * time.Millisecond)
  1945  		if tries == 1 {
  1946  			t.Errorf("pending requests = %d; want 0", n)
  1947  		}
  1948  	}
  1949  }
  1950  
  1951  func TestCancelRequestWithChannelBeforeDo_Cancel(t *testing.T) {
  1952  	testCancelRequestWithChannelBeforeDo(t, false)
  1953  }
  1954  func TestCancelRequestWithChannelBeforeDo_Context(t *testing.T) {
  1955  	testCancelRequestWithChannelBeforeDo(t, true)
  1956  }
  1957  func testCancelRequestWithChannelBeforeDo(t *testing.T, withCtx bool) {
  1958  	setParallel(t)
  1959  	defer afterTest(t)
  1960  	unblockc := make(chan bool)
  1961  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1962  		<-unblockc
  1963  	}))
  1964  	defer ts.Close()
  1965  	defer close(unblockc)
  1966  
  1967  	c := ts.Client()
  1968  
  1969  	req, _ := NewRequest("GET", ts.URL, nil)
  1970  	if withCtx {
  1971  		ctx, cancel := context.WithCancel(context.Background())
  1972  		cancel()
  1973  		req = req.WithContext(ctx)
  1974  	} else {
  1975  		ch := make(chan struct{})
  1976  		req.Cancel = ch
  1977  		close(ch)
  1978  	}
  1979  
  1980  	_, err := c.Do(req)
  1981  	if ue, ok := err.(*url.Error); ok {
  1982  		err = ue.Err
  1983  	}
  1984  	if withCtx {
  1985  		if err != context.Canceled {
  1986  			t.Errorf("Do error = %v; want %v", err, context.Canceled)
  1987  		}
  1988  	} else {
  1989  		if err == nil || !strings.Contains(err.Error(), "canceled") {
  1990  			t.Errorf("Do error = %v; want cancelation", err)
  1991  		}
  1992  	}
  1993  }
  1994  
  1995  // Issue 11020. The returned error message should be errRequestCanceled
  1996  func TestTransportCancelBeforeResponseHeaders(t *testing.T) {
  1997  	defer afterTest(t)
  1998  
  1999  	serverConnCh := make(chan net.Conn, 1)
  2000  	tr := &Transport{
  2001  		Dial: func(network, addr string) (net.Conn, error) {
  2002  			cc, sc := net.Pipe()
  2003  			serverConnCh <- sc
  2004  			return cc, nil
  2005  		},
  2006  	}
  2007  	defer tr.CloseIdleConnections()
  2008  	errc := make(chan error, 1)
  2009  	req, _ := NewRequest("GET", "http://example.com/", nil)
  2010  	go func() {
  2011  		_, err := tr.RoundTrip(req)
  2012  		errc <- err
  2013  	}()
  2014  
  2015  	sc := <-serverConnCh
  2016  	verb := make([]byte, 3)
  2017  	if _, err := io.ReadFull(sc, verb); err != nil {
  2018  		t.Errorf("Error reading HTTP verb from server: %v", err)
  2019  	}
  2020  	if string(verb) != "GET" {
  2021  		t.Errorf("server received %q; want GET", verb)
  2022  	}
  2023  	defer sc.Close()
  2024  
  2025  	tr.CancelRequest(req)
  2026  
  2027  	err := <-errc
  2028  	if err == nil {
  2029  		t.Fatalf("unexpected success from RoundTrip")
  2030  	}
  2031  	if err != ExportErrRequestCanceled {
  2032  		t.Errorf("RoundTrip error = %v; want ExportErrRequestCanceled", err)
  2033  	}
  2034  }
  2035  
  2036  // golang.org/issue/3672 -- Client can't close HTTP stream
  2037  // Calling Close on a Response.Body used to just read until EOF.
  2038  // Now it actually closes the TCP connection.
  2039  func TestTransportCloseResponseBody(t *testing.T) {
  2040  	defer afterTest(t)
  2041  	writeErr := make(chan error, 1)
  2042  	msg := []byte("young\n")
  2043  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2044  		for {
  2045  			_, err := w.Write(msg)
  2046  			if err != nil {
  2047  				writeErr <- err
  2048  				return
  2049  			}
  2050  			w.(Flusher).Flush()
  2051  		}
  2052  	}))
  2053  	defer ts.Close()
  2054  
  2055  	c := ts.Client()
  2056  	tr := c.Transport.(*Transport)
  2057  
  2058  	req, _ := NewRequest("GET", ts.URL, nil)
  2059  	defer tr.CancelRequest(req)
  2060  
  2061  	res, err := c.Do(req)
  2062  	if err != nil {
  2063  		t.Fatal(err)
  2064  	}
  2065  
  2066  	const repeats = 3
  2067  	buf := make([]byte, len(msg)*repeats)
  2068  	want := bytes.Repeat(msg, repeats)
  2069  
  2070  	_, err = io.ReadFull(res.Body, buf)
  2071  	if err != nil {
  2072  		t.Fatal(err)
  2073  	}
  2074  	if !bytes.Equal(buf, want) {
  2075  		t.Fatalf("read %q; want %q", buf, want)
  2076  	}
  2077  	didClose := make(chan error, 1)
  2078  	go func() {
  2079  		didClose <- res.Body.Close()
  2080  	}()
  2081  	select {
  2082  	case err := <-didClose:
  2083  		if err != nil {
  2084  			t.Errorf("Close = %v", err)
  2085  		}
  2086  	case <-time.After(10 * time.Second):
  2087  		t.Fatal("too long waiting for close")
  2088  	}
  2089  	select {
  2090  	case err := <-writeErr:
  2091  		if err == nil {
  2092  			t.Errorf("expected non-nil write error")
  2093  		}
  2094  	case <-time.After(10 * time.Second):
  2095  		t.Fatal("too long waiting for write error")
  2096  	}
  2097  }
  2098  
  2099  type fooProto struct{}
  2100  
  2101  func (fooProto) RoundTrip(req *Request) (*Response, error) {
  2102  	res := &Response{
  2103  		Status:     "200 OK",
  2104  		StatusCode: 200,
  2105  		Header:     make(Header),
  2106  		Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
  2107  	}
  2108  	return res, nil
  2109  }
  2110  
  2111  func TestTransportAltProto(t *testing.T) {
  2112  	defer afterTest(t)
  2113  	tr := &Transport{}
  2114  	c := &Client{Transport: tr}
  2115  	tr.RegisterProtocol("foo", fooProto{})
  2116  	res, err := c.Get("foo://bar.com/path")
  2117  	if err != nil {
  2118  		t.Fatal(err)
  2119  	}
  2120  	bodyb, err := ioutil.ReadAll(res.Body)
  2121  	if err != nil {
  2122  		t.Fatal(err)
  2123  	}
  2124  	body := string(bodyb)
  2125  	if e := "You wanted foo://bar.com/path"; body != e {
  2126  		t.Errorf("got response %q, want %q", body, e)
  2127  	}
  2128  }
  2129  
  2130  func TestTransportNoHost(t *testing.T) {
  2131  	defer afterTest(t)
  2132  	tr := &Transport{}
  2133  	_, err := tr.RoundTrip(&Request{
  2134  		Header: make(Header),
  2135  		URL: &url.URL{
  2136  			Scheme: "http",
  2137  		},
  2138  	})
  2139  	want := "http: no Host in request URL"
  2140  	if got := fmt.Sprint(err); got != want {
  2141  		t.Errorf("error = %v; want %q", err, want)
  2142  	}
  2143  }
  2144  
  2145  // Issue 13311
  2146  func TestTransportEmptyMethod(t *testing.T) {
  2147  	req, _ := NewRequest("GET", "http://foo.com/", nil)
  2148  	req.Method = ""                                 // docs say "For client requests an empty string means GET"
  2149  	got, err := httputil.DumpRequestOut(req, false) // DumpRequestOut uses Transport
  2150  	if err != nil {
  2151  		t.Fatal(err)
  2152  	}
  2153  	if !strings.Contains(string(got), "GET ") {
  2154  		t.Fatalf("expected substring 'GET '; got: %s", got)
  2155  	}
  2156  }
  2157  
  2158  func TestTransportSocketLateBinding(t *testing.T) {
  2159  	setParallel(t)
  2160  	defer afterTest(t)
  2161  
  2162  	mux := NewServeMux()
  2163  	fooGate := make(chan bool, 1)
  2164  	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
  2165  		w.Header().Set("foo-ipport", r.RemoteAddr)
  2166  		w.(Flusher).Flush()
  2167  		<-fooGate
  2168  	})
  2169  	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
  2170  		w.Header().Set("bar-ipport", r.RemoteAddr)
  2171  	})
  2172  	ts := httptest.NewServer(mux)
  2173  	defer ts.Close()
  2174  
  2175  	dialGate := make(chan bool, 1)
  2176  	c := ts.Client()
  2177  	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
  2178  		if <-dialGate {
  2179  			return net.Dial(n, addr)
  2180  		}
  2181  		return nil, errors.New("manually closed")
  2182  	}
  2183  
  2184  	dialGate <- true // only allow one dial
  2185  	fooRes, err := c.Get(ts.URL + "/foo")
  2186  	if err != nil {
  2187  		t.Fatal(err)
  2188  	}
  2189  	fooAddr := fooRes.Header.Get("foo-ipport")
  2190  	if fooAddr == "" {
  2191  		t.Fatal("No addr on /foo request")
  2192  	}
  2193  	time.AfterFunc(200*time.Millisecond, func() {
  2194  		// let the foo response finish so we can use its
  2195  		// connection for /bar
  2196  		fooGate <- true
  2197  		io.Copy(ioutil.Discard, fooRes.Body)
  2198  		fooRes.Body.Close()
  2199  	})
  2200  
  2201  	barRes, err := c.Get(ts.URL + "/bar")
  2202  	if err != nil {
  2203  		t.Fatal(err)
  2204  	}
  2205  	barAddr := barRes.Header.Get("bar-ipport")
  2206  	if barAddr != fooAddr {
  2207  		t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
  2208  	}
  2209  	barRes.Body.Close()
  2210  	dialGate <- false
  2211  }
  2212  
  2213  // Issue 2184
  2214  func TestTransportReading100Continue(t *testing.T) {
  2215  	defer afterTest(t)
  2216  
  2217  	const numReqs = 5
  2218  	reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
  2219  	reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
  2220  
  2221  	send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
  2222  		defer w.Close()
  2223  		defer r.Close()
  2224  		br := bufio.NewReader(r)
  2225  		n := 0
  2226  		for {
  2227  			n++
  2228  			req, err := ReadRequest(br)
  2229  			if err == io.EOF {
  2230  				return
  2231  			}
  2232  			if err != nil {
  2233  				t.Error(err)
  2234  				return
  2235  			}
  2236  			slurp, err := ioutil.ReadAll(req.Body)
  2237  			if err != nil {
  2238  				t.Errorf("Server request body slurp: %v", err)
  2239  				return
  2240  			}
  2241  			id := req.Header.Get("Request-Id")
  2242  			resCode := req.Header.Get("X-Want-Response-Code")
  2243  			if resCode == "" {
  2244  				resCode = "100 Continue"
  2245  				if string(slurp) != reqBody(n) {
  2246  					t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
  2247  				}
  2248  			}
  2249  			body := fmt.Sprintf("Response number %d", n)
  2250  			v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
  2251  Date: Thu, 28 Feb 2013 17:55:41 GMT
  2252  
  2253  HTTP/1.1 200 OK
  2254  Content-Type: text/html
  2255  Echo-Request-Id: %s
  2256  Content-Length: %d
  2257  
  2258  %s`, resCode, id, len(body), body), "\n", "\r\n", -1))
  2259  			w.Write(v)
  2260  			if id == reqID(numReqs) {
  2261  				return
  2262  			}
  2263  		}
  2264  
  2265  	}
  2266  
  2267  	tr := &Transport{
  2268  		Dial: func(n, addr string) (net.Conn, error) {
  2269  			sr, sw := io.Pipe() // server read/write
  2270  			cr, cw := io.Pipe() // client read/write
  2271  			conn := &rwTestConn{
  2272  				Reader: cr,
  2273  				Writer: sw,
  2274  				closeFunc: func() error {
  2275  					sw.Close()
  2276  					cw.Close()
  2277  					return nil
  2278  				},
  2279  			}
  2280  			go send100Response(cw, sr)
  2281  			return conn, nil
  2282  		},
  2283  		DisableKeepAlives: false,
  2284  	}
  2285  	defer tr.CloseIdleConnections()
  2286  	c := &Client{Transport: tr}
  2287  
  2288  	testResponse := func(req *Request, name string, wantCode int) {
  2289  		res, err := c.Do(req)
  2290  		if err != nil {
  2291  			t.Fatalf("%s: Do: %v", name, err)
  2292  		}
  2293  		if res.StatusCode != wantCode {
  2294  			t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
  2295  		}
  2296  		if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
  2297  			t.Errorf("%s: response id %q != request id %q", name, idBack, id)
  2298  		}
  2299  		_, err = ioutil.ReadAll(res.Body)
  2300  		if err != nil {
  2301  			t.Fatalf("%s: Slurp error: %v", name, err)
  2302  		}
  2303  	}
  2304  
  2305  	// Few 100 responses, making sure we're not off-by-one.
  2306  	for i := 1; i <= numReqs; i++ {
  2307  		req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
  2308  		req.Header.Set("Request-Id", reqID(i))
  2309  		testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
  2310  	}
  2311  
  2312  	// And some other informational 1xx but non-100 responses, to test
  2313  	// we return them but don't re-use the connection.
  2314  	for i := 1; i <= numReqs; i++ {
  2315  		req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i)))
  2316  		req.Header.Set("X-Want-Response-Code", "123 Sesame Street")
  2317  		testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123)
  2318  	}
  2319  }
  2320  
  2321  type proxyFromEnvTest struct {
  2322  	req string // URL to fetch; blank means "http://example.com"
  2323  
  2324  	env      string // HTTP_PROXY
  2325  	httpsenv string // HTTPS_PROXY
  2326  	noenv    string // NO_PROXY
  2327  	reqmeth  string // REQUEST_METHOD
  2328  
  2329  	want    string
  2330  	wanterr error
  2331  }
  2332  
  2333  func (t proxyFromEnvTest) String() string {
  2334  	var buf bytes.Buffer
  2335  	space := func() {
  2336  		if buf.Len() > 0 {
  2337  			buf.WriteByte(' ')
  2338  		}
  2339  	}
  2340  	if t.env != "" {
  2341  		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
  2342  	}
  2343  	if t.httpsenv != "" {
  2344  		space()
  2345  		fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv)
  2346  	}
  2347  	if t.noenv != "" {
  2348  		space()
  2349  		fmt.Fprintf(&buf, "no_proxy=%q", t.noenv)
  2350  	}
  2351  	if t.reqmeth != "" {
  2352  		space()
  2353  		fmt.Fprintf(&buf, "request_method=%q", t.reqmeth)
  2354  	}
  2355  	req := "http://example.com"
  2356  	if t.req != "" {
  2357  		req = t.req
  2358  	}
  2359  	space()
  2360  	fmt.Fprintf(&buf, "req=%q", req)
  2361  	return strings.TrimSpace(buf.String())
  2362  }
  2363  
  2364  var proxyFromEnvTests = []proxyFromEnvTest{
  2365  	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2366  	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
  2367  	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
  2368  	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
  2369  	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  2370  	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
  2371  	{env: "socks5://127.0.0.1", want: "socks5://127.0.0.1"},
  2372  
  2373  	// Don't use secure for http
  2374  	{req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"},
  2375  	// Use secure for https.
  2376  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"},
  2377  	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"},
  2378  
  2379  	// Issue 16405: don't use HTTP_PROXY in a CGI environment,
  2380  	// where HTTP_PROXY can be attacker-controlled.
  2381  	{env: "http://10.1.2.3:8080", reqmeth: "POST",
  2382  		want:    "<nil>",
  2383  		wanterr: errors.New("net/http: refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxy")},
  2384  
  2385  	{want: "<nil>"},
  2386  
  2387  	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  2388  	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  2389  	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2390  	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
  2391  	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  2392  }
  2393  
  2394  func TestProxyFromEnvironment(t *testing.T) {
  2395  	ResetProxyEnv()
  2396  	defer ResetProxyEnv()
  2397  	for _, tt := range proxyFromEnvTests {
  2398  		os.Setenv("HTTP_PROXY", tt.env)
  2399  		os.Setenv("HTTPS_PROXY", tt.httpsenv)
  2400  		os.Setenv("NO_PROXY", tt.noenv)
  2401  		os.Setenv("REQUEST_METHOD", tt.reqmeth)
  2402  		ResetCachedEnvironment()
  2403  		reqURL := tt.req
  2404  		if reqURL == "" {
  2405  			reqURL = "http://example.com"
  2406  		}
  2407  		req, _ := NewRequest("GET", reqURL, nil)
  2408  		url, err := ProxyFromEnvironment(req)
  2409  		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
  2410  			t.Errorf("%v: got error = %q, want %q", tt, g, e)
  2411  			continue
  2412  		}
  2413  		if got := fmt.Sprintf("%s", url); got != tt.want {
  2414  			t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
  2415  		}
  2416  	}
  2417  }
  2418  
  2419  func TestIdleConnChannelLeak(t *testing.T) {
  2420  	// Not parallel: uses global test hooks.
  2421  	var mu sync.Mutex
  2422  	var n int
  2423  
  2424  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2425  		mu.Lock()
  2426  		n++
  2427  		mu.Unlock()
  2428  	}))
  2429  	defer ts.Close()
  2430  
  2431  	const nReqs = 5
  2432  	didRead := make(chan bool, nReqs)
  2433  	SetReadLoopBeforeNextReadHook(func() { didRead <- true })
  2434  	defer SetReadLoopBeforeNextReadHook(nil)
  2435  
  2436  	c := ts.Client()
  2437  	tr := c.Transport.(*Transport)
  2438  	tr.Dial = func(netw, addr string) (net.Conn, error) {
  2439  		return net.Dial(netw, ts.Listener.Addr().String())
  2440  	}
  2441  
  2442  	// First, without keep-alives.
  2443  	for _, disableKeep := range []bool{true, false} {
  2444  		tr.DisableKeepAlives = disableKeep
  2445  		for i := 0; i < nReqs; i++ {
  2446  			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
  2447  			if err != nil {
  2448  				t.Fatal(err)
  2449  			}
  2450  			// Note: no res.Body.Close is needed here, since the
  2451  			// response Content-Length is zero. Perhaps the test
  2452  			// should be more explicit and use a HEAD, but tests
  2453  			// elsewhere guarantee that zero byte responses generate
  2454  			// a "Content-Length: 0" instead of chunking.
  2455  		}
  2456  
  2457  		// At this point, each of the 5 Transport.readLoop goroutines
  2458  		// are scheduling noting that there are no response bodies (see
  2459  		// earlier comment), and are then calling putIdleConn, which
  2460  		// decrements this count. Usually that happens quickly, which is
  2461  		// why this test has seemed to work for ages. But it's still
  2462  		// racey: we have wait for them to finish first. See Issue 10427
  2463  		for i := 0; i < nReqs; i++ {
  2464  			<-didRead
  2465  		}
  2466  
  2467  		if got := tr.IdleConnChMapSizeForTesting(); got != 0 {
  2468  			t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
  2469  		}
  2470  	}
  2471  }
  2472  
  2473  // Verify the status quo: that the Client.Post function coerces its
  2474  // body into a ReadCloser if it's a Closer, and that the Transport
  2475  // then closes it.
  2476  func TestTransportClosesRequestBody(t *testing.T) {
  2477  	defer afterTest(t)
  2478  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2479  		io.Copy(ioutil.Discard, r.Body)
  2480  	}))
  2481  	defer ts.Close()
  2482  
  2483  	c := ts.Client()
  2484  
  2485  	closes := 0
  2486  
  2487  	res, err := c.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
  2488  	if err != nil {
  2489  		t.Fatal(err)
  2490  	}
  2491  	res.Body.Close()
  2492  	if closes != 1 {
  2493  		t.Errorf("closes = %d; want 1", closes)
  2494  	}
  2495  }
  2496  
  2497  func TestTransportTLSHandshakeTimeout(t *testing.T) {
  2498  	defer afterTest(t)
  2499  	if testing.Short() {
  2500  		t.Skip("skipping in short mode")
  2501  	}
  2502  	ln := newLocalListener(t)
  2503  	defer ln.Close()
  2504  	testdonec := make(chan struct{})
  2505  	defer close(testdonec)
  2506  
  2507  	go func() {
  2508  		c, err := ln.Accept()
  2509  		if err != nil {
  2510  			t.Error(err)
  2511  			return
  2512  		}
  2513  		<-testdonec
  2514  		c.Close()
  2515  	}()
  2516  
  2517  	getdonec := make(chan struct{})
  2518  	go func() {
  2519  		defer close(getdonec)
  2520  		tr := &Transport{
  2521  			Dial: func(_, _ string) (net.Conn, error) {
  2522  				return net.Dial("tcp", ln.Addr().String())
  2523  			},
  2524  			TLSHandshakeTimeout: 250 * time.Millisecond,
  2525  		}
  2526  		cl := &Client{Transport: tr}
  2527  		_, err := cl.Get("https://dummy.tld/")
  2528  		if err == nil {
  2529  			t.Error("expected error")
  2530  			return
  2531  		}
  2532  		ue, ok := err.(*url.Error)
  2533  		if !ok {
  2534  			t.Errorf("expected url.Error; got %#v", err)
  2535  			return
  2536  		}
  2537  		ne, ok := ue.Err.(net.Error)
  2538  		if !ok {
  2539  			t.Errorf("expected net.Error; got %#v", err)
  2540  			return
  2541  		}
  2542  		if !ne.Timeout() {
  2543  			t.Errorf("expected timeout error; got %v", err)
  2544  		}
  2545  		if !strings.Contains(err.Error(), "handshake timeout") {
  2546  			t.Errorf("expected 'handshake timeout' in error; got %v", err)
  2547  		}
  2548  	}()
  2549  	select {
  2550  	case <-getdonec:
  2551  	case <-time.After(5 * time.Second):
  2552  		t.Error("test timeout; TLS handshake hung?")
  2553  	}
  2554  }
  2555  
  2556  // Trying to repro golang.org/issue/3514
  2557  func TestTLSServerClosesConnection(t *testing.T) {
  2558  	defer afterTest(t)
  2559  	testenv.SkipFlaky(t, 7634)
  2560  
  2561  	closedc := make(chan bool, 1)
  2562  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2563  		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
  2564  			conn, _, _ := w.(Hijacker).Hijack()
  2565  			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
  2566  			conn.Close()
  2567  			closedc <- true
  2568  			return
  2569  		}
  2570  		fmt.Fprintf(w, "hello")
  2571  	}))
  2572  	defer ts.Close()
  2573  
  2574  	c := ts.Client()
  2575  	tr := c.Transport.(*Transport)
  2576  
  2577  	var nSuccess = 0
  2578  	var errs []error
  2579  	const trials = 20
  2580  	for i := 0; i < trials; i++ {
  2581  		tr.CloseIdleConnections()
  2582  		res, err := c.Get(ts.URL + "/keep-alive-then-die")
  2583  		if err != nil {
  2584  			t.Fatal(err)
  2585  		}
  2586  		<-closedc
  2587  		slurp, err := ioutil.ReadAll(res.Body)
  2588  		if err != nil {
  2589  			t.Fatal(err)
  2590  		}
  2591  		if string(slurp) != "foo" {
  2592  			t.Errorf("Got %q, want foo", slurp)
  2593  		}
  2594  
  2595  		// Now try again and see if we successfully
  2596  		// pick a new connection.
  2597  		res, err = c.Get(ts.URL + "/")
  2598  		if err != nil {
  2599  			errs = append(errs, err)
  2600  			continue
  2601  		}
  2602  		slurp, err = ioutil.ReadAll(res.Body)
  2603  		if err != nil {
  2604  			errs = append(errs, err)
  2605  			continue
  2606  		}
  2607  		nSuccess++
  2608  	}
  2609  	if nSuccess > 0 {
  2610  		t.Logf("successes = %d of %d", nSuccess, trials)
  2611  	} else {
  2612  		t.Errorf("All runs failed:")
  2613  	}
  2614  	for _, err := range errs {
  2615  		t.Logf("  err: %v", err)
  2616  	}
  2617  }
  2618  
  2619  // byteFromChanReader is an io.Reader that reads a single byte at a
  2620  // time from the channel. When the channel is closed, the reader
  2621  // returns io.EOF.
  2622  type byteFromChanReader chan byte
  2623  
  2624  func (c byteFromChanReader) Read(p []byte) (n int, err error) {
  2625  	if len(p) == 0 {
  2626  		return
  2627  	}
  2628  	b, ok := <-c
  2629  	if !ok {
  2630  		return 0, io.EOF
  2631  	}
  2632  	p[0] = b
  2633  	return 1, nil
  2634  }
  2635  
  2636  // Verifies that the Transport doesn't reuse a connection in the case
  2637  // where the server replies before the request has been fully
  2638  // written. We still honor that reply (see TestIssue3595), but don't
  2639  // send future requests on the connection because it's then in a
  2640  // questionable state.
  2641  // golang.org/issue/7569
  2642  func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
  2643  	setParallel(t)
  2644  	defer afterTest(t)
  2645  	var sconn struct {
  2646  		sync.Mutex
  2647  		c net.Conn
  2648  	}
  2649  	var getOkay bool
  2650  	closeConn := func() {
  2651  		sconn.Lock()
  2652  		defer sconn.Unlock()
  2653  		if sconn.c != nil {
  2654  			sconn.c.Close()
  2655  			sconn.c = nil
  2656  			if !getOkay {
  2657  				t.Logf("Closed server connection")
  2658  			}
  2659  		}
  2660  	}
  2661  	defer closeConn()
  2662  
  2663  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2664  		if r.Method == "GET" {
  2665  			io.WriteString(w, "bar")
  2666  			return
  2667  		}
  2668  		conn, _, _ := w.(Hijacker).Hijack()
  2669  		sconn.Lock()
  2670  		sconn.c = conn
  2671  		sconn.Unlock()
  2672  		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
  2673  		go io.Copy(ioutil.Discard, conn)
  2674  	}))
  2675  	defer ts.Close()
  2676  	c := ts.Client()
  2677  
  2678  	const bodySize = 256 << 10
  2679  	finalBit := make(byteFromChanReader, 1)
  2680  	req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
  2681  	req.ContentLength = bodySize
  2682  	res, err := c.Do(req)
  2683  	if err := wantBody(res, err, "foo"); err != nil {
  2684  		t.Errorf("POST response: %v", err)
  2685  	}
  2686  	donec := make(chan bool)
  2687  	go func() {
  2688  		defer close(donec)
  2689  		res, err = c.Get(ts.URL)
  2690  		if err := wantBody(res, err, "bar"); err != nil {
  2691  			t.Errorf("GET response: %v", err)
  2692  			return
  2693  		}
  2694  		getOkay = true // suppress test noise
  2695  	}()
  2696  	time.AfterFunc(5*time.Second, closeConn)
  2697  	select {
  2698  	case <-donec:
  2699  		finalBit <- 'x' // unblock the writeloop of the first Post
  2700  		close(finalBit)
  2701  	case <-time.After(7 * time.Second):
  2702  		t.Fatal("timeout waiting for GET request to finish")
  2703  	}
  2704  }
  2705  
  2706  // Tests that we don't leak Transport persistConn.readLoop goroutines
  2707  // when a server hangs up immediately after saying it would keep-alive.
  2708  func TestTransportIssue10457(t *testing.T) {
  2709  	defer afterTest(t) // used to fail in goroutine leak check
  2710  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2711  		// Send a response with no body, keep-alive
  2712  		// (implicit), and then lie and immediately close the
  2713  		// connection. This forces the Transport's readLoop to
  2714  		// immediately Peek an io.EOF and get to the point
  2715  		// that used to hang.
  2716  		conn, _, _ := w.(Hijacker).Hijack()
  2717  		conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
  2718  		conn.Close()
  2719  	}))
  2720  	defer ts.Close()
  2721  	c := ts.Client()
  2722  
  2723  	res, err := c.Get(ts.URL)
  2724  	if err != nil {
  2725  		t.Fatalf("Get: %v", err)
  2726  	}
  2727  	defer res.Body.Close()
  2728  
  2729  	// Just a sanity check that we at least get the response. The real
  2730  	// test here is that the "defer afterTest" above doesn't find any
  2731  	// leaked goroutines.
  2732  	if got, want := res.Header.Get("Foo"), "Bar"; got != want {
  2733  		t.Errorf("Foo header = %q; want %q", got, want)
  2734  	}
  2735  }
  2736  
  2737  type errorReader struct {
  2738  	err error
  2739  }
  2740  
  2741  func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
  2742  
  2743  type closerFunc func() error
  2744  
  2745  func (f closerFunc) Close() error { return f() }
  2746  
  2747  type writerFuncConn struct {
  2748  	net.Conn
  2749  	write func(p []byte) (n int, err error)
  2750  }
  2751  
  2752  func (c writerFuncConn) Write(p []byte) (n int, err error) { return c.write(p) }
  2753  
  2754  // Issues 4677, 18241, and 17844. If we try to reuse a connection that the
  2755  // server is in the process of closing, we may end up successfully writing out
  2756  // our request (or a portion of our request) only to find a connection error
  2757  // when we try to read from (or finish writing to) the socket.
  2758  //
  2759  // NOTE: we resend a request only if:
  2760  //   - we reused a keep-alive connection
  2761  //   - we haven't yet received any header data
  2762  //   - either we wrote no bytes to the server, or the request is idempotent
  2763  // This automatically prevents an infinite resend loop because we'll run out of
  2764  // the cached keep-alive connections eventually.
  2765  func TestRetryRequestsOnError(t *testing.T) {
  2766  	newRequest := func(method, urlStr string, body io.Reader) *Request {
  2767  		req, err := NewRequest(method, urlStr, body)
  2768  		if err != nil {
  2769  			t.Fatal(err)
  2770  		}
  2771  		return req
  2772  	}
  2773  
  2774  	testCases := []struct {
  2775  		name       string
  2776  		failureN   int
  2777  		failureErr error
  2778  		// Note that we can't just re-use the Request object across calls to c.Do
  2779  		// because we need to rewind Body between calls.  (GetBody is only used to
  2780  		// rewind Body on failure and redirects, not just because it's done.)
  2781  		req       func() *Request
  2782  		reqString string
  2783  	}{
  2784  		{
  2785  			name: "IdempotentNoBodySomeWritten",
  2786  			// Believe that we've written some bytes to the server, so we know we're
  2787  			// not just in the "retry when no bytes sent" case".
  2788  			failureN: 1,
  2789  			// Use the specific error that shouldRetryRequest looks for with idempotent requests.
  2790  			failureErr: ExportErrServerClosedIdle,
  2791  			req: func() *Request {
  2792  				return newRequest("GET", "http://fake.golang", nil)
  2793  			},
  2794  			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`,
  2795  		},
  2796  		{
  2797  			name: "IdempotentGetBodySomeWritten",
  2798  			// Believe that we've written some bytes to the server, so we know we're
  2799  			// not just in the "retry when no bytes sent" case".
  2800  			failureN: 1,
  2801  			// Use the specific error that shouldRetryRequest looks for with idempotent requests.
  2802  			failureErr: ExportErrServerClosedIdle,
  2803  			req: func() *Request {
  2804  				return newRequest("GET", "http://fake.golang", strings.NewReader("foo\n"))
  2805  			},
  2806  			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`,
  2807  		},
  2808  		{
  2809  			name: "NothingWrittenNoBody",
  2810  			// It's key that we return 0 here -- that's what enables Transport to know
  2811  			// that nothing was written, even though this is a non-idempotent request.
  2812  			failureN:   0,
  2813  			failureErr: errors.New("second write fails"),
  2814  			req: func() *Request {
  2815  				return newRequest("DELETE", "http://fake.golang", nil)
  2816  			},
  2817  			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`,
  2818  		},
  2819  		{
  2820  			name: "NothingWrittenGetBody",
  2821  			// It's key that we return 0 here -- that's what enables Transport to know
  2822  			// that nothing was written, even though this is a non-idempotent request.
  2823  			failureN:   0,
  2824  			failureErr: errors.New("second write fails"),
  2825  			// Note that NewRequest will set up GetBody for strings.Reader, which is
  2826  			// required for the retry to occur
  2827  			req: func() *Request {
  2828  				return newRequest("POST", "http://fake.golang", strings.NewReader("foo\n"))
  2829  			},
  2830  			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`,
  2831  		},
  2832  	}
  2833  
  2834  	for _, tc := range testCases {
  2835  		t.Run(tc.name, func(t *testing.T) {
  2836  			defer afterTest(t)
  2837  
  2838  			var (
  2839  				mu     sync.Mutex
  2840  				logbuf bytes.Buffer
  2841  			)
  2842  			logf := func(format string, args ...interface{}) {
  2843  				mu.Lock()
  2844  				defer mu.Unlock()
  2845  				fmt.Fprintf(&logbuf, format, args...)
  2846  				logbuf.WriteByte('\n')
  2847  			}
  2848  
  2849  			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2850  				logf("Handler")
  2851  				w.Header().Set("X-Status", "ok")
  2852  			}))
  2853  			defer ts.Close()
  2854  
  2855  			var writeNumAtomic int32
  2856  			c := ts.Client()
  2857  			c.Transport.(*Transport).Dial = func(network, addr string) (net.Conn, error) {
  2858  				logf("Dial")
  2859  				c, err := net.Dial(network, ts.Listener.Addr().String())
  2860  				if err != nil {
  2861  					logf("Dial error: %v", err)
  2862  					return nil, err
  2863  				}
  2864  				return &writerFuncConn{
  2865  					Conn: c,
  2866  					write: func(p []byte) (n int, err error) {
  2867  						if atomic.AddInt32(&writeNumAtomic, 1) == 2 {
  2868  							logf("intentional write failure")
  2869  							return tc.failureN, tc.failureErr
  2870  						}
  2871  						logf("Write(%q)", p)
  2872  						return c.Write(p)
  2873  					},
  2874  				}, nil
  2875  			}
  2876  
  2877  			SetRoundTripRetried(func() {
  2878  				logf("Retried.")
  2879  			})
  2880  			defer SetRoundTripRetried(nil)
  2881  
  2882  			for i := 0; i < 3; i++ {
  2883  				res, err := c.Do(tc.req())
  2884  				if err != nil {
  2885  					t.Fatalf("i=%d: Do = %v", i, err)
  2886  				}
  2887  				res.Body.Close()
  2888  			}
  2889  
  2890  			mu.Lock()
  2891  			got := logbuf.String()
  2892  			mu.Unlock()
  2893  			want := fmt.Sprintf(`Dial
  2894  Write("%s")
  2895  Handler
  2896  intentional write failure
  2897  Retried.
  2898  Dial
  2899  Write("%s")
  2900  Handler
  2901  Write("%s")
  2902  Handler
  2903  `, tc.reqString, tc.reqString, tc.reqString)
  2904  			if got != want {
  2905  				t.Errorf("Log of events differs. Got:\n%s\nWant:\n%s", got, want)
  2906  			}
  2907  		})
  2908  	}
  2909  }
  2910  
  2911  // Issue 6981
  2912  func TestTransportClosesBodyOnError(t *testing.T) {
  2913  	setParallel(t)
  2914  	defer afterTest(t)
  2915  	readBody := make(chan error, 1)
  2916  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2917  		_, err := ioutil.ReadAll(r.Body)
  2918  		readBody <- err
  2919  	}))
  2920  	defer ts.Close()
  2921  	c := ts.Client()
  2922  	fakeErr := errors.New("fake error")
  2923  	didClose := make(chan bool, 1)
  2924  	req, _ := NewRequest("POST", ts.URL, struct {
  2925  		io.Reader
  2926  		io.Closer
  2927  	}{
  2928  		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}),
  2929  		closerFunc(func() error {
  2930  			select {
  2931  			case didClose <- true:
  2932  			default:
  2933  			}
  2934  			return nil
  2935  		}),
  2936  	})
  2937  	res, err := c.Do(req)
  2938  	if res != nil {
  2939  		defer res.Body.Close()
  2940  	}
  2941  	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
  2942  		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
  2943  	}
  2944  	select {
  2945  	case err := <-readBody:
  2946  		if err == nil {
  2947  			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
  2948  		}
  2949  	case <-time.After(5 * time.Second):
  2950  		t.Error("timeout waiting for server handler to complete")
  2951  	}
  2952  	select {
  2953  	case <-didClose:
  2954  	default:
  2955  		t.Errorf("didn't see Body.Close")
  2956  	}
  2957  }
  2958  
  2959  func TestTransportDialTLS(t *testing.T) {
  2960  	setParallel(t)
  2961  	defer afterTest(t)
  2962  	var mu sync.Mutex // guards following
  2963  	var gotReq, didDial bool
  2964  
  2965  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  2966  		mu.Lock()
  2967  		gotReq = true
  2968  		mu.Unlock()
  2969  	}))
  2970  	defer ts.Close()
  2971  	c := ts.Client()
  2972  	c.Transport.(*Transport).DialTLS = func(netw, addr string) (net.Conn, error) {
  2973  		mu.Lock()
  2974  		didDial = true
  2975  		mu.Unlock()
  2976  		c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig)
  2977  		if err != nil {
  2978  			return nil, err
  2979  		}
  2980  		return c, c.Handshake()
  2981  	}
  2982  
  2983  	res, err := c.Get(ts.URL)
  2984  	if err != nil {
  2985  		t.Fatal(err)
  2986  	}
  2987  	res.Body.Close()
  2988  	mu.Lock()
  2989  	if !gotReq {
  2990  		t.Error("didn't get request")
  2991  	}
  2992  	if !didDial {
  2993  		t.Error("didn't use dial hook")
  2994  	}
  2995  }
  2996  
  2997  // Test for issue 8755
  2998  // Ensure that if a proxy returns an error, it is exposed by RoundTrip
  2999  func TestRoundTripReturnsProxyError(t *testing.T) {
  3000  	badProxy := func(*Request) (*url.URL, error) {
  3001  		return nil, errors.New("errorMessage")
  3002  	}
  3003  
  3004  	tr := &Transport{Proxy: badProxy}
  3005  
  3006  	req, _ := NewRequest("GET", "http://example.com", nil)
  3007  
  3008  	_, err := tr.RoundTrip(req)
  3009  
  3010  	if err == nil {
  3011  		t.Error("Expected proxy error to be returned by RoundTrip")
  3012  	}
  3013  }
  3014  
  3015  // tests that putting an idle conn after a call to CloseIdleConns does return it
  3016  func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
  3017  	tr := &Transport{}
  3018  	wantIdle := func(when string, n int) bool {
  3019  		got := tr.IdleConnCountForTesting("|http|example.com") // key used by PutIdleTestConn
  3020  		if got == n {
  3021  			return true
  3022  		}
  3023  		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
  3024  		return false
  3025  	}
  3026  	wantIdle("start", 0)
  3027  	if !tr.PutIdleTestConn() {
  3028  		t.Fatal("put failed")
  3029  	}
  3030  	if !tr.PutIdleTestConn() {
  3031  		t.Fatal("second put failed")
  3032  	}
  3033  	wantIdle("after put", 2)
  3034  	tr.CloseIdleConnections()
  3035  	if !tr.IsIdleForTesting() {
  3036  		t.Error("should be idle after CloseIdleConnections")
  3037  	}
  3038  	wantIdle("after close idle", 0)
  3039  	if tr.PutIdleTestConn() {
  3040  		t.Fatal("put didn't fail")
  3041  	}
  3042  	wantIdle("after second put", 0)
  3043  
  3044  	tr.RequestIdleConnChForTesting() // should toggle the transport out of idle mode
  3045  	if tr.IsIdleForTesting() {
  3046  		t.Error("shouldn't be idle after RequestIdleConnChForTesting")
  3047  	}
  3048  	if !tr.PutIdleTestConn() {
  3049  		t.Fatal("after re-activation")
  3050  	}
  3051  	wantIdle("after final put", 1)
  3052  }
  3053  
  3054  // This tests that an client requesting a content range won't also
  3055  // implicitly ask for gzip support. If they want that, they need to do it
  3056  // on their own.
  3057  // golang.org/issue/8923
  3058  func TestTransportRangeAndGzip(t *testing.T) {
  3059  	defer afterTest(t)
  3060  	reqc := make(chan *Request, 1)
  3061  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3062  		reqc <- r
  3063  	}))
  3064  	defer ts.Close()
  3065  	c := ts.Client()
  3066  
  3067  	req, _ := NewRequest("GET", ts.URL, nil)
  3068  	req.Header.Set("Range", "bytes=7-11")
  3069  	res, err := c.Do(req)
  3070  	if err != nil {
  3071  		t.Fatal(err)
  3072  	}
  3073  
  3074  	select {
  3075  	case r := <-reqc:
  3076  		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
  3077  			t.Error("Transport advertised gzip support in the Accept header")
  3078  		}
  3079  		if r.Header.Get("Range") == "" {
  3080  			t.Error("no Range in request")
  3081  		}
  3082  	case <-time.After(10 * time.Second):
  3083  		t.Fatal("timeout")
  3084  	}
  3085  	res.Body.Close()
  3086  }
  3087  
  3088  // Test for issue 10474
  3089  func TestTransportResponseCancelRace(t *testing.T) {
  3090  	defer afterTest(t)
  3091  
  3092  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3093  		// important that this response has a body.
  3094  		var b [1024]byte
  3095  		w.Write(b[:])
  3096  	}))
  3097  	defer ts.Close()
  3098  	tr := ts.Client().Transport.(*Transport)
  3099  
  3100  	req, err := NewRequest("GET", ts.URL, nil)
  3101  	if err != nil {
  3102  		t.Fatal(err)
  3103  	}
  3104  	res, err := tr.RoundTrip(req)
  3105  	if err != nil {
  3106  		t.Fatal(err)
  3107  	}
  3108  	// If we do an early close, Transport just throws the connection away and
  3109  	// doesn't reuse it. In order to trigger the bug, it has to reuse the connection
  3110  	// so read the body
  3111  	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
  3112  		t.Fatal(err)
  3113  	}
  3114  
  3115  	req2, err := NewRequest("GET", ts.URL, nil)
  3116  	if err != nil {
  3117  		t.Fatal(err)
  3118  	}
  3119  	tr.CancelRequest(req)
  3120  	res, err = tr.RoundTrip(req2)
  3121  	if err != nil {
  3122  		t.Fatal(err)
  3123  	}
  3124  	res.Body.Close()
  3125  }
  3126  
  3127  // Test for issue 19248: Content-Encoding's value is case insensitive.
  3128  func TestTransportContentEncodingCaseInsensitive(t *testing.T) {
  3129  	setParallel(t)
  3130  	defer afterTest(t)
  3131  	for _, ce := range []string{"gzip", "GZIP"} {
  3132  		ce := ce
  3133  		t.Run(ce, func(t *testing.T) {
  3134  			const encodedString = "Hello Gopher"
  3135  			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3136  				w.Header().Set("Content-Encoding", ce)
  3137  				gz := gzip.NewWriter(w)
  3138  				gz.Write([]byte(encodedString))
  3139  				gz.Close()
  3140  			}))
  3141  			defer ts.Close()
  3142  
  3143  			res, err := ts.Client().Get(ts.URL)
  3144  			if err != nil {
  3145  				t.Fatal(err)
  3146  			}
  3147  
  3148  			body, err := ioutil.ReadAll(res.Body)
  3149  			res.Body.Close()
  3150  			if err != nil {
  3151  				t.Fatal(err)
  3152  			}
  3153  
  3154  			if string(body) != encodedString {
  3155  				t.Fatalf("Expected body %q, got: %q\n", encodedString, string(body))
  3156  			}
  3157  		})
  3158  	}
  3159  }
  3160  
  3161  func TestTransportDialCancelRace(t *testing.T) {
  3162  	defer afterTest(t)
  3163  
  3164  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  3165  	defer ts.Close()
  3166  	tr := ts.Client().Transport.(*Transport)
  3167  
  3168  	req, err := NewRequest("GET", ts.URL, nil)
  3169  	if err != nil {
  3170  		t.Fatal(err)
  3171  	}
  3172  	SetEnterRoundTripHook(func() {
  3173  		tr.CancelRequest(req)
  3174  	})
  3175  	defer SetEnterRoundTripHook(nil)
  3176  	res, err := tr.RoundTrip(req)
  3177  	if err != ExportErrRequestCanceled {
  3178  		t.Errorf("expected canceled request error; got %v", err)
  3179  		if err == nil {
  3180  			res.Body.Close()
  3181  		}
  3182  	}
  3183  }
  3184  
  3185  // logWritesConn is a net.Conn that logs each Write call to writes
  3186  // and then proxies to w.
  3187  // It proxies Read calls to a reader it receives from rch.
  3188  type logWritesConn struct {
  3189  	net.Conn // nil. crash on use.
  3190  
  3191  	w io.Writer
  3192  
  3193  	rch <-chan io.Reader
  3194  	r   io.Reader // nil until received by rch
  3195  
  3196  	mu     sync.Mutex
  3197  	writes []string
  3198  }
  3199  
  3200  func (c *logWritesConn) Write(p []byte) (n int, err error) {
  3201  	c.mu.Lock()
  3202  	defer c.mu.Unlock()
  3203  	c.writes = append(c.writes, string(p))
  3204  	return c.w.Write(p)
  3205  }
  3206  
  3207  func (c *logWritesConn) Read(p []byte) (n int, err error) {
  3208  	if c.r == nil {
  3209  		c.r = <-c.rch
  3210  	}
  3211  	return c.r.Read(p)
  3212  }
  3213  
  3214  func (c *logWritesConn) Close() error { return nil }
  3215  
  3216  // Issue 6574
  3217  func TestTransportFlushesBodyChunks(t *testing.T) {
  3218  	defer afterTest(t)
  3219  	resBody := make(chan io.Reader, 1)
  3220  	connr, connw := io.Pipe() // connection pipe pair
  3221  	lw := &logWritesConn{
  3222  		rch: resBody,
  3223  		w:   connw,
  3224  	}
  3225  	tr := &Transport{
  3226  		Dial: func(network, addr string) (net.Conn, error) {
  3227  			return lw, nil
  3228  		},
  3229  	}
  3230  	bodyr, bodyw := io.Pipe() // body pipe pair
  3231  	go func() {
  3232  		defer bodyw.Close()
  3233  		for i := 0; i < 3; i++ {
  3234  			fmt.Fprintf(bodyw, "num%d\n", i)
  3235  		}
  3236  	}()
  3237  	resc := make(chan *Response)
  3238  	go func() {
  3239  		req, _ := NewRequest("POST", "http://localhost:8080", bodyr)
  3240  		req.Header.Set("User-Agent", "x") // known value for test
  3241  		res, err := tr.RoundTrip(req)
  3242  		if err != nil {
  3243  			t.Errorf("RoundTrip: %v", err)
  3244  			close(resc)
  3245  			return
  3246  		}
  3247  		resc <- res
  3248  
  3249  	}()
  3250  	// Fully consume the request before checking the Write log vs. want.
  3251  	req, err := ReadRequest(bufio.NewReader(connr))
  3252  	if err != nil {
  3253  		t.Fatal(err)
  3254  	}
  3255  	io.Copy(ioutil.Discard, req.Body)
  3256  
  3257  	// Unblock the transport's roundTrip goroutine.
  3258  	resBody <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n")
  3259  	res, ok := <-resc
  3260  	if !ok {
  3261  		return
  3262  	}
  3263  	defer res.Body.Close()
  3264  
  3265  	want := []string{
  3266  		"POST / HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: x\r\nTransfer-Encoding: chunked\r\nAccept-Encoding: gzip\r\n\r\n" +
  3267  			"5\r\nnum0\n\r\n",
  3268  		"5\r\nnum1\n\r\n",
  3269  		"5\r\nnum2\n\r\n",
  3270  		"0\r\n\r\n",
  3271  	}
  3272  	if !reflect.DeepEqual(lw.writes, want) {
  3273  		t.Errorf("Writes differed.\n Got: %q\nWant: %q\n", lw.writes, want)
  3274  	}
  3275  }
  3276  
  3277  // Issue 11745.
  3278  func TestTransportPrefersResponseOverWriteError(t *testing.T) {
  3279  	if testing.Short() {
  3280  		t.Skip("skipping in short mode")
  3281  	}
  3282  	defer afterTest(t)
  3283  	const contentLengthLimit = 1024 * 1024 // 1MB
  3284  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3285  		if r.ContentLength >= contentLengthLimit {
  3286  			w.WriteHeader(StatusBadRequest)
  3287  			r.Body.Close()
  3288  			return
  3289  		}
  3290  		w.WriteHeader(StatusOK)
  3291  	}))
  3292  	defer ts.Close()
  3293  	c := ts.Client()
  3294  
  3295  	fail := 0
  3296  	count := 100
  3297  	bigBody := strings.Repeat("a", contentLengthLimit*2)
  3298  	for i := 0; i < count; i++ {
  3299  		req, err := NewRequest("PUT", ts.URL, strings.NewReader(bigBody))
  3300  		if err != nil {
  3301  			t.Fatal(err)
  3302  		}
  3303  		resp, err := c.Do(req)
  3304  		if err != nil {
  3305  			fail++
  3306  			t.Logf("%d = %#v", i, err)
  3307  			if ue, ok := err.(*url.Error); ok {
  3308  				t.Logf("urlErr = %#v", ue.Err)
  3309  				if ne, ok := ue.Err.(*net.OpError); ok {
  3310  					t.Logf("netOpError = %#v", ne.Err)
  3311  				}
  3312  			}
  3313  		} else {
  3314  			resp.Body.Close()
  3315  			if resp.StatusCode != 400 {
  3316  				t.Errorf("Expected status code 400, got %v", resp.Status)
  3317  			}
  3318  		}
  3319  	}
  3320  	if fail > 0 {
  3321  		t.Errorf("Failed %v out of %v\n", fail, count)
  3322  	}
  3323  }
  3324  
  3325  func TestTransportAutomaticHTTP2(t *testing.T) {
  3326  	testTransportAutoHTTP(t, &Transport{}, true)
  3327  }
  3328  
  3329  // golang.org/issue/14391: also check DefaultTransport
  3330  func TestTransportAutomaticHTTP2_DefaultTransport(t *testing.T) {
  3331  	testTransportAutoHTTP(t, DefaultTransport.(*Transport), true)
  3332  }
  3333  
  3334  func TestTransportAutomaticHTTP2_TLSNextProto(t *testing.T) {
  3335  	testTransportAutoHTTP(t, &Transport{
  3336  		TLSNextProto: make(map[string]func(string, *tls.Conn) RoundTripper),
  3337  	}, false)
  3338  }
  3339  
  3340  func TestTransportAutomaticHTTP2_TLSConfig(t *testing.T) {
  3341  	testTransportAutoHTTP(t, &Transport{
  3342  		TLSClientConfig: new(tls.Config),
  3343  	}, false)
  3344  }
  3345  
  3346  func TestTransportAutomaticHTTP2_ExpectContinueTimeout(t *testing.T) {
  3347  	testTransportAutoHTTP(t, &Transport{
  3348  		ExpectContinueTimeout: 1 * time.Second,
  3349  	}, true)
  3350  }
  3351  
  3352  func TestTransportAutomaticHTTP2_Dial(t *testing.T) {
  3353  	var d net.Dialer
  3354  	testTransportAutoHTTP(t, &Transport{
  3355  		Dial: d.Dial,
  3356  	}, false)
  3357  }
  3358  
  3359  func TestTransportAutomaticHTTP2_DialTLS(t *testing.T) {
  3360  	testTransportAutoHTTP(t, &Transport{
  3361  		DialTLS: func(network, addr string) (net.Conn, error) {
  3362  			panic("unused")
  3363  		},
  3364  	}, false)
  3365  }
  3366  
  3367  func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) {
  3368  	_, err := tr.RoundTrip(new(Request))
  3369  	if err == nil {
  3370  		t.Error("expected error from RoundTrip")
  3371  	}
  3372  	if reg := tr.TLSNextProto["h2"] != nil; reg != wantH2 {
  3373  		t.Errorf("HTTP/2 registered = %v; want %v", reg, wantH2)
  3374  	}
  3375  }
  3376  
  3377  // Issue 13633: there was a race where we returned bodyless responses
  3378  // to callers before recycling the persistent connection, which meant
  3379  // a client doing two subsequent requests could end up on different
  3380  // connections. It's somewhat harmless but enough tests assume it's
  3381  // not true in order to test other things that it's worth fixing.
  3382  // Plus it's nice to be consistent and not have timing-dependent
  3383  // behavior.
  3384  func TestTransportReuseConnEmptyResponseBody(t *testing.T) {
  3385  	defer afterTest(t)
  3386  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  3387  		w.Header().Set("X-Addr", r.RemoteAddr)
  3388  		// Empty response body.
  3389  	}))
  3390  	defer cst.close()
  3391  	n := 100
  3392  	if testing.Short() {
  3393  		n = 10
  3394  	}
  3395  	var firstAddr string
  3396  	for i := 0; i < n; i++ {
  3397  		res, err := cst.c.Get(cst.ts.URL)
  3398  		if err != nil {
  3399  			log.Fatal(err)
  3400  		}
  3401  		addr := res.Header.Get("X-Addr")
  3402  		if i == 0 {
  3403  			firstAddr = addr
  3404  		} else if addr != firstAddr {
  3405  			t.Fatalf("On request %d, addr %q != original addr %q", i+1, addr, firstAddr)
  3406  		}
  3407  		res.Body.Close()
  3408  	}
  3409  }
  3410  
  3411  // Issue 13839
  3412  func TestNoCrashReturningTransportAltConn(t *testing.T) {
  3413  	cert, err := tls.X509KeyPair(internal.LocalhostCert, internal.LocalhostKey)
  3414  	if err != nil {
  3415  		t.Fatal(err)
  3416  	}
  3417  	ln := newLocalListener(t)
  3418  	defer ln.Close()
  3419  
  3420  	handledPendingDial := make(chan bool, 1)
  3421  	SetPendingDialHooks(nil, func() { handledPendingDial <- true })
  3422  	defer SetPendingDialHooks(nil, nil)
  3423  
  3424  	testDone := make(chan struct{})
  3425  	defer close(testDone)
  3426  	go func() {
  3427  		tln := tls.NewListener(ln, &tls.Config{
  3428  			NextProtos:   []string{"foo"},
  3429  			Certificates: []tls.Certificate{cert},
  3430  		})
  3431  		sc, err := tln.Accept()
  3432  		if err != nil {
  3433  			t.Error(err)
  3434  			return
  3435  		}
  3436  		if err := sc.(*tls.Conn).Handshake(); err != nil {
  3437  			t.Error(err)
  3438  			return
  3439  		}
  3440  		<-testDone
  3441  		sc.Close()
  3442  	}()
  3443  
  3444  	addr := ln.Addr().String()
  3445  
  3446  	req, _ := NewRequest("GET", "https://fake.tld/", nil)
  3447  	cancel := make(chan struct{})
  3448  	req.Cancel = cancel
  3449  
  3450  	doReturned := make(chan bool, 1)
  3451  	madeRoundTripper := make(chan bool, 1)
  3452  
  3453  	tr := &Transport{
  3454  		DisableKeepAlives: true,
  3455  		TLSNextProto: map[string]func(string, *tls.Conn) RoundTripper{
  3456  			"foo": func(authority string, c *tls.Conn) RoundTripper {
  3457  				madeRoundTripper <- true
  3458  				return funcRoundTripper(func() {
  3459  					t.Error("foo RoundTripper should not be called")
  3460  				})
  3461  			},
  3462  		},
  3463  		Dial: func(_, _ string) (net.Conn, error) {
  3464  			panic("shouldn't be called")
  3465  		},
  3466  		DialTLS: func(_, _ string) (net.Conn, error) {
  3467  			tc, err := tls.Dial("tcp", addr, &tls.Config{
  3468  				InsecureSkipVerify: true,
  3469  				NextProtos:         []string{"foo"},
  3470  			})
  3471  			if err != nil {
  3472  				return nil, err
  3473  			}
  3474  			if err := tc.Handshake(); err != nil {
  3475  				return nil, err
  3476  			}
  3477  			close(cancel)
  3478  			<-doReturned
  3479  			return tc, nil
  3480  		},
  3481  	}
  3482  	c := &Client{Transport: tr}
  3483  
  3484  	_, err = c.Do(req)
  3485  	if ue, ok := err.(*url.Error); !ok || ue.Err != ExportErrRequestCanceledConn {
  3486  		t.Fatalf("Do error = %v; want url.Error with errRequestCanceledConn", err)
  3487  	}
  3488  
  3489  	doReturned <- true
  3490  	<-madeRoundTripper
  3491  	<-handledPendingDial
  3492  }
  3493  
  3494  func TestTransportReuseConnection_Gzip_Chunked(t *testing.T) {
  3495  	testTransportReuseConnection_Gzip(t, true)
  3496  }
  3497  
  3498  func TestTransportReuseConnection_Gzip_ContentLength(t *testing.T) {
  3499  	testTransportReuseConnection_Gzip(t, false)
  3500  }
  3501  
  3502  // Make sure we re-use underlying TCP connection for gzipped responses too.
  3503  func testTransportReuseConnection_Gzip(t *testing.T, chunked bool) {
  3504  	setParallel(t)
  3505  	defer afterTest(t)
  3506  	addr := make(chan string, 2)
  3507  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3508  		addr <- r.RemoteAddr
  3509  		w.Header().Set("Content-Encoding", "gzip")
  3510  		if chunked {
  3511  			w.(Flusher).Flush()
  3512  		}
  3513  		w.Write(rgz) // arbitrary gzip response
  3514  	}))
  3515  	defer ts.Close()
  3516  	c := ts.Client()
  3517  
  3518  	for i := 0; i < 2; i++ {
  3519  		res, err := c.Get(ts.URL)
  3520  		if err != nil {
  3521  			t.Fatal(err)
  3522  		}
  3523  		buf := make([]byte, len(rgz))
  3524  		if n, err := io.ReadFull(res.Body, buf); err != nil {
  3525  			t.Errorf("%d. ReadFull = %v, %v", i, n, err)
  3526  		}
  3527  		// Note: no res.Body.Close call. It should work without it,
  3528  		// since the flate.Reader's internal buffering will hit EOF
  3529  		// and that should be sufficient.
  3530  	}
  3531  	a1, a2 := <-addr, <-addr
  3532  	if a1 != a2 {
  3533  		t.Fatalf("didn't reuse connection")
  3534  	}
  3535  }
  3536  
  3537  func TestTransportResponseHeaderLength(t *testing.T) {
  3538  	setParallel(t)
  3539  	defer afterTest(t)
  3540  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3541  		if r.URL.Path == "/long" {
  3542  			w.Header().Set("Long", strings.Repeat("a", 1<<20))
  3543  		}
  3544  	}))
  3545  	defer ts.Close()
  3546  	c := ts.Client()
  3547  	c.Transport.(*Transport).MaxResponseHeaderBytes = 512 << 10
  3548  
  3549  	if res, err := c.Get(ts.URL); err != nil {
  3550  		t.Fatal(err)
  3551  	} else {
  3552  		res.Body.Close()
  3553  	}
  3554  
  3555  	res, err := c.Get(ts.URL + "/long")
  3556  	if err == nil {
  3557  		defer res.Body.Close()
  3558  		var n int64
  3559  		for k, vv := range res.Header {
  3560  			for _, v := range vv {
  3561  				n += int64(len(k)) + int64(len(v))
  3562  			}
  3563  		}
  3564  		t.Fatalf("Unexpected success. Got %v and %d bytes of response headers", res.Status, n)
  3565  	}
  3566  	if want := "server response headers exceeded 524288 bytes"; !strings.Contains(err.Error(), want) {
  3567  		t.Errorf("got error: %v; want %q", err, want)
  3568  	}
  3569  }
  3570  
  3571  func TestTransportEventTrace(t *testing.T)    { testTransportEventTrace(t, h1Mode, false) }
  3572  func TestTransportEventTrace_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, false) }
  3573  
  3574  // test a non-nil httptrace.ClientTrace but with all hooks set to zero.
  3575  func TestTransportEventTrace_NoHooks(t *testing.T)    { testTransportEventTrace(t, h1Mode, true) }
  3576  func TestTransportEventTrace_NoHooks_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, true) }
  3577  
  3578  func testTransportEventTrace(t *testing.T, h2 bool, noHooks bool) {
  3579  	defer afterTest(t)
  3580  	const resBody = "some body"
  3581  	gotWroteReqEvent := make(chan struct{})
  3582  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  3583  		if _, err := ioutil.ReadAll(r.Body); err != nil {
  3584  			t.Error(err)
  3585  		}
  3586  		if !noHooks {
  3587  			select {
  3588  			case <-gotWroteReqEvent:
  3589  			case <-time.After(5 * time.Second):
  3590  				t.Error("timeout waiting for WroteRequest event")
  3591  			}
  3592  		}
  3593  		io.WriteString(w, resBody)
  3594  	}))
  3595  	defer cst.close()
  3596  
  3597  	cst.tr.ExpectContinueTimeout = 1 * time.Second
  3598  
  3599  	var mu sync.Mutex // guards buf
  3600  	var buf bytes.Buffer
  3601  	logf := func(format string, args ...interface{}) {
  3602  		mu.Lock()
  3603  		defer mu.Unlock()
  3604  		fmt.Fprintf(&buf, format, args...)
  3605  		buf.WriteByte('\n')
  3606  	}
  3607  
  3608  	addrStr := cst.ts.Listener.Addr().String()
  3609  	ip, port, err := net.SplitHostPort(addrStr)
  3610  	if err != nil {
  3611  		t.Fatal(err)
  3612  	}
  3613  
  3614  	// Install a fake DNS server.
  3615  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) {
  3616  		if host != "dns-is-faked.golang" {
  3617  			t.Errorf("unexpected DNS host lookup for %q", host)
  3618  			return nil, nil
  3619  		}
  3620  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  3621  	})
  3622  
  3623  	req, _ := NewRequest("POST", cst.scheme()+"://dns-is-faked.golang:"+port, strings.NewReader("some body"))
  3624  	trace := &httptrace.ClientTrace{
  3625  		GetConn:              func(hostPort string) { logf("Getting conn for %v ...", hostPort) },
  3626  		GotConn:              func(ci httptrace.GotConnInfo) { logf("got conn: %+v", ci) },
  3627  		GotFirstResponseByte: func() { logf("first response byte") },
  3628  		PutIdleConn:          func(err error) { logf("PutIdleConn = %v", err) },
  3629  		DNSStart:             func(e httptrace.DNSStartInfo) { logf("DNS start: %+v", e) },
  3630  		DNSDone:              func(e httptrace.DNSDoneInfo) { logf("DNS done: %+v", e) },
  3631  		ConnectStart:         func(network, addr string) { logf("ConnectStart: Connecting to %s %s ...", network, addr) },
  3632  		ConnectDone: func(network, addr string, err error) {
  3633  			if err != nil {
  3634  				t.Errorf("ConnectDone: %v", err)
  3635  			}
  3636  			logf("ConnectDone: connected to %s %s = %v", network, addr, err)
  3637  		},
  3638  		Wait100Continue: func() { logf("Wait100Continue") },
  3639  		Got100Continue:  func() { logf("Got100Continue") },
  3640  		WroteRequest: func(e httptrace.WroteRequestInfo) {
  3641  			logf("WroteRequest: %+v", e)
  3642  			close(gotWroteReqEvent)
  3643  		},
  3644  	}
  3645  	if h2 {
  3646  		trace.TLSHandshakeStart = func() { logf("tls handshake start") }
  3647  		trace.TLSHandshakeDone = func(s tls.ConnectionState, err error) {
  3648  			logf("tls handshake done. ConnectionState = %v \n err = %v", s, err)
  3649  		}
  3650  	}
  3651  	if noHooks {
  3652  		// zero out all func pointers, trying to get some path to crash
  3653  		*trace = httptrace.ClientTrace{}
  3654  	}
  3655  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  3656  
  3657  	req.Header.Set("Expect", "100-continue")
  3658  	res, err := cst.c.Do(req)
  3659  	if err != nil {
  3660  		t.Fatal(err)
  3661  	}
  3662  	logf("got roundtrip.response")
  3663  	slurp, err := ioutil.ReadAll(res.Body)
  3664  	if err != nil {
  3665  		t.Fatal(err)
  3666  	}
  3667  	logf("consumed body")
  3668  	if string(slurp) != resBody || res.StatusCode != 200 {
  3669  		t.Fatalf("Got %q, %v; want %q, 200 OK", slurp, res.Status, resBody)
  3670  	}
  3671  	res.Body.Close()
  3672  
  3673  	if noHooks {
  3674  		// Done at this point. Just testing a full HTTP
  3675  		// requests can happen with a trace pointing to a zero
  3676  		// ClientTrace, full of nil func pointers.
  3677  		return
  3678  	}
  3679  
  3680  	mu.Lock()
  3681  	got := buf.String()
  3682  	mu.Unlock()
  3683  
  3684  	wantOnce := func(sub string) {
  3685  		if strings.Count(got, sub) != 1 {
  3686  			t.Errorf("expected substring %q exactly once in output.", sub)
  3687  		}
  3688  	}
  3689  	wantOnceOrMore := func(sub string) {
  3690  		if strings.Count(got, sub) == 0 {
  3691  			t.Errorf("expected substring %q at least once in output.", sub)
  3692  		}
  3693  	}
  3694  	wantOnce("Getting conn for dns-is-faked.golang:" + port)
  3695  	wantOnce("DNS start: {Host:dns-is-faked.golang}")
  3696  	wantOnce("DNS done: {Addrs:[{IP:" + ip + " Zone:}] Err:<nil> Coalesced:false}")
  3697  	wantOnce("got conn: {")
  3698  	wantOnceOrMore("Connecting to tcp " + addrStr)
  3699  	wantOnceOrMore("connected to tcp " + addrStr + " = <nil>")
  3700  	wantOnce("Reused:false WasIdle:false IdleTime:0s")
  3701  	wantOnce("first response byte")
  3702  	if h2 {
  3703  		wantOnce("tls handshake start")
  3704  		wantOnce("tls handshake done")
  3705  	} else {
  3706  		wantOnce("PutIdleConn = <nil>")
  3707  	}
  3708  	wantOnce("Wait100Continue")
  3709  	wantOnce("Got100Continue")
  3710  	wantOnce("WroteRequest: {Err:<nil>}")
  3711  	if strings.Contains(got, " to udp ") {
  3712  		t.Errorf("should not see UDP (DNS) connections")
  3713  	}
  3714  	if t.Failed() {
  3715  		t.Errorf("Output:\n%s", got)
  3716  	}
  3717  }
  3718  
  3719  var (
  3720  	isDNSHijackedOnce sync.Once
  3721  	isDNSHijacked     bool
  3722  )
  3723  
  3724  func skipIfDNSHijacked(t *testing.T) {
  3725  	// Skip this test if the user is using a shady/ISP
  3726  	// DNS server hijacking queries.
  3727  	// See issues 16732, 16716.
  3728  	isDNSHijackedOnce.Do(func() {
  3729  		addrs, _ := net.LookupHost("dns-should-not-resolve.golang")
  3730  		isDNSHijacked = len(addrs) != 0
  3731  	})
  3732  	if isDNSHijacked {
  3733  		t.Skip("skipping; test requires non-hijacking DNS server")
  3734  	}
  3735  }
  3736  
  3737  func TestTransportEventTraceRealDNS(t *testing.T) {
  3738  	skipIfDNSHijacked(t)
  3739  	defer afterTest(t)
  3740  	tr := &Transport{}
  3741  	defer tr.CloseIdleConnections()
  3742  	c := &Client{Transport: tr}
  3743  
  3744  	var mu sync.Mutex // guards buf
  3745  	var buf bytes.Buffer
  3746  	logf := func(format string, args ...interface{}) {
  3747  		mu.Lock()
  3748  		defer mu.Unlock()
  3749  		fmt.Fprintf(&buf, format, args...)
  3750  		buf.WriteByte('\n')
  3751  	}
  3752  
  3753  	req, _ := NewRequest("GET", "http://dns-should-not-resolve.golang:80", nil)
  3754  	trace := &httptrace.ClientTrace{
  3755  		DNSStart:     func(e httptrace.DNSStartInfo) { logf("DNSStart: %+v", e) },
  3756  		DNSDone:      func(e httptrace.DNSDoneInfo) { logf("DNSDone: %+v", e) },
  3757  		ConnectStart: func(network, addr string) { logf("ConnectStart: %s %s", network, addr) },
  3758  		ConnectDone:  func(network, addr string, err error) { logf("ConnectDone: %s %s %v", network, addr, err) },
  3759  	}
  3760  	req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
  3761  
  3762  	resp, err := c.Do(req)
  3763  	if err == nil {
  3764  		resp.Body.Close()
  3765  		t.Fatal("expected error during DNS lookup")
  3766  	}
  3767  
  3768  	mu.Lock()
  3769  	got := buf.String()
  3770  	mu.Unlock()
  3771  
  3772  	wantSub := func(sub string) {
  3773  		if !strings.Contains(got, sub) {
  3774  			t.Errorf("expected substring %q in output.", sub)
  3775  		}
  3776  	}
  3777  	wantSub("DNSStart: {Host:dns-should-not-resolve.golang}")
  3778  	wantSub("DNSDone: {Addrs:[] Err:")
  3779  	if strings.Contains(got, "ConnectStart") || strings.Contains(got, "ConnectDone") {
  3780  		t.Errorf("should not see Connect events")
  3781  	}
  3782  	if t.Failed() {
  3783  		t.Errorf("Output:\n%s", got)
  3784  	}
  3785  }
  3786  
  3787  // Issue 14353: port can only contain digits.
  3788  func TestTransportRejectsAlphaPort(t *testing.T) {
  3789  	res, err := Get("http://dummy.tld:123foo/bar")
  3790  	if err == nil {
  3791  		res.Body.Close()
  3792  		t.Fatal("unexpected success")
  3793  	}
  3794  	ue, ok := err.(*url.Error)
  3795  	if !ok {
  3796  		t.Fatalf("got %#v; want *url.Error", err)
  3797  	}
  3798  	got := ue.Err.Error()
  3799  	want := `invalid URL port "123foo"`
  3800  	if got != want {
  3801  		t.Errorf("got error %q; want %q", got, want)
  3802  	}
  3803  }
  3804  
  3805  // Test the httptrace.TLSHandshake{Start,Done} hooks with a https http1
  3806  // connections. The http2 test is done in TestTransportEventTrace_h2
  3807  func TestTLSHandshakeTrace(t *testing.T) {
  3808  	defer afterTest(t)
  3809  	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
  3810  	defer ts.Close()
  3811  
  3812  	var mu sync.Mutex
  3813  	var start, done bool
  3814  	trace := &httptrace.ClientTrace{
  3815  		TLSHandshakeStart: func() {
  3816  			mu.Lock()
  3817  			defer mu.Unlock()
  3818  			start = true
  3819  		},
  3820  		TLSHandshakeDone: func(s tls.ConnectionState, err error) {
  3821  			mu.Lock()
  3822  			defer mu.Unlock()
  3823  			done = true
  3824  			if err != nil {
  3825  				t.Fatal("Expected error to be nil but was:", err)
  3826  			}
  3827  		},
  3828  	}
  3829  
  3830  	c := ts.Client()
  3831  	req, err := NewRequest("GET", ts.URL, nil)
  3832  	if err != nil {
  3833  		t.Fatal("Unable to construct test request:", err)
  3834  	}
  3835  	req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
  3836  
  3837  	r, err := c.Do(req)
  3838  	if err != nil {
  3839  		t.Fatal("Unexpected error making request:", err)
  3840  	}
  3841  	r.Body.Close()
  3842  	mu.Lock()
  3843  	defer mu.Unlock()
  3844  	if !start {
  3845  		t.Fatal("Expected TLSHandshakeStart to be called, but wasn't")
  3846  	}
  3847  	if !done {
  3848  		t.Fatal("Expected TLSHandshakeDone to be called, but wasnt't")
  3849  	}
  3850  }
  3851  
  3852  func TestTransportMaxIdleConns(t *testing.T) {
  3853  	defer afterTest(t)
  3854  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  3855  		// No body for convenience.
  3856  	}))
  3857  	defer ts.Close()
  3858  	c := ts.Client()
  3859  	tr := c.Transport.(*Transport)
  3860  	tr.MaxIdleConns = 4
  3861  
  3862  	ip, port, err := net.SplitHostPort(ts.Listener.Addr().String())
  3863  	if err != nil {
  3864  		t.Fatal(err)
  3865  	}
  3866  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) {
  3867  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  3868  	})
  3869  
  3870  	hitHost := func(n int) {
  3871  		req, _ := NewRequest("GET", fmt.Sprintf("http://host-%d.dns-is-faked.golang:"+port, n), nil)
  3872  		req = req.WithContext(ctx)
  3873  		res, err := c.Do(req)
  3874  		if err != nil {
  3875  			t.Fatal(err)
  3876  		}
  3877  		res.Body.Close()
  3878  	}
  3879  	for i := 0; i < 4; i++ {
  3880  		hitHost(i)
  3881  	}
  3882  	want := []string{
  3883  		"|http|host-0.dns-is-faked.golang:" + port,
  3884  		"|http|host-1.dns-is-faked.golang:" + port,
  3885  		"|http|host-2.dns-is-faked.golang:" + port,
  3886  		"|http|host-3.dns-is-faked.golang:" + port,
  3887  	}
  3888  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  3889  		t.Fatalf("idle conn keys mismatch.\n got: %q\nwant: %q\n", got, want)
  3890  	}
  3891  
  3892  	// Now hitting the 5th host should kick out the first host:
  3893  	hitHost(4)
  3894  	want = []string{
  3895  		"|http|host-1.dns-is-faked.golang:" + port,
  3896  		"|http|host-2.dns-is-faked.golang:" + port,
  3897  		"|http|host-3.dns-is-faked.golang:" + port,
  3898  		"|http|host-4.dns-is-faked.golang:" + port,
  3899  	}
  3900  	if got := tr.IdleConnKeysForTesting(); !reflect.DeepEqual(got, want) {
  3901  		t.Fatalf("idle conn keys mismatch after 5th host.\n got: %q\nwant: %q\n", got, want)
  3902  	}
  3903  }
  3904  
  3905  func TestTransportIdleConnTimeout_h1(t *testing.T) { testTransportIdleConnTimeout(t, h1Mode) }
  3906  func TestTransportIdleConnTimeout_h2(t *testing.T) { testTransportIdleConnTimeout(t, h2Mode) }
  3907  func testTransportIdleConnTimeout(t *testing.T, h2 bool) {
  3908  	if testing.Short() {
  3909  		t.Skip("skipping in short mode")
  3910  	}
  3911  	defer afterTest(t)
  3912  
  3913  	const timeout = 1 * time.Second
  3914  
  3915  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  3916  		// No body for convenience.
  3917  	}))
  3918  	defer cst.close()
  3919  	tr := cst.tr
  3920  	tr.IdleConnTimeout = timeout
  3921  	defer tr.CloseIdleConnections()
  3922  	c := &Client{Transport: tr}
  3923  
  3924  	idleConns := func() []string {
  3925  		if h2 {
  3926  			return tr.IdleConnStrsForTesting_h2()
  3927  		} else {
  3928  			return tr.IdleConnStrsForTesting()
  3929  		}
  3930  	}
  3931  
  3932  	var conn string
  3933  	doReq := func(n int) {
  3934  		req, _ := NewRequest("GET", cst.ts.URL, nil)
  3935  		req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
  3936  			PutIdleConn: func(err error) {
  3937  				if err != nil {
  3938  					t.Errorf("failed to keep idle conn: %v", err)
  3939  				}
  3940  			},
  3941  		}))
  3942  		res, err := c.Do(req)
  3943  		if err != nil {
  3944  			t.Fatal(err)
  3945  		}
  3946  		res.Body.Close()
  3947  		conns := idleConns()
  3948  		if len(conns) != 1 {
  3949  			t.Fatalf("req %v: unexpected number of idle conns: %q", n, conns)
  3950  		}
  3951  		if conn == "" {
  3952  			conn = conns[0]
  3953  		}
  3954  		if conn != conns[0] {
  3955  			t.Fatalf("req %v: cached connection changed; expected the same one throughout the test", n)
  3956  		}
  3957  	}
  3958  	for i := 0; i < 3; i++ {
  3959  		doReq(i)
  3960  		time.Sleep(timeout / 2)
  3961  	}
  3962  	time.Sleep(timeout * 3 / 2)
  3963  	if got := idleConns(); len(got) != 0 {
  3964  		t.Errorf("idle conns = %q; want none", got)
  3965  	}
  3966  }
  3967  
  3968  // Issue 16208: Go 1.7 crashed after Transport.IdleConnTimeout if an
  3969  // HTTP/2 connection was established but but its caller no longer
  3970  // wanted it. (Assuming the connection cache was enabled, which it is
  3971  // by default)
  3972  //
  3973  // This test reproduced the crash by setting the IdleConnTimeout low
  3974  // (to make the test reasonable) and then making a request which is
  3975  // canceled by the DialTLS hook, which then also waits to return the
  3976  // real connection until after the RoundTrip saw the error.  Then we
  3977  // know the successful tls.Dial from DialTLS will need to go into the
  3978  // idle pool. Then we give it a of time to explode.
  3979  func TestIdleConnH2Crash(t *testing.T) {
  3980  	setParallel(t)
  3981  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  3982  		// nothing
  3983  	}))
  3984  	defer cst.close()
  3985  
  3986  	ctx, cancel := context.WithCancel(context.Background())
  3987  	defer cancel()
  3988  
  3989  	sawDoErr := make(chan bool, 1)
  3990  	testDone := make(chan struct{})
  3991  	defer close(testDone)
  3992  
  3993  	cst.tr.IdleConnTimeout = 5 * time.Millisecond
  3994  	cst.tr.DialTLS = func(network, addr string) (net.Conn, error) {
  3995  		c, err := tls.Dial(network, addr, &tls.Config{
  3996  			InsecureSkipVerify: true,
  3997  			NextProtos:         []string{"h2"},
  3998  		})
  3999  		if err != nil {
  4000  			t.Error(err)
  4001  			return nil, err
  4002  		}
  4003  		if cs := c.ConnectionState(); cs.NegotiatedProtocol != "h2" {
  4004  			t.Errorf("protocol = %q; want %q", cs.NegotiatedProtocol, "h2")
  4005  			c.Close()
  4006  			return nil, errors.New("bogus")
  4007  		}
  4008  
  4009  		cancel()
  4010  
  4011  		failTimer := time.NewTimer(5 * time.Second)
  4012  		defer failTimer.Stop()
  4013  		select {
  4014  		case <-sawDoErr:
  4015  		case <-testDone:
  4016  		case <-failTimer.C:
  4017  			t.Error("timeout in DialTLS, waiting too long for cst.c.Do to fail")
  4018  		}
  4019  		return c, nil
  4020  	}
  4021  
  4022  	req, _ := NewRequest("GET", cst.ts.URL, nil)
  4023  	req = req.WithContext(ctx)
  4024  	res, err := cst.c.Do(req)
  4025  	if err == nil {
  4026  		res.Body.Close()
  4027  		t.Fatal("unexpected success")
  4028  	}
  4029  	sawDoErr <- true
  4030  
  4031  	// Wait for the explosion.
  4032  	time.Sleep(cst.tr.IdleConnTimeout * 10)
  4033  }
  4034  
  4035  type funcConn struct {
  4036  	net.Conn
  4037  	read  func([]byte) (int, error)
  4038  	write func([]byte) (int, error)
  4039  }
  4040  
  4041  func (c funcConn) Read(p []byte) (int, error)  { return c.read(p) }
  4042  func (c funcConn) Write(p []byte) (int, error) { return c.write(p) }
  4043  func (c funcConn) Close() error                { return nil }
  4044  
  4045  // Issue 16465: Transport.RoundTrip should return the raw net.Conn.Read error from Peek
  4046  // back to the caller.
  4047  func TestTransportReturnsPeekError(t *testing.T) {
  4048  	errValue := errors.New("specific error value")
  4049  
  4050  	wrote := make(chan struct{})
  4051  	var wroteOnce sync.Once
  4052  
  4053  	tr := &Transport{
  4054  		Dial: func(network, addr string) (net.Conn, error) {
  4055  			c := funcConn{
  4056  				read: func([]byte) (int, error) {
  4057  					<-wrote
  4058  					return 0, errValue
  4059  				},
  4060  				write: func(p []byte) (int, error) {
  4061  					wroteOnce.Do(func() { close(wrote) })
  4062  					return len(p), nil
  4063  				},
  4064  			}
  4065  			return c, nil
  4066  		},
  4067  	}
  4068  	_, err := tr.RoundTrip(httptest.NewRequest("GET", "http://fake.tld/", nil))
  4069  	if err != errValue {
  4070  		t.Errorf("error = %#v; want %v", err, errValue)
  4071  	}
  4072  }
  4073  
  4074  // Issue 13835: international domain names should work
  4075  func TestTransportIDNA_h1(t *testing.T) { testTransportIDNA(t, h1Mode) }
  4076  func TestTransportIDNA_h2(t *testing.T) { testTransportIDNA(t, h2Mode) }
  4077  func testTransportIDNA(t *testing.T, h2 bool) {
  4078  	defer afterTest(t)
  4079  
  4080  	const uniDomain = "гофер.го"
  4081  	const punyDomain = "xn--c1ae0ajs.xn--c1aw"
  4082  
  4083  	var port string
  4084  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  4085  		want := punyDomain + ":" + port
  4086  		if r.Host != want {
  4087  			t.Errorf("Host header = %q; want %q", r.Host, want)
  4088  		}
  4089  		if h2 {
  4090  			if r.TLS == nil {
  4091  				t.Errorf("r.TLS == nil")
  4092  			} else if r.TLS.ServerName != punyDomain {
  4093  				t.Errorf("TLS.ServerName = %q; want %q", r.TLS.ServerName, punyDomain)
  4094  			}
  4095  		}
  4096  		w.Header().Set("Hit-Handler", "1")
  4097  	}))
  4098  	defer cst.close()
  4099  
  4100  	ip, port, err := net.SplitHostPort(cst.ts.Listener.Addr().String())
  4101  	if err != nil {
  4102  		t.Fatal(err)
  4103  	}
  4104  
  4105  	// Install a fake DNS server.
  4106  	ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) {
  4107  		if host != punyDomain {
  4108  			t.Errorf("got DNS host lookup for %q; want %q", host, punyDomain)
  4109  			return nil, nil
  4110  		}
  4111  		return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
  4112  	})
  4113  
  4114  	req, _ := NewRequest("GET", cst.scheme()+"://"+uniDomain+":"+port, nil)
  4115  	trace := &httptrace.ClientTrace{
  4116  		GetConn: func(hostPort string) {
  4117  			want := net.JoinHostPort(punyDomain, port)
  4118  			if hostPort != want {
  4119  				t.Errorf("getting conn for %q; want %q", hostPort, want)
  4120  			}
  4121  		},
  4122  		DNSStart: func(e httptrace.DNSStartInfo) {
  4123  			if e.Host != punyDomain {
  4124  				t.Errorf("DNSStart Host = %q; want %q", e.Host, punyDomain)
  4125  			}
  4126  		},
  4127  	}
  4128  	req = req.WithContext(httptrace.WithClientTrace(ctx, trace))
  4129  
  4130  	res, err := cst.tr.RoundTrip(req)
  4131  	if err != nil {
  4132  		t.Fatal(err)
  4133  	}
  4134  	defer res.Body.Close()
  4135  	if res.Header.Get("Hit-Handler") != "1" {
  4136  		out, err := httputil.DumpResponse(res, true)
  4137  		if err != nil {
  4138  			t.Fatal(err)
  4139  		}
  4140  		t.Errorf("Response body wasn't from Handler. Got:\n%s\n", out)
  4141  	}
  4142  }
  4143  
  4144  // Issue 13290: send User-Agent in proxy CONNECT
  4145  func TestTransportProxyConnectHeader(t *testing.T) {
  4146  	defer afterTest(t)
  4147  	reqc := make(chan *Request, 1)
  4148  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  4149  		if r.Method != "CONNECT" {
  4150  			t.Errorf("method = %q; want CONNECT", r.Method)
  4151  		}
  4152  		reqc <- r
  4153  		c, _, err := w.(Hijacker).Hijack()
  4154  		if err != nil {
  4155  			t.Errorf("Hijack: %v", err)
  4156  			return
  4157  		}
  4158  		c.Close()
  4159  	}))
  4160  	defer ts.Close()
  4161  
  4162  	c := ts.Client()
  4163  	c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) {
  4164  		return url.Parse(ts.URL)
  4165  	}
  4166  	c.Transport.(*Transport).ProxyConnectHeader = Header{
  4167  		"User-Agent": {"foo"},
  4168  		"Other":      {"bar"},
  4169  	}
  4170  
  4171  	res, err := c.Get("https://dummy.tld/") // https to force a CONNECT
  4172  	if err == nil {
  4173  		res.Body.Close()
  4174  		t.Errorf("unexpected success")
  4175  	}
  4176  	select {
  4177  	case <-time.After(3 * time.Second):
  4178  		t.Fatal("timeout")
  4179  	case r := <-reqc:
  4180  		if got, want := r.Header.Get("User-Agent"), "foo"; got != want {
  4181  			t.Errorf("CONNECT request User-Agent = %q; want %q", got, want)
  4182  		}
  4183  		if got, want := r.Header.Get("Other"), "bar"; got != want {
  4184  			t.Errorf("CONNECT request Other = %q; want %q", got, want)
  4185  		}
  4186  	}
  4187  }
  4188  
  4189  var errFakeRoundTrip = errors.New("fake roundtrip")
  4190  
  4191  type funcRoundTripper func()
  4192  
  4193  func (fn funcRoundTripper) RoundTrip(*Request) (*Response, error) {
  4194  	fn()
  4195  	return nil, errFakeRoundTrip
  4196  }
  4197  
  4198  func wantBody(res *Response, err error, want string) error {
  4199  	if err != nil {
  4200  		return err
  4201  	}
  4202  	slurp, err := ioutil.ReadAll(res.Body)
  4203  	if err != nil {
  4204  		return fmt.Errorf("error reading body: %v", err)
  4205  	}
  4206  	if string(slurp) != want {
  4207  		return fmt.Errorf("body = %q; want %q", slurp, want)
  4208  	}
  4209  	if err := res.Body.Close(); err != nil {
  4210  		return fmt.Errorf("body Close = %v", err)
  4211  	}
  4212  	return nil
  4213  }
  4214  
  4215  func newLocalListener(t *testing.T) net.Listener {
  4216  	ln, err := net.Listen("tcp", "127.0.0.1:0")
  4217  	if err != nil {
  4218  		ln, err = net.Listen("tcp6", "[::1]:0")
  4219  	}
  4220  	if err != nil {
  4221  		t.Fatal(err)
  4222  	}
  4223  	return ln
  4224  }
  4225  
  4226  type countCloseReader struct {
  4227  	n *int
  4228  	io.Reader
  4229  }
  4230  
  4231  func (cr countCloseReader) Close() error {
  4232  	(*cr.n)++
  4233  	return nil
  4234  }
  4235  
  4236  // rgz is a gzip quine that uncompresses to itself.
  4237  var rgz = []byte{
  4238  	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  4239  	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  4240  	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  4241  	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  4242  	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  4243  	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  4244  	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  4245  	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  4246  	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  4247  	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  4248  	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  4249  	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  4250  	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  4251  	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  4252  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  4253  	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  4254  	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  4255  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  4256  	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  4257  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  4258  	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  4259  	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  4260  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  4261  	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  4262  	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  4263  	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  4264  	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  4265  	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  4266  	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  4267  	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  4268  	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  4269  	0x00, 0x00,
  4270  }
  4271  
  4272  // Ensure that a missing status doesn't make the server panic
  4273  // See Issue https://golang.org/issues/21701
  4274  func TestMissingStatusNoPanic(t *testing.T) {
  4275  	t.Parallel()
  4276  
  4277  	const want = "unknown status code"
  4278  
  4279  	ln := newLocalListener(t)
  4280  	addr := ln.Addr().String()
  4281  	shutdown := make(chan bool, 1)
  4282  	done := make(chan bool)
  4283  	fullAddrURL := fmt.Sprintf("http://%s", addr)
  4284  	raw := "HTTP/1.1 400\r\n" +
  4285  		"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
  4286  		"Content-Type: text/html; charset=utf-8\r\n" +
  4287  		"Content-Length: 10\r\n" +
  4288  		"Last-Modified: Wed, 30 Aug 2017 19:02:02 GMT\r\n" +
  4289  		"Vary: Accept-Encoding\r\n\r\n" +
  4290  		"Aloha Olaa"
  4291  
  4292  	go func() {
  4293  		defer func() {
  4294  			ln.Close()
  4295  			close(done)
  4296  		}()
  4297  
  4298  		conn, _ := ln.Accept()
  4299  		if conn != nil {
  4300  			io.WriteString(conn, raw)
  4301  			ioutil.ReadAll(conn)
  4302  			conn.Close()
  4303  		}
  4304  	}()
  4305  
  4306  	proxyURL, err := url.Parse(fullAddrURL)
  4307  	if err != nil {
  4308  		t.Fatalf("proxyURL: %v", err)
  4309  	}
  4310  
  4311  	tr := &Transport{Proxy: ProxyURL(proxyURL)}
  4312  
  4313  	req, _ := NewRequest("GET", "https://golang.org/", nil)
  4314  	res, err, panicked := doFetchCheckPanic(tr, req)
  4315  	if panicked {
  4316  		t.Error("panicked, expecting an error")
  4317  	}
  4318  	if res != nil && res.Body != nil {
  4319  		io.Copy(ioutil.Discard, res.Body)
  4320  		res.Body.Close()
  4321  	}
  4322  
  4323  	if err == nil || !strings.Contains(err.Error(), want) {
  4324  		t.Errorf("got=%v want=%q", err, want)
  4325  	}
  4326  
  4327  	close(shutdown)
  4328  	<-done
  4329  }
  4330  
  4331  func doFetchCheckPanic(tr *Transport, req *Request) (res *Response, err error, panicked bool) {
  4332  	defer func() {
  4333  		if r := recover(); r != nil {
  4334  			panicked = true
  4335  		}
  4336  	}()
  4337  	res, err = tr.RoundTrip(req)
  4338  	return
  4339  }
  4340  
  4341  // Issue 22330: do not allow the response body to be read when the status code
  4342  // forbids a response body.
  4343  func TestNoBodyOnChunked304Response(t *testing.T) {
  4344  	defer afterTest(t)
  4345  	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
  4346  		conn, buf, _ := w.(Hijacker).Hijack()
  4347  		buf.Write([]byte("HTTP/1.1 304 NOT MODIFIED\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"))
  4348  		buf.Flush()
  4349  		conn.Close()
  4350  	}))
  4351  	defer cst.close()
  4352  
  4353  	// Our test server above is sending back bogus data after the
  4354  	// response (the "0\r\n\r\n" part), which causes the Transport
  4355  	// code to log spam. Disable keep-alives so we never even try
  4356  	// to reuse the connection.
  4357  	cst.tr.DisableKeepAlives = true
  4358  
  4359  	res, err := cst.c.Get(cst.ts.URL)
  4360  	if err != nil {
  4361  		t.Fatal(err)
  4362  	}
  4363  
  4364  	if res.Body != NoBody {
  4365  		t.Errorf("Unexpected body on 304 response")
  4366  	}
  4367  }
  4368  

View as plain text