github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/net/http/transport_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Tests for transport.go
     6  
     7  package http_test
     8  
     9  import (
    10  	"bufio"
    11  	"bytes"
    12  	"compress/gzip"
    13  	"crypto/rand"
    14  	"fmt"
    15  	"io"
    16  	"io/ioutil"
    17  	"net"
    18  	. "net/http"
    19  	"net/http/httptest"
    20  	"net/url"
    21  	"os"
    22  	"runtime"
    23  	"strconv"
    24  	"strings"
    25  	"sync"
    26  	"testing"
    27  	"time"
    28  )
    29  
    30  // TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
    31  //       and then verify that the final 2 responses get errors back.
    32  
    33  // hostPortHandler writes back the client's "host:port".
    34  var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
    35  	if r.FormValue("close") == "true" {
    36  		w.Header().Set("Connection", "close")
    37  	}
    38  	w.Write([]byte(r.RemoteAddr))
    39  })
    40  
    41  // testCloseConn is a net.Conn tracked by a testConnSet.
    42  type testCloseConn struct {
    43  	net.Conn
    44  	set *testConnSet
    45  }
    46  
    47  func (c *testCloseConn) Close() error {
    48  	c.set.remove(c)
    49  	return c.Conn.Close()
    50  }
    51  
    52  // testConnSet tracks a set of TCP connections and whether they've
    53  // been closed.
    54  type testConnSet struct {
    55  	t      *testing.T
    56  	closed map[net.Conn]bool
    57  	list   []net.Conn // in order created
    58  	mutex  sync.Mutex
    59  }
    60  
    61  func (tcs *testConnSet) insert(c net.Conn) {
    62  	tcs.mutex.Lock()
    63  	defer tcs.mutex.Unlock()
    64  	tcs.closed[c] = false
    65  	tcs.list = append(tcs.list, c)
    66  }
    67  
    68  func (tcs *testConnSet) remove(c net.Conn) {
    69  	tcs.mutex.Lock()
    70  	defer tcs.mutex.Unlock()
    71  	tcs.closed[c] = true
    72  }
    73  
    74  // some tests use this to manage raw tcp connections for later inspection
    75  func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) {
    76  	connSet := &testConnSet{
    77  		t:      t,
    78  		closed: make(map[net.Conn]bool),
    79  	}
    80  	dial := func(n, addr string) (net.Conn, error) {
    81  		c, err := net.Dial(n, addr)
    82  		if err != nil {
    83  			return nil, err
    84  		}
    85  		tc := &testCloseConn{c, connSet}
    86  		connSet.insert(tc)
    87  		return tc, nil
    88  	}
    89  	return connSet, dial
    90  }
    91  
    92  func (tcs *testConnSet) check(t *testing.T) {
    93  	tcs.mutex.Lock()
    94  	defer tcs.mutex.Unlock()
    95  
    96  	for i, c := range tcs.list {
    97  		if !tcs.closed[c] {
    98  			t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list))
    99  		}
   100  	}
   101  }
   102  
   103  // Two subsequent requests and verify their response is the same.
   104  // The response from the server is our own IP:port
   105  func TestTransportKeepAlives(t *testing.T) {
   106  	defer afterTest(t)
   107  	ts := httptest.NewServer(hostPortHandler)
   108  	defer ts.Close()
   109  
   110  	for _, disableKeepAlive := range []bool{false, true} {
   111  		tr := &Transport{DisableKeepAlives: disableKeepAlive}
   112  		defer tr.CloseIdleConnections()
   113  		c := &Client{Transport: tr}
   114  
   115  		fetch := func(n int) string {
   116  			res, err := c.Get(ts.URL)
   117  			if err != nil {
   118  				t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
   119  			}
   120  			body, err := ioutil.ReadAll(res.Body)
   121  			if err != nil {
   122  				t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
   123  			}
   124  			return string(body)
   125  		}
   126  
   127  		body1 := fetch(1)
   128  		body2 := fetch(2)
   129  
   130  		bodiesDiffer := body1 != body2
   131  		if bodiesDiffer != disableKeepAlive {
   132  			t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   133  				disableKeepAlive, bodiesDiffer, body1, body2)
   134  		}
   135  	}
   136  }
   137  
   138  func TestTransportConnectionCloseOnResponse(t *testing.T) {
   139  	defer afterTest(t)
   140  	ts := httptest.NewServer(hostPortHandler)
   141  	defer ts.Close()
   142  
   143  	connSet, testDial := makeTestDial(t)
   144  
   145  	for _, connectionClose := range []bool{false, true} {
   146  		tr := &Transport{
   147  			Dial: testDial,
   148  		}
   149  		c := &Client{Transport: tr}
   150  
   151  		fetch := func(n int) string {
   152  			req := new(Request)
   153  			var err error
   154  			req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
   155  			if err != nil {
   156  				t.Fatalf("URL parse error: %v", err)
   157  			}
   158  			req.Method = "GET"
   159  			req.Proto = "HTTP/1.1"
   160  			req.ProtoMajor = 1
   161  			req.ProtoMinor = 1
   162  
   163  			res, err := c.Do(req)
   164  			if err != nil {
   165  				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
   166  			}
   167  			defer res.Body.Close()
   168  			body, err := ioutil.ReadAll(res.Body)
   169  			if err != nil {
   170  				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
   171  			}
   172  			return string(body)
   173  		}
   174  
   175  		body1 := fetch(1)
   176  		body2 := fetch(2)
   177  		bodiesDiffer := body1 != body2
   178  		if bodiesDiffer != connectionClose {
   179  			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   180  				connectionClose, bodiesDiffer, body1, body2)
   181  		}
   182  
   183  		tr.CloseIdleConnections()
   184  	}
   185  
   186  	connSet.check(t)
   187  }
   188  
   189  func TestTransportConnectionCloseOnRequest(t *testing.T) {
   190  	defer afterTest(t)
   191  	ts := httptest.NewServer(hostPortHandler)
   192  	defer ts.Close()
   193  
   194  	connSet, testDial := makeTestDial(t)
   195  
   196  	for _, connectionClose := range []bool{false, true} {
   197  		tr := &Transport{
   198  			Dial: testDial,
   199  		}
   200  		c := &Client{Transport: tr}
   201  
   202  		fetch := func(n int) string {
   203  			req := new(Request)
   204  			var err error
   205  			req.URL, err = url.Parse(ts.URL)
   206  			if err != nil {
   207  				t.Fatalf("URL parse error: %v", err)
   208  			}
   209  			req.Method = "GET"
   210  			req.Proto = "HTTP/1.1"
   211  			req.ProtoMajor = 1
   212  			req.ProtoMinor = 1
   213  			req.Close = connectionClose
   214  
   215  			res, err := c.Do(req)
   216  			if err != nil {
   217  				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
   218  			}
   219  			body, err := ioutil.ReadAll(res.Body)
   220  			if err != nil {
   221  				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
   222  			}
   223  			return string(body)
   224  		}
   225  
   226  		body1 := fetch(1)
   227  		body2 := fetch(2)
   228  		bodiesDiffer := body1 != body2
   229  		if bodiesDiffer != connectionClose {
   230  			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
   231  				connectionClose, bodiesDiffer, body1, body2)
   232  		}
   233  
   234  		tr.CloseIdleConnections()
   235  	}
   236  
   237  	connSet.check(t)
   238  }
   239  
   240  func TestTransportIdleCacheKeys(t *testing.T) {
   241  	defer afterTest(t)
   242  	ts := httptest.NewServer(hostPortHandler)
   243  	defer ts.Close()
   244  
   245  	tr := &Transport{DisableKeepAlives: false}
   246  	c := &Client{Transport: tr}
   247  
   248  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   249  		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
   250  	}
   251  
   252  	resp, err := c.Get(ts.URL)
   253  	if err != nil {
   254  		t.Error(err)
   255  	}
   256  	ioutil.ReadAll(resp.Body)
   257  
   258  	keys := tr.IdleConnKeysForTesting()
   259  	if e, g := 1, len(keys); e != g {
   260  		t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
   261  	}
   262  
   263  	if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
   264  		t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
   265  	}
   266  
   267  	tr.CloseIdleConnections()
   268  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   269  		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
   270  	}
   271  }
   272  
   273  func TestTransportMaxPerHostIdleConns(t *testing.T) {
   274  	defer afterTest(t)
   275  	resch := make(chan string)
   276  	gotReq := make(chan bool)
   277  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   278  		gotReq <- true
   279  		msg := <-resch
   280  		_, err := w.Write([]byte(msg))
   281  		if err != nil {
   282  			t.Fatalf("Write: %v", err)
   283  		}
   284  	}))
   285  	defer ts.Close()
   286  	maxIdleConns := 2
   287  	tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns}
   288  	c := &Client{Transport: tr}
   289  
   290  	// Start 3 outstanding requests and wait for the server to get them.
   291  	// Their responses will hang until we write to resch, though.
   292  	donech := make(chan bool)
   293  	doReq := func() {
   294  		resp, err := c.Get(ts.URL)
   295  		if err != nil {
   296  			t.Error(err)
   297  		}
   298  		_, err = ioutil.ReadAll(resp.Body)
   299  		if err != nil {
   300  			t.Fatalf("ReadAll: %v", err)
   301  		}
   302  		donech <- true
   303  	}
   304  	go doReq()
   305  	<-gotReq
   306  	go doReq()
   307  	<-gotReq
   308  	go doReq()
   309  	<-gotReq
   310  
   311  	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
   312  		t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
   313  	}
   314  
   315  	resch <- "res1"
   316  	<-donech
   317  	keys := tr.IdleConnKeysForTesting()
   318  	if e, g := 1, len(keys); e != g {
   319  		t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
   320  	}
   321  	cacheKey := "|http|" + ts.Listener.Addr().String()
   322  	if keys[0] != cacheKey {
   323  		t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
   324  	}
   325  	if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
   326  		t.Errorf("after first response, expected %d idle conns; got %d", e, g)
   327  	}
   328  
   329  	resch <- "res2"
   330  	<-donech
   331  	if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g {
   332  		t.Errorf("after second response, expected %d idle conns; got %d", e, g)
   333  	}
   334  
   335  	resch <- "res3"
   336  	<-donech
   337  	if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g {
   338  		t.Errorf("after third response, still expected %d idle conns; got %d", e, g)
   339  	}
   340  }
   341  
   342  func TestTransportServerClosingUnexpectedly(t *testing.T) {
   343  	defer afterTest(t)
   344  	ts := httptest.NewServer(hostPortHandler)
   345  	defer ts.Close()
   346  
   347  	tr := &Transport{}
   348  	c := &Client{Transport: tr}
   349  
   350  	fetch := func(n, retries int) string {
   351  		condFatalf := func(format string, arg ...interface{}) {
   352  			if retries <= 0 {
   353  				t.Fatalf(format, arg...)
   354  			}
   355  			t.Logf("retrying shortly after expected error: "+format, arg...)
   356  			time.Sleep(time.Second / time.Duration(retries))
   357  		}
   358  		for retries >= 0 {
   359  			retries--
   360  			res, err := c.Get(ts.URL)
   361  			if err != nil {
   362  				condFatalf("error in req #%d, GET: %v", n, err)
   363  				continue
   364  			}
   365  			body, err := ioutil.ReadAll(res.Body)
   366  			if err != nil {
   367  				condFatalf("error in req #%d, ReadAll: %v", n, err)
   368  				continue
   369  			}
   370  			res.Body.Close()
   371  			return string(body)
   372  		}
   373  		panic("unreachable")
   374  	}
   375  
   376  	body1 := fetch(1, 0)
   377  	body2 := fetch(2, 0)
   378  
   379  	ts.CloseClientConnections() // surprise!
   380  
   381  	// This test has an expected race. Sleeping for 25 ms prevents
   382  	// it on most fast machines, causing the next fetch() call to
   383  	// succeed quickly.  But if we do get errors, fetch() will retry 5
   384  	// times with some delays between.
   385  	time.Sleep(25 * time.Millisecond)
   386  
   387  	body3 := fetch(3, 5)
   388  
   389  	if body1 != body2 {
   390  		t.Errorf("expected body1 and body2 to be equal")
   391  	}
   392  	if body2 == body3 {
   393  		t.Errorf("expected body2 and body3 to be different")
   394  	}
   395  }
   396  
   397  // Test for http://golang.org/issue/2616 (appropriate issue number)
   398  // This fails pretty reliably with GOMAXPROCS=100 or something high.
   399  func TestStressSurpriseServerCloses(t *testing.T) {
   400  	defer afterTest(t)
   401  	if testing.Short() {
   402  		t.Skip("skipping test in short mode")
   403  	}
   404  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   405  		w.Header().Set("Content-Length", "5")
   406  		w.Header().Set("Content-Type", "text/plain")
   407  		w.Write([]byte("Hello"))
   408  		w.(Flusher).Flush()
   409  		conn, buf, _ := w.(Hijacker).Hijack()
   410  		buf.Flush()
   411  		conn.Close()
   412  	}))
   413  	defer ts.Close()
   414  
   415  	tr := &Transport{DisableKeepAlives: false}
   416  	c := &Client{Transport: tr}
   417  
   418  	// Do a bunch of traffic from different goroutines. Send to activityc
   419  	// after each request completes, regardless of whether it failed.
   420  	const (
   421  		numClients    = 50
   422  		reqsPerClient = 250
   423  	)
   424  	activityc := make(chan bool)
   425  	for i := 0; i < numClients; i++ {
   426  		go func() {
   427  			for i := 0; i < reqsPerClient; i++ {
   428  				res, err := c.Get(ts.URL)
   429  				if err == nil {
   430  					// We expect errors since the server is
   431  					// hanging up on us after telling us to
   432  					// send more requests, so we don't
   433  					// actually care what the error is.
   434  					// But we want to close the body in cases
   435  					// where we won the race.
   436  					res.Body.Close()
   437  				}
   438  				activityc <- true
   439  			}
   440  		}()
   441  	}
   442  
   443  	// Make sure all the request come back, one way or another.
   444  	for i := 0; i < numClients*reqsPerClient; i++ {
   445  		select {
   446  		case <-activityc:
   447  		case <-time.After(5 * time.Second):
   448  			t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
   449  		}
   450  	}
   451  }
   452  
   453  // TestTransportHeadResponses verifies that we deal with Content-Lengths
   454  // with no bodies properly
   455  func TestTransportHeadResponses(t *testing.T) {
   456  	defer afterTest(t)
   457  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   458  		if r.Method != "HEAD" {
   459  			panic("expected HEAD; got " + r.Method)
   460  		}
   461  		w.Header().Set("Content-Length", "123")
   462  		w.WriteHeader(200)
   463  	}))
   464  	defer ts.Close()
   465  
   466  	tr := &Transport{DisableKeepAlives: false}
   467  	c := &Client{Transport: tr}
   468  	for i := 0; i < 2; i++ {
   469  		res, err := c.Head(ts.URL)
   470  		if err != nil {
   471  			t.Errorf("error on loop %d: %v", i, err)
   472  		}
   473  		if e, g := "123", res.Header.Get("Content-Length"); e != g {
   474  			t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
   475  		}
   476  		if e, g := int64(123), res.ContentLength; e != g {
   477  			t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
   478  		}
   479  	}
   480  }
   481  
   482  // TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
   483  // on responses to HEAD requests.
   484  func TestTransportHeadChunkedResponse(t *testing.T) {
   485  	defer afterTest(t)
   486  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   487  		if r.Method != "HEAD" {
   488  			panic("expected HEAD; got " + r.Method)
   489  		}
   490  		w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
   491  		w.Header().Set("x-client-ipport", r.RemoteAddr)
   492  		w.WriteHeader(200)
   493  	}))
   494  	defer ts.Close()
   495  
   496  	tr := &Transport{DisableKeepAlives: false}
   497  	c := &Client{Transport: tr}
   498  
   499  	res1, err := c.Head(ts.URL)
   500  	if err != nil {
   501  		t.Fatalf("request 1 error: %v", err)
   502  	}
   503  	res2, err := c.Head(ts.URL)
   504  	if err != nil {
   505  		t.Fatalf("request 2 error: %v", err)
   506  	}
   507  	if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
   508  		t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
   509  	}
   510  }
   511  
   512  var roundTripTests = []struct {
   513  	accept       string
   514  	expectAccept string
   515  	compressed   bool
   516  }{
   517  	// Requests with no accept-encoding header use transparent compression
   518  	{"", "gzip", false},
   519  	// Requests with other accept-encoding should pass through unmodified
   520  	{"foo", "foo", false},
   521  	// Requests with accept-encoding == gzip should be passed through
   522  	{"gzip", "gzip", true},
   523  }
   524  
   525  // Test that the modification made to the Request by the RoundTripper is cleaned up
   526  func TestRoundTripGzip(t *testing.T) {
   527  	defer afterTest(t)
   528  	const responseBody = "test response body"
   529  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   530  		accept := req.Header.Get("Accept-Encoding")
   531  		if expect := req.FormValue("expect_accept"); accept != expect {
   532  			t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
   533  				req.FormValue("testnum"), accept, expect)
   534  		}
   535  		if accept == "gzip" {
   536  			rw.Header().Set("Content-Encoding", "gzip")
   537  			gz := gzip.NewWriter(rw)
   538  			gz.Write([]byte(responseBody))
   539  			gz.Close()
   540  		} else {
   541  			rw.Header().Set("Content-Encoding", accept)
   542  			rw.Write([]byte(responseBody))
   543  		}
   544  	}))
   545  	defer ts.Close()
   546  
   547  	for i, test := range roundTripTests {
   548  		// Test basic request (no accept-encoding)
   549  		req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
   550  		if test.accept != "" {
   551  			req.Header.Set("Accept-Encoding", test.accept)
   552  		}
   553  		res, err := DefaultTransport.RoundTrip(req)
   554  		var body []byte
   555  		if test.compressed {
   556  			gzip, err := gzip.NewReader(res.Body)
   557  			if err != nil {
   558  				t.Errorf("%d. gzip NewReader: %v", i, err)
   559  				continue
   560  			}
   561  			body, err = ioutil.ReadAll(gzip)
   562  			res.Body.Close()
   563  		} else {
   564  			body, err = ioutil.ReadAll(res.Body)
   565  		}
   566  		if err != nil {
   567  			t.Errorf("%d. Error: %q", i, err)
   568  			continue
   569  		}
   570  		if g, e := string(body), responseBody; g != e {
   571  			t.Errorf("%d. body = %q; want %q", i, g, e)
   572  		}
   573  		if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
   574  			t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
   575  		}
   576  		if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
   577  			t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
   578  		}
   579  	}
   580  
   581  }
   582  
   583  func TestTransportGzip(t *testing.T) {
   584  	defer afterTest(t)
   585  	const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
   586  	const nRandBytes = 1024 * 1024
   587  	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
   588  		if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
   589  			t.Errorf("Accept-Encoding = %q, want %q", g, e)
   590  		}
   591  		rw.Header().Set("Content-Encoding", "gzip")
   592  		if req.Method == "HEAD" {
   593  			return
   594  		}
   595  
   596  		var w io.Writer = rw
   597  		var buf bytes.Buffer
   598  		if req.FormValue("chunked") == "0" {
   599  			w = &buf
   600  			defer io.Copy(rw, &buf)
   601  			defer func() {
   602  				rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
   603  			}()
   604  		}
   605  		gz := gzip.NewWriter(w)
   606  		gz.Write([]byte(testString))
   607  		if req.FormValue("body") == "large" {
   608  			io.CopyN(gz, rand.Reader, nRandBytes)
   609  		}
   610  		gz.Close()
   611  	}))
   612  	defer ts.Close()
   613  
   614  	for _, chunked := range []string{"1", "0"} {
   615  		c := &Client{Transport: &Transport{}}
   616  
   617  		// First fetch something large, but only read some of it.
   618  		res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
   619  		if err != nil {
   620  			t.Fatalf("large get: %v", err)
   621  		}
   622  		buf := make([]byte, len(testString))
   623  		n, err := io.ReadFull(res.Body, buf)
   624  		if err != nil {
   625  			t.Fatalf("partial read of large response: size=%d, %v", n, err)
   626  		}
   627  		if e, g := testString, string(buf); e != g {
   628  			t.Errorf("partial read got %q, expected %q", g, e)
   629  		}
   630  		res.Body.Close()
   631  		// Read on the body, even though it's closed
   632  		n, err = res.Body.Read(buf)
   633  		if n != 0 || err == nil {
   634  			t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
   635  		}
   636  
   637  		// Then something small.
   638  		res, err = c.Get(ts.URL + "/?chunked=" + chunked)
   639  		if err != nil {
   640  			t.Fatal(err)
   641  		}
   642  		body, err := ioutil.ReadAll(res.Body)
   643  		if err != nil {
   644  			t.Fatal(err)
   645  		}
   646  		if g, e := string(body), testString; g != e {
   647  			t.Fatalf("body = %q; want %q", g, e)
   648  		}
   649  		if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
   650  			t.Fatalf("Content-Encoding = %q; want %q", g, e)
   651  		}
   652  
   653  		// Read on the body after it's been fully read:
   654  		n, err = res.Body.Read(buf)
   655  		if n != 0 || err == nil {
   656  			t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
   657  		}
   658  		res.Body.Close()
   659  		n, err = res.Body.Read(buf)
   660  		if n != 0 || err == nil {
   661  			t.Errorf("expected Read error after Close; got %d, %v", n, err)
   662  		}
   663  	}
   664  
   665  	// And a HEAD request too, because they're always weird.
   666  	c := &Client{Transport: &Transport{}}
   667  	res, err := c.Head(ts.URL)
   668  	if err != nil {
   669  		t.Fatalf("Head: %v", err)
   670  	}
   671  	if res.StatusCode != 200 {
   672  		t.Errorf("Head status=%d; want=200", res.StatusCode)
   673  	}
   674  }
   675  
   676  func TestTransportProxy(t *testing.T) {
   677  	defer afterTest(t)
   678  	ch := make(chan string, 1)
   679  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   680  		ch <- "real server"
   681  	}))
   682  	defer ts.Close()
   683  	proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   684  		ch <- "proxy for " + r.URL.String()
   685  	}))
   686  	defer proxy.Close()
   687  
   688  	pu, err := url.Parse(proxy.URL)
   689  	if err != nil {
   690  		t.Fatal(err)
   691  	}
   692  	c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
   693  	c.Head(ts.URL)
   694  	got := <-ch
   695  	want := "proxy for " + ts.URL + "/"
   696  	if got != want {
   697  		t.Errorf("want %q, got %q", want, got)
   698  	}
   699  }
   700  
   701  // TestTransportGzipRecursive sends a gzip quine and checks that the
   702  // client gets the same value back. This is more cute than anything,
   703  // but checks that we don't recurse forever, and checks that
   704  // Content-Encoding is removed.
   705  func TestTransportGzipRecursive(t *testing.T) {
   706  	defer afterTest(t)
   707  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   708  		w.Header().Set("Content-Encoding", "gzip")
   709  		w.Write(rgz)
   710  	}))
   711  	defer ts.Close()
   712  
   713  	c := &Client{Transport: &Transport{}}
   714  	res, err := c.Get(ts.URL)
   715  	if err != nil {
   716  		t.Fatal(err)
   717  	}
   718  	body, err := ioutil.ReadAll(res.Body)
   719  	if err != nil {
   720  		t.Fatal(err)
   721  	}
   722  	if !bytes.Equal(body, rgz) {
   723  		t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
   724  			body, rgz)
   725  	}
   726  	if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
   727  		t.Fatalf("Content-Encoding = %q; want %q", g, e)
   728  	}
   729  }
   730  
   731  // tests that persistent goroutine connections shut down when no longer desired.
   732  func TestTransportPersistConnLeak(t *testing.T) {
   733  	defer afterTest(t)
   734  	gotReqCh := make(chan bool)
   735  	unblockCh := make(chan bool)
   736  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   737  		gotReqCh <- true
   738  		<-unblockCh
   739  		w.Header().Set("Content-Length", "0")
   740  		w.WriteHeader(204)
   741  	}))
   742  	defer ts.Close()
   743  
   744  	tr := &Transport{}
   745  	c := &Client{Transport: tr}
   746  
   747  	n0 := runtime.NumGoroutine()
   748  
   749  	const numReq = 25
   750  	didReqCh := make(chan bool)
   751  	for i := 0; i < numReq; i++ {
   752  		go func() {
   753  			res, err := c.Get(ts.URL)
   754  			didReqCh <- true
   755  			if err != nil {
   756  				t.Errorf("client fetch error: %v", err)
   757  				return
   758  			}
   759  			res.Body.Close()
   760  		}()
   761  	}
   762  
   763  	// Wait for all goroutines to be stuck in the Handler.
   764  	for i := 0; i < numReq; i++ {
   765  		<-gotReqCh
   766  	}
   767  
   768  	nhigh := runtime.NumGoroutine()
   769  
   770  	// Tell all handlers to unblock and reply.
   771  	for i := 0; i < numReq; i++ {
   772  		unblockCh <- true
   773  	}
   774  
   775  	// Wait for all HTTP clients to be done.
   776  	for i := 0; i < numReq; i++ {
   777  		<-didReqCh
   778  	}
   779  
   780  	tr.CloseIdleConnections()
   781  	time.Sleep(100 * time.Millisecond)
   782  	runtime.GC()
   783  	runtime.GC() // even more.
   784  	nfinal := runtime.NumGoroutine()
   785  
   786  	growth := nfinal - n0
   787  
   788  	// We expect 0 or 1 extra goroutine, empirically.  Allow up to 5.
   789  	// Previously we were leaking one per numReq.
   790  	t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
   791  	if int(growth) > 5 {
   792  		t.Error("too many new goroutines")
   793  	}
   794  }
   795  
   796  // golang.org/issue/4531: Transport leaks goroutines when
   797  // request.ContentLength is explicitly short
   798  func TestTransportPersistConnLeakShortBody(t *testing.T) {
   799  	defer afterTest(t)
   800  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   801  	}))
   802  	defer ts.Close()
   803  
   804  	tr := &Transport{}
   805  	c := &Client{Transport: tr}
   806  
   807  	n0 := runtime.NumGoroutine()
   808  	body := []byte("Hello")
   809  	for i := 0; i < 20; i++ {
   810  		req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
   811  		if err != nil {
   812  			t.Fatal(err)
   813  		}
   814  		req.ContentLength = int64(len(body) - 2) // explicitly short
   815  		_, err = c.Do(req)
   816  		if err == nil {
   817  			t.Fatal("Expect an error from writing too long of a body.")
   818  		}
   819  	}
   820  	nhigh := runtime.NumGoroutine()
   821  	tr.CloseIdleConnections()
   822  	time.Sleep(50 * time.Millisecond)
   823  	runtime.GC()
   824  	nfinal := runtime.NumGoroutine()
   825  
   826  	growth := nfinal - n0
   827  
   828  	// We expect 0 or 1 extra goroutine, empirically.  Allow up to 5.
   829  	// Previously we were leaking one per numReq.
   830  	t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
   831  	if int(growth) > 5 {
   832  		t.Error("too many new goroutines")
   833  	}
   834  }
   835  
   836  // This used to crash; http://golang.org/issue/3266
   837  func TestTransportIdleConnCrash(t *testing.T) {
   838  	defer afterTest(t)
   839  	tr := &Transport{}
   840  	c := &Client{Transport: tr}
   841  
   842  	unblockCh := make(chan bool, 1)
   843  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   844  		<-unblockCh
   845  		tr.CloseIdleConnections()
   846  	}))
   847  	defer ts.Close()
   848  
   849  	didreq := make(chan bool)
   850  	go func() {
   851  		res, err := c.Get(ts.URL)
   852  		if err != nil {
   853  			t.Error(err)
   854  		} else {
   855  			res.Body.Close() // returns idle conn
   856  		}
   857  		didreq <- true
   858  	}()
   859  	unblockCh <- true
   860  	<-didreq
   861  }
   862  
   863  // Test that the transport doesn't close the TCP connection early,
   864  // before the response body has been read.  This was a regression
   865  // which sadly lacked a triggering test.  The large response body made
   866  // the old race easier to trigger.
   867  func TestIssue3644(t *testing.T) {
   868  	defer afterTest(t)
   869  	const numFoos = 5000
   870  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   871  		w.Header().Set("Connection", "close")
   872  		for i := 0; i < numFoos; i++ {
   873  			w.Write([]byte("foo "))
   874  		}
   875  	}))
   876  	defer ts.Close()
   877  	tr := &Transport{}
   878  	c := &Client{Transport: tr}
   879  	res, err := c.Get(ts.URL)
   880  	if err != nil {
   881  		t.Fatal(err)
   882  	}
   883  	defer res.Body.Close()
   884  	bs, err := ioutil.ReadAll(res.Body)
   885  	if err != nil {
   886  		t.Fatal(err)
   887  	}
   888  	if len(bs) != numFoos*len("foo ") {
   889  		t.Errorf("unexpected response length")
   890  	}
   891  }
   892  
   893  // Test that a client receives a server's reply, even if the server doesn't read
   894  // the entire request body.
   895  func TestIssue3595(t *testing.T) {
   896  	defer afterTest(t)
   897  	const deniedMsg = "sorry, denied."
   898  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   899  		Error(w, deniedMsg, StatusUnauthorized)
   900  	}))
   901  	defer ts.Close()
   902  	tr := &Transport{}
   903  	c := &Client{Transport: tr}
   904  	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
   905  	if err != nil {
   906  		t.Errorf("Post: %v", err)
   907  		return
   908  	}
   909  	got, err := ioutil.ReadAll(res.Body)
   910  	if err != nil {
   911  		t.Fatalf("Body ReadAll: %v", err)
   912  	}
   913  	if !strings.Contains(string(got), deniedMsg) {
   914  		t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
   915  	}
   916  }
   917  
   918  // From http://golang.org/issue/4454 ,
   919  // "client fails to handle requests with no body and chunked encoding"
   920  func TestChunkedNoContent(t *testing.T) {
   921  	defer afterTest(t)
   922  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   923  		w.WriteHeader(StatusNoContent)
   924  	}))
   925  	defer ts.Close()
   926  
   927  	for _, closeBody := range []bool{true, false} {
   928  		c := &Client{Transport: &Transport{}}
   929  		const n = 4
   930  		for i := 1; i <= n; i++ {
   931  			res, err := c.Get(ts.URL)
   932  			if err != nil {
   933  				t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
   934  			} else {
   935  				if closeBody {
   936  					res.Body.Close()
   937  				}
   938  			}
   939  		}
   940  	}
   941  }
   942  
   943  func TestTransportConcurrency(t *testing.T) {
   944  	defer afterTest(t)
   945  	maxProcs, numReqs := 16, 500
   946  	if testing.Short() {
   947  		maxProcs, numReqs = 4, 50
   948  	}
   949  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
   950  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
   951  		fmt.Fprintf(w, "%v", r.FormValue("echo"))
   952  	}))
   953  	defer ts.Close()
   954  
   955  	var wg sync.WaitGroup
   956  	wg.Add(numReqs)
   957  
   958  	tr := &Transport{
   959  		Dial: func(netw, addr string) (c net.Conn, err error) {
   960  			// Due to the Transport's "socket late
   961  			// binding" (see idleConnCh in transport.go),
   962  			// the numReqs HTTP requests below can finish
   963  			// with a dial still outstanding.  So count
   964  			// our dials as work too so the leak checker
   965  			// doesn't complain at us.
   966  			wg.Add(1)
   967  			defer wg.Done()
   968  			return net.Dial(netw, addr)
   969  		},
   970  	}
   971  	defer tr.CloseIdleConnections()
   972  	c := &Client{Transport: tr}
   973  	reqs := make(chan string)
   974  	defer close(reqs)
   975  
   976  	for i := 0; i < maxProcs*2; i++ {
   977  		go func() {
   978  			for req := range reqs {
   979  				res, err := c.Get(ts.URL + "/?echo=" + req)
   980  				if err != nil {
   981  					t.Errorf("error on req %s: %v", req, err)
   982  					wg.Done()
   983  					continue
   984  				}
   985  				all, err := ioutil.ReadAll(res.Body)
   986  				if err != nil {
   987  					t.Errorf("read error on req %s: %v", req, err)
   988  					wg.Done()
   989  					continue
   990  				}
   991  				if string(all) != req {
   992  					t.Errorf("body of req %s = %q; want %q", req, all, req)
   993  				}
   994  				res.Body.Close()
   995  				wg.Done()
   996  			}
   997  		}()
   998  	}
   999  	for i := 0; i < numReqs; i++ {
  1000  		reqs <- fmt.Sprintf("request-%d", i)
  1001  	}
  1002  	wg.Wait()
  1003  }
  1004  
  1005  func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
  1006  	defer afterTest(t)
  1007  	const debug = false
  1008  	mux := NewServeMux()
  1009  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1010  		io.Copy(w, neverEnding('a'))
  1011  	})
  1012  	ts := httptest.NewServer(mux)
  1013  	timeout := 100 * time.Millisecond
  1014  
  1015  	client := &Client{
  1016  		Transport: &Transport{
  1017  			Dial: func(n, addr string) (net.Conn, error) {
  1018  				conn, err := net.Dial(n, addr)
  1019  				if err != nil {
  1020  					return nil, err
  1021  				}
  1022  				conn.SetDeadline(time.Now().Add(timeout))
  1023  				if debug {
  1024  					conn = NewLoggingConn("client", conn)
  1025  				}
  1026  				return conn, nil
  1027  			},
  1028  			DisableKeepAlives: true,
  1029  		},
  1030  	}
  1031  
  1032  	getFailed := false
  1033  	nRuns := 5
  1034  	if testing.Short() {
  1035  		nRuns = 1
  1036  	}
  1037  	for i := 0; i < nRuns; i++ {
  1038  		if debug {
  1039  			println("run", i+1, "of", nRuns)
  1040  		}
  1041  		sres, err := client.Get(ts.URL + "/get")
  1042  		if err != nil {
  1043  			if !getFailed {
  1044  				// Make the timeout longer, once.
  1045  				getFailed = true
  1046  				t.Logf("increasing timeout")
  1047  				i--
  1048  				timeout *= 10
  1049  				continue
  1050  			}
  1051  			t.Errorf("Error issuing GET: %v", err)
  1052  			break
  1053  		}
  1054  		_, err = io.Copy(ioutil.Discard, sres.Body)
  1055  		if err == nil {
  1056  			t.Errorf("Unexpected successful copy")
  1057  			break
  1058  		}
  1059  	}
  1060  	if debug {
  1061  		println("tests complete; waiting for handlers to finish")
  1062  	}
  1063  	ts.Close()
  1064  }
  1065  
  1066  func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
  1067  	defer afterTest(t)
  1068  	const debug = false
  1069  	mux := NewServeMux()
  1070  	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
  1071  		io.Copy(w, neverEnding('a'))
  1072  	})
  1073  	mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
  1074  		defer r.Body.Close()
  1075  		io.Copy(ioutil.Discard, r.Body)
  1076  	})
  1077  	ts := httptest.NewServer(mux)
  1078  	timeout := 100 * time.Millisecond
  1079  
  1080  	client := &Client{
  1081  		Transport: &Transport{
  1082  			Dial: func(n, addr string) (net.Conn, error) {
  1083  				conn, err := net.Dial(n, addr)
  1084  				if err != nil {
  1085  					return nil, err
  1086  				}
  1087  				conn.SetDeadline(time.Now().Add(timeout))
  1088  				if debug {
  1089  					conn = NewLoggingConn("client", conn)
  1090  				}
  1091  				return conn, nil
  1092  			},
  1093  			DisableKeepAlives: true,
  1094  		},
  1095  	}
  1096  
  1097  	getFailed := false
  1098  	nRuns := 5
  1099  	if testing.Short() {
  1100  		nRuns = 1
  1101  	}
  1102  	for i := 0; i < nRuns; i++ {
  1103  		if debug {
  1104  			println("run", i+1, "of", nRuns)
  1105  		}
  1106  		sres, err := client.Get(ts.URL + "/get")
  1107  		if err != nil {
  1108  			if !getFailed {
  1109  				// Make the timeout longer, once.
  1110  				getFailed = true
  1111  				t.Logf("increasing timeout")
  1112  				i--
  1113  				timeout *= 10
  1114  				continue
  1115  			}
  1116  			t.Errorf("Error issuing GET: %v", err)
  1117  			break
  1118  		}
  1119  		req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
  1120  		_, err = client.Do(req)
  1121  		if err == nil {
  1122  			sres.Body.Close()
  1123  			t.Errorf("Unexpected successful PUT")
  1124  			break
  1125  		}
  1126  		sres.Body.Close()
  1127  	}
  1128  	if debug {
  1129  		println("tests complete; waiting for handlers to finish")
  1130  	}
  1131  	ts.Close()
  1132  }
  1133  
  1134  func TestTransportResponseHeaderTimeout(t *testing.T) {
  1135  	defer afterTest(t)
  1136  	if testing.Short() {
  1137  		t.Skip("skipping timeout test in -short mode")
  1138  	}
  1139  	mux := NewServeMux()
  1140  	mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {})
  1141  	mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
  1142  		time.Sleep(2 * time.Second)
  1143  	})
  1144  	ts := httptest.NewServer(mux)
  1145  	defer ts.Close()
  1146  
  1147  	tr := &Transport{
  1148  		ResponseHeaderTimeout: 500 * time.Millisecond,
  1149  	}
  1150  	defer tr.CloseIdleConnections()
  1151  	c := &Client{Transport: tr}
  1152  
  1153  	tests := []struct {
  1154  		path    string
  1155  		want    int
  1156  		wantErr string
  1157  	}{
  1158  		{path: "/fast", want: 200},
  1159  		{path: "/slow", wantErr: "timeout awaiting response headers"},
  1160  		{path: "/fast", want: 200},
  1161  	}
  1162  	for i, tt := range tests {
  1163  		res, err := c.Get(ts.URL + tt.path)
  1164  		if err != nil {
  1165  			if strings.Contains(err.Error(), tt.wantErr) {
  1166  				continue
  1167  			}
  1168  			t.Errorf("%d. unexpected error: %v", i, err)
  1169  			continue
  1170  		}
  1171  		if tt.wantErr != "" {
  1172  			t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
  1173  			continue
  1174  		}
  1175  		if res.StatusCode != tt.want {
  1176  			t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
  1177  		}
  1178  	}
  1179  }
  1180  
  1181  func TestTransportCancelRequest(t *testing.T) {
  1182  	defer afterTest(t)
  1183  	if testing.Short() {
  1184  		t.Skip("skipping test in -short mode")
  1185  	}
  1186  	unblockc := make(chan bool)
  1187  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1188  		fmt.Fprintf(w, "Hello")
  1189  		w.(Flusher).Flush() // send headers and some body
  1190  		<-unblockc
  1191  	}))
  1192  	defer ts.Close()
  1193  	defer close(unblockc)
  1194  
  1195  	tr := &Transport{}
  1196  	defer tr.CloseIdleConnections()
  1197  	c := &Client{Transport: tr}
  1198  
  1199  	req, _ := NewRequest("GET", ts.URL, nil)
  1200  	res, err := c.Do(req)
  1201  	if err != nil {
  1202  		t.Fatal(err)
  1203  	}
  1204  	go func() {
  1205  		time.Sleep(1 * time.Second)
  1206  		tr.CancelRequest(req)
  1207  	}()
  1208  	t0 := time.Now()
  1209  	body, err := ioutil.ReadAll(res.Body)
  1210  	d := time.Since(t0)
  1211  
  1212  	if err == nil {
  1213  		t.Error("expected an error reading the body")
  1214  	}
  1215  	if string(body) != "Hello" {
  1216  		t.Errorf("Body = %q; want Hello", body)
  1217  	}
  1218  	if d < 500*time.Millisecond {
  1219  		t.Errorf("expected ~1 second delay; got %v", d)
  1220  	}
  1221  	// Verify no outstanding requests after readLoop/writeLoop
  1222  	// goroutines shut down.
  1223  	for tries := 3; tries > 0; tries-- {
  1224  		n := tr.NumPendingRequestsForTesting()
  1225  		if n == 0 {
  1226  			break
  1227  		}
  1228  		time.Sleep(100 * time.Millisecond)
  1229  		if tries == 1 {
  1230  			t.Errorf("pending requests = %d; want 0", n)
  1231  		}
  1232  	}
  1233  }
  1234  
  1235  // golang.org/issue/3672 -- Client can't close HTTP stream
  1236  // Calling Close on a Response.Body used to just read until EOF.
  1237  // Now it actually closes the TCP connection.
  1238  func TestTransportCloseResponseBody(t *testing.T) {
  1239  	defer afterTest(t)
  1240  	writeErr := make(chan error, 1)
  1241  	msg := []byte("young\n")
  1242  	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
  1243  		for {
  1244  			_, err := w.Write(msg)
  1245  			if err != nil {
  1246  				writeErr <- err
  1247  				return
  1248  			}
  1249  			w.(Flusher).Flush()
  1250  		}
  1251  	}))
  1252  	defer ts.Close()
  1253  
  1254  	tr := &Transport{}
  1255  	defer tr.CloseIdleConnections()
  1256  	c := &Client{Transport: tr}
  1257  
  1258  	req, _ := NewRequest("GET", ts.URL, nil)
  1259  	defer tr.CancelRequest(req)
  1260  
  1261  	res, err := c.Do(req)
  1262  	if err != nil {
  1263  		t.Fatal(err)
  1264  	}
  1265  
  1266  	const repeats = 3
  1267  	buf := make([]byte, len(msg)*repeats)
  1268  	want := bytes.Repeat(msg, repeats)
  1269  
  1270  	_, err = io.ReadFull(res.Body, buf)
  1271  	if err != nil {
  1272  		t.Fatal(err)
  1273  	}
  1274  	if !bytes.Equal(buf, want) {
  1275  		t.Errorf("read %q; want %q", buf, want)
  1276  	}
  1277  	didClose := make(chan error, 1)
  1278  	go func() {
  1279  		didClose <- res.Body.Close()
  1280  	}()
  1281  	select {
  1282  	case err := <-didClose:
  1283  		if err != nil {
  1284  			t.Errorf("Close = %v", err)
  1285  		}
  1286  	case <-time.After(10 * time.Second):
  1287  		t.Fatal("too long waiting for close")
  1288  	}
  1289  	select {
  1290  	case err := <-writeErr:
  1291  		if err == nil {
  1292  			t.Errorf("expected non-nil write error")
  1293  		}
  1294  	case <-time.After(10 * time.Second):
  1295  		t.Fatal("too long waiting for write error")
  1296  	}
  1297  }
  1298  
  1299  type fooProto struct{}
  1300  
  1301  func (fooProto) RoundTrip(req *Request) (*Response, error) {
  1302  	res := &Response{
  1303  		Status:     "200 OK",
  1304  		StatusCode: 200,
  1305  		Header:     make(Header),
  1306  		Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
  1307  	}
  1308  	return res, nil
  1309  }
  1310  
  1311  func TestTransportAltProto(t *testing.T) {
  1312  	defer afterTest(t)
  1313  	tr := &Transport{}
  1314  	c := &Client{Transport: tr}
  1315  	tr.RegisterProtocol("foo", fooProto{})
  1316  	res, err := c.Get("foo://bar.com/path")
  1317  	if err != nil {
  1318  		t.Fatal(err)
  1319  	}
  1320  	bodyb, err := ioutil.ReadAll(res.Body)
  1321  	if err != nil {
  1322  		t.Fatal(err)
  1323  	}
  1324  	body := string(bodyb)
  1325  	if e := "You wanted foo://bar.com/path"; body != e {
  1326  		t.Errorf("got response %q, want %q", body, e)
  1327  	}
  1328  }
  1329  
  1330  func TestTransportNoHost(t *testing.T) {
  1331  	defer afterTest(t)
  1332  	tr := &Transport{}
  1333  	_, err := tr.RoundTrip(&Request{
  1334  		Header: make(Header),
  1335  		URL: &url.URL{
  1336  			Scheme: "http",
  1337  		},
  1338  	})
  1339  	want := "http: no Host in request URL"
  1340  	if got := fmt.Sprint(err); got != want {
  1341  		t.Errorf("error = %v; want %q", err, want)
  1342  	}
  1343  }
  1344  
  1345  func TestTransportSocketLateBinding(t *testing.T) {
  1346  	defer afterTest(t)
  1347  
  1348  	mux := NewServeMux()
  1349  	fooGate := make(chan bool, 1)
  1350  	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
  1351  		w.Header().Set("foo-ipport", r.RemoteAddr)
  1352  		w.(Flusher).Flush()
  1353  		<-fooGate
  1354  	})
  1355  	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
  1356  		w.Header().Set("bar-ipport", r.RemoteAddr)
  1357  	})
  1358  	ts := httptest.NewServer(mux)
  1359  	defer ts.Close()
  1360  
  1361  	dialGate := make(chan bool, 1)
  1362  	tr := &Transport{
  1363  		Dial: func(n, addr string) (net.Conn, error) {
  1364  			<-dialGate
  1365  			return net.Dial(n, addr)
  1366  		},
  1367  		DisableKeepAlives: false,
  1368  	}
  1369  	defer tr.CloseIdleConnections()
  1370  	c := &Client{
  1371  		Transport: tr,
  1372  	}
  1373  
  1374  	dialGate <- true // only allow one dial
  1375  	fooRes, err := c.Get(ts.URL + "/foo")
  1376  	if err != nil {
  1377  		t.Fatal(err)
  1378  	}
  1379  	fooAddr := fooRes.Header.Get("foo-ipport")
  1380  	if fooAddr == "" {
  1381  		t.Fatal("No addr on /foo request")
  1382  	}
  1383  	time.AfterFunc(200*time.Millisecond, func() {
  1384  		// let the foo response finish so we can use its
  1385  		// connection for /bar
  1386  		fooGate <- true
  1387  		io.Copy(ioutil.Discard, fooRes.Body)
  1388  		fooRes.Body.Close()
  1389  	})
  1390  
  1391  	barRes, err := c.Get(ts.URL + "/bar")
  1392  	if err != nil {
  1393  		t.Fatal(err)
  1394  	}
  1395  	barAddr := barRes.Header.Get("bar-ipport")
  1396  	if barAddr != fooAddr {
  1397  		t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
  1398  	}
  1399  	barRes.Body.Close()
  1400  	dialGate <- true
  1401  }
  1402  
  1403  // Issue 2184
  1404  func TestTransportReading100Continue(t *testing.T) {
  1405  	defer afterTest(t)
  1406  
  1407  	const numReqs = 5
  1408  	reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
  1409  	reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
  1410  
  1411  	send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
  1412  		defer w.Close()
  1413  		defer r.Close()
  1414  		br := bufio.NewReader(r)
  1415  		n := 0
  1416  		for {
  1417  			n++
  1418  			req, err := ReadRequest(br)
  1419  			if err == io.EOF {
  1420  				return
  1421  			}
  1422  			if err != nil {
  1423  				t.Error(err)
  1424  				return
  1425  			}
  1426  			slurp, err := ioutil.ReadAll(req.Body)
  1427  			if err != nil {
  1428  				t.Errorf("Server request body slurp: %v", err)
  1429  				return
  1430  			}
  1431  			id := req.Header.Get("Request-Id")
  1432  			resCode := req.Header.Get("X-Want-Response-Code")
  1433  			if resCode == "" {
  1434  				resCode = "100 Continue"
  1435  				if string(slurp) != reqBody(n) {
  1436  					t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
  1437  				}
  1438  			}
  1439  			body := fmt.Sprintf("Response number %d", n)
  1440  			v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
  1441  Date: Thu, 28 Feb 2013 17:55:41 GMT
  1442  
  1443  HTTP/1.1 200 OK
  1444  Content-Type: text/html
  1445  Echo-Request-Id: %s
  1446  Content-Length: %d
  1447  
  1448  %s`, resCode, id, len(body), body), "\n", "\r\n", -1))
  1449  			w.Write(v)
  1450  			if id == reqID(numReqs) {
  1451  				return
  1452  			}
  1453  		}
  1454  
  1455  	}
  1456  
  1457  	tr := &Transport{
  1458  		Dial: func(n, addr string) (net.Conn, error) {
  1459  			sr, sw := io.Pipe() // server read/write
  1460  			cr, cw := io.Pipe() // client read/write
  1461  			conn := &rwTestConn{
  1462  				Reader: cr,
  1463  				Writer: sw,
  1464  				closeFunc: func() error {
  1465  					sw.Close()
  1466  					cw.Close()
  1467  					return nil
  1468  				},
  1469  			}
  1470  			go send100Response(cw, sr)
  1471  			return conn, nil
  1472  		},
  1473  		DisableKeepAlives: false,
  1474  	}
  1475  	defer tr.CloseIdleConnections()
  1476  	c := &Client{Transport: tr}
  1477  
  1478  	testResponse := func(req *Request, name string, wantCode int) {
  1479  		res, err := c.Do(req)
  1480  		if err != nil {
  1481  			t.Fatalf("%s: Do: %v", name, err)
  1482  		}
  1483  		if res.StatusCode != wantCode {
  1484  			t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
  1485  		}
  1486  		if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
  1487  			t.Errorf("%s: response id %q != request id %q", name, idBack, id)
  1488  		}
  1489  		_, err = ioutil.ReadAll(res.Body)
  1490  		if err != nil {
  1491  			t.Fatalf("%s: Slurp error: %v", name, err)
  1492  		}
  1493  	}
  1494  
  1495  	// Few 100 responses, making sure we're not off-by-one.
  1496  	for i := 1; i <= numReqs; i++ {
  1497  		req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
  1498  		req.Header.Set("Request-Id", reqID(i))
  1499  		testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
  1500  	}
  1501  
  1502  	// And some other informational 1xx but non-100 responses, to test
  1503  	// we return them but don't re-use the connection.
  1504  	for i := 1; i <= numReqs; i++ {
  1505  		req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i)))
  1506  		req.Header.Set("X-Want-Response-Code", "123 Sesame Street")
  1507  		testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123)
  1508  	}
  1509  }
  1510  
  1511  type proxyFromEnvTest struct {
  1512  	req     string // URL to fetch; blank means "http://example.com"
  1513  	env     string
  1514  	noenv   string
  1515  	want    string
  1516  	wanterr error
  1517  }
  1518  
  1519  func (t proxyFromEnvTest) String() string {
  1520  	var buf bytes.Buffer
  1521  	if t.env != "" {
  1522  		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
  1523  	}
  1524  	if t.noenv != "" {
  1525  		fmt.Fprintf(&buf, " no_proxy=%q", t.noenv)
  1526  	}
  1527  	req := "http://example.com"
  1528  	if t.req != "" {
  1529  		req = t.req
  1530  	}
  1531  	fmt.Fprintf(&buf, " req=%q", req)
  1532  	return strings.TrimSpace(buf.String())
  1533  }
  1534  
  1535  var proxyFromEnvTests = []proxyFromEnvTest{
  1536  	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  1537  	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
  1538  	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
  1539  	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
  1540  	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
  1541  	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
  1542  	{want: "<nil>"},
  1543  	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  1544  	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
  1545  	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  1546  	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
  1547  	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
  1548  }
  1549  
  1550  func TestProxyFromEnvironment(t *testing.T) {
  1551  	os.Setenv("HTTP_PROXY", "")
  1552  	os.Setenv("http_proxy", "")
  1553  	os.Setenv("NO_PROXY", "")
  1554  	os.Setenv("no_proxy", "")
  1555  	for _, tt := range proxyFromEnvTests {
  1556  		os.Setenv("HTTP_PROXY", tt.env)
  1557  		os.Setenv("NO_PROXY", tt.noenv)
  1558  		reqURL := tt.req
  1559  		if reqURL == "" {
  1560  			reqURL = "http://example.com"
  1561  		}
  1562  		req, _ := NewRequest("GET", reqURL, nil)
  1563  		url, err := ProxyFromEnvironment(req)
  1564  		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
  1565  			t.Errorf("%v: got error = %q, want %q", tt, g, e)
  1566  			continue
  1567  		}
  1568  		if got := fmt.Sprintf("%s", url); got != tt.want {
  1569  			t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
  1570  		}
  1571  	}
  1572  }
  1573  
  1574  // rgz is a gzip quine that uncompresses to itself.
  1575  var rgz = []byte{
  1576  	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
  1577  	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
  1578  	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
  1579  	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
  1580  	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
  1581  	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
  1582  	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
  1583  	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
  1584  	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
  1585  	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
  1586  	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
  1587  	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
  1588  	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
  1589  	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
  1590  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  1591  	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
  1592  	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
  1593  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
  1594  	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
  1595  	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
  1596  	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
  1597  	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
  1598  	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
  1599  	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
  1600  	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
  1601  	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
  1602  	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
  1603  	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
  1604  	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
  1605  	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  1606  	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
  1607  	0x00, 0x00,
  1608  }