github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/src/net/http/clientserver_test.go (about)

     1  // Copyright 2015 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 that use both the client & server, in both HTTP/1 and HTTP/2 mode.
     6  
     7  package http_test
     8  
     9  import (
    10  	"bytes"
    11  	"compress/gzip"
    12  	"crypto/tls"
    13  	"fmt"
    14  	"io"
    15  	"io/ioutil"
    16  	"log"
    17  	"net"
    18  	. "net/http"
    19  	"net/http/httptest"
    20  	"net/http/httputil"
    21  	"net/url"
    22  	"os"
    23  	"reflect"
    24  	"runtime"
    25  	"sort"
    26  	"strings"
    27  	"sync"
    28  	"sync/atomic"
    29  	"testing"
    30  	"time"
    31  )
    32  
    33  type clientServerTest struct {
    34  	t  *testing.T
    35  	h2 bool
    36  	h  Handler
    37  	ts *httptest.Server
    38  	tr *Transport
    39  	c  *Client
    40  }
    41  
    42  func (t *clientServerTest) close() {
    43  	t.tr.CloseIdleConnections()
    44  	t.ts.Close()
    45  }
    46  
    47  func (t *clientServerTest) scheme() string {
    48  	if t.h2 {
    49  		return "https"
    50  	}
    51  	return "http"
    52  }
    53  
    54  const (
    55  	h1Mode = false
    56  	h2Mode = true
    57  )
    58  
    59  func newClientServerTest(t *testing.T, h2 bool, h Handler, opts ...interface{}) *clientServerTest {
    60  	cst := &clientServerTest{
    61  		t:  t,
    62  		h2: h2,
    63  		h:  h,
    64  		tr: &Transport{},
    65  	}
    66  	cst.c = &Client{Transport: cst.tr}
    67  
    68  	for _, opt := range opts {
    69  		switch opt := opt.(type) {
    70  		case func(*Transport):
    71  			opt(cst.tr)
    72  		default:
    73  			t.Fatalf("unhandled option type %T", opt)
    74  		}
    75  	}
    76  
    77  	if !h2 {
    78  		cst.ts = httptest.NewServer(h)
    79  		return cst
    80  	}
    81  	cst.ts = httptest.NewUnstartedServer(h)
    82  	ExportHttp2ConfigureServer(cst.ts.Config, nil)
    83  	cst.ts.TLS = cst.ts.Config.TLSConfig
    84  	cst.ts.StartTLS()
    85  
    86  	cst.tr.TLSClientConfig = &tls.Config{
    87  		InsecureSkipVerify: true,
    88  	}
    89  	if err := ExportHttp2ConfigureTransport(cst.tr); err != nil {
    90  		t.Fatal(err)
    91  	}
    92  	return cst
    93  }
    94  
    95  // Testing the newClientServerTest helper itself.
    96  func TestNewClientServerTest(t *testing.T) {
    97  	var got struct {
    98  		sync.Mutex
    99  		log []string
   100  	}
   101  	h := HandlerFunc(func(w ResponseWriter, r *Request) {
   102  		got.Lock()
   103  		defer got.Unlock()
   104  		got.log = append(got.log, r.Proto)
   105  	})
   106  	for _, v := range [2]bool{false, true} {
   107  		cst := newClientServerTest(t, v, h)
   108  		if _, err := cst.c.Head(cst.ts.URL); err != nil {
   109  			t.Fatal(err)
   110  		}
   111  		cst.close()
   112  	}
   113  	got.Lock() // no need to unlock
   114  	if want := []string{"HTTP/1.1", "HTTP/2.0"}; !reflect.DeepEqual(got.log, want) {
   115  		t.Errorf("got %q; want %q", got.log, want)
   116  	}
   117  }
   118  
   119  func TestChunkedResponseHeaders_h1(t *testing.T) { testChunkedResponseHeaders(t, h1Mode) }
   120  func TestChunkedResponseHeaders_h2(t *testing.T) { testChunkedResponseHeaders(t, h2Mode) }
   121  
   122  func testChunkedResponseHeaders(t *testing.T, h2 bool) {
   123  	defer afterTest(t)
   124  	log.SetOutput(ioutil.Discard) // is noisy otherwise
   125  	defer log.SetOutput(os.Stderr)
   126  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   127  		w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted
   128  		w.(Flusher).Flush()
   129  		fmt.Fprintf(w, "I am a chunked response.")
   130  	}))
   131  	defer cst.close()
   132  
   133  	res, err := cst.c.Get(cst.ts.URL)
   134  	if err != nil {
   135  		t.Fatalf("Get error: %v", err)
   136  	}
   137  	defer res.Body.Close()
   138  	if g, e := res.ContentLength, int64(-1); g != e {
   139  		t.Errorf("expected ContentLength of %d; got %d", e, g)
   140  	}
   141  	wantTE := []string{"chunked"}
   142  	if h2 {
   143  		wantTE = nil
   144  	}
   145  	if !reflect.DeepEqual(res.TransferEncoding, wantTE) {
   146  		t.Errorf("TransferEncoding = %v; want %v", res.TransferEncoding, wantTE)
   147  	}
   148  	if got, haveCL := res.Header["Content-Length"]; haveCL {
   149  		t.Errorf("Unexpected Content-Length: %q", got)
   150  	}
   151  }
   152  
   153  type reqFunc func(c *Client, url string) (*Response, error)
   154  
   155  // h12Compare is a test that compares HTTP/1 and HTTP/2 behavior
   156  // against each other.
   157  type h12Compare struct {
   158  	Handler            func(ResponseWriter, *Request)    // required
   159  	ReqFunc            reqFunc                           // optional
   160  	CheckResponse      func(proto string, res *Response) // optional
   161  	EarlyCheckResponse func(proto string, res *Response) // optional; pre-normalize
   162  	Opts               []interface{}
   163  }
   164  
   165  func (tt h12Compare) reqFunc() reqFunc {
   166  	if tt.ReqFunc == nil {
   167  		return (*Client).Get
   168  	}
   169  	return tt.ReqFunc
   170  }
   171  
   172  func (tt h12Compare) run(t *testing.T) {
   173  	setParallel(t)
   174  	cst1 := newClientServerTest(t, false, HandlerFunc(tt.Handler), tt.Opts...)
   175  	defer cst1.close()
   176  	cst2 := newClientServerTest(t, true, HandlerFunc(tt.Handler), tt.Opts...)
   177  	defer cst2.close()
   178  
   179  	res1, err := tt.reqFunc()(cst1.c, cst1.ts.URL)
   180  	if err != nil {
   181  		t.Errorf("HTTP/1 request: %v", err)
   182  		return
   183  	}
   184  	res2, err := tt.reqFunc()(cst2.c, cst2.ts.URL)
   185  	if err != nil {
   186  		t.Errorf("HTTP/2 request: %v", err)
   187  		return
   188  	}
   189  
   190  	if fn := tt.EarlyCheckResponse; fn != nil {
   191  		fn("HTTP/1.1", res1)
   192  		fn("HTTP/2.0", res2)
   193  	}
   194  
   195  	tt.normalizeRes(t, res1, "HTTP/1.1")
   196  	tt.normalizeRes(t, res2, "HTTP/2.0")
   197  	res1body, res2body := res1.Body, res2.Body
   198  
   199  	eres1 := mostlyCopy(res1)
   200  	eres2 := mostlyCopy(res2)
   201  	if !reflect.DeepEqual(eres1, eres2) {
   202  		t.Errorf("Response headers to handler differed:\nhttp/1 (%v):\n\t%#v\nhttp/2 (%v):\n\t%#v",
   203  			cst1.ts.URL, eres1, cst2.ts.URL, eres2)
   204  	}
   205  	if !reflect.DeepEqual(res1body, res2body) {
   206  		t.Errorf("Response bodies to handler differed.\nhttp1: %v\nhttp2: %v\n", res1body, res2body)
   207  	}
   208  	if fn := tt.CheckResponse; fn != nil {
   209  		res1.Body, res2.Body = res1body, res2body
   210  		fn("HTTP/1.1", res1)
   211  		fn("HTTP/2.0", res2)
   212  	}
   213  }
   214  
   215  func mostlyCopy(r *Response) *Response {
   216  	c := *r
   217  	c.Body = nil
   218  	c.TransferEncoding = nil
   219  	c.TLS = nil
   220  	c.Request = nil
   221  	return &c
   222  }
   223  
   224  type slurpResult struct {
   225  	io.ReadCloser
   226  	body []byte
   227  	err  error
   228  }
   229  
   230  func (sr slurpResult) String() string { return fmt.Sprintf("body %q; err %v", sr.body, sr.err) }
   231  
   232  func (tt h12Compare) normalizeRes(t *testing.T, res *Response, wantProto string) {
   233  	if res.Proto == wantProto {
   234  		res.Proto, res.ProtoMajor, res.ProtoMinor = "", 0, 0
   235  	} else {
   236  		t.Errorf("got %q response; want %q", res.Proto, wantProto)
   237  	}
   238  	slurp, err := ioutil.ReadAll(res.Body)
   239  
   240  	res.Body.Close()
   241  	res.Body = slurpResult{
   242  		ReadCloser: ioutil.NopCloser(bytes.NewReader(slurp)),
   243  		body:       slurp,
   244  		err:        err,
   245  	}
   246  	for i, v := range res.Header["Date"] {
   247  		res.Header["Date"][i] = strings.Repeat("x", len(v))
   248  	}
   249  	if res.Request == nil {
   250  		t.Errorf("for %s, no request", wantProto)
   251  	}
   252  	if (res.TLS != nil) != (wantProto == "HTTP/2.0") {
   253  		t.Errorf("TLS set = %v; want %v", res.TLS != nil, res.TLS == nil)
   254  	}
   255  }
   256  
   257  // Issue 13532
   258  func TestH12_HeadContentLengthNoBody(t *testing.T) {
   259  	h12Compare{
   260  		ReqFunc: (*Client).Head,
   261  		Handler: func(w ResponseWriter, r *Request) {
   262  		},
   263  	}.run(t)
   264  }
   265  
   266  func TestH12_HeadContentLengthSmallBody(t *testing.T) {
   267  	h12Compare{
   268  		ReqFunc: (*Client).Head,
   269  		Handler: func(w ResponseWriter, r *Request) {
   270  			io.WriteString(w, "small")
   271  		},
   272  	}.run(t)
   273  }
   274  
   275  func TestH12_HeadContentLengthLargeBody(t *testing.T) {
   276  	h12Compare{
   277  		ReqFunc: (*Client).Head,
   278  		Handler: func(w ResponseWriter, r *Request) {
   279  			chunk := strings.Repeat("x", 512<<10)
   280  			for i := 0; i < 10; i++ {
   281  				io.WriteString(w, chunk)
   282  			}
   283  		},
   284  	}.run(t)
   285  }
   286  
   287  func TestH12_200NoBody(t *testing.T) {
   288  	h12Compare{Handler: func(w ResponseWriter, r *Request) {}}.run(t)
   289  }
   290  
   291  func TestH2_204NoBody(t *testing.T) { testH12_noBody(t, 204) }
   292  func TestH2_304NoBody(t *testing.T) { testH12_noBody(t, 304) }
   293  func TestH2_404NoBody(t *testing.T) { testH12_noBody(t, 404) }
   294  
   295  func testH12_noBody(t *testing.T, status int) {
   296  	h12Compare{Handler: func(w ResponseWriter, r *Request) {
   297  		w.WriteHeader(status)
   298  	}}.run(t)
   299  }
   300  
   301  func TestH12_SmallBody(t *testing.T) {
   302  	h12Compare{Handler: func(w ResponseWriter, r *Request) {
   303  		io.WriteString(w, "small body")
   304  	}}.run(t)
   305  }
   306  
   307  func TestH12_ExplicitContentLength(t *testing.T) {
   308  	h12Compare{Handler: func(w ResponseWriter, r *Request) {
   309  		w.Header().Set("Content-Length", "3")
   310  		io.WriteString(w, "foo")
   311  	}}.run(t)
   312  }
   313  
   314  func TestH12_FlushBeforeBody(t *testing.T) {
   315  	h12Compare{Handler: func(w ResponseWriter, r *Request) {
   316  		w.(Flusher).Flush()
   317  		io.WriteString(w, "foo")
   318  	}}.run(t)
   319  }
   320  
   321  func TestH12_FlushMidBody(t *testing.T) {
   322  	h12Compare{Handler: func(w ResponseWriter, r *Request) {
   323  		io.WriteString(w, "foo")
   324  		w.(Flusher).Flush()
   325  		io.WriteString(w, "bar")
   326  	}}.run(t)
   327  }
   328  
   329  func TestH12_Head_ExplicitLen(t *testing.T) {
   330  	h12Compare{
   331  		ReqFunc: (*Client).Head,
   332  		Handler: func(w ResponseWriter, r *Request) {
   333  			if r.Method != "HEAD" {
   334  				t.Errorf("unexpected method %q", r.Method)
   335  			}
   336  			w.Header().Set("Content-Length", "1235")
   337  		},
   338  	}.run(t)
   339  }
   340  
   341  func TestH12_Head_ImplicitLen(t *testing.T) {
   342  	h12Compare{
   343  		ReqFunc: (*Client).Head,
   344  		Handler: func(w ResponseWriter, r *Request) {
   345  			if r.Method != "HEAD" {
   346  				t.Errorf("unexpected method %q", r.Method)
   347  			}
   348  			io.WriteString(w, "foo")
   349  		},
   350  	}.run(t)
   351  }
   352  
   353  func TestH12_HandlerWritesTooLittle(t *testing.T) {
   354  	h12Compare{
   355  		Handler: func(w ResponseWriter, r *Request) {
   356  			w.Header().Set("Content-Length", "3")
   357  			io.WriteString(w, "12") // one byte short
   358  		},
   359  		CheckResponse: func(proto string, res *Response) {
   360  			sr, ok := res.Body.(slurpResult)
   361  			if !ok {
   362  				t.Errorf("%s body is %T; want slurpResult", proto, res.Body)
   363  				return
   364  			}
   365  			if sr.err != io.ErrUnexpectedEOF {
   366  				t.Errorf("%s read error = %v; want io.ErrUnexpectedEOF", proto, sr.err)
   367  			}
   368  			if string(sr.body) != "12" {
   369  				t.Errorf("%s body = %q; want %q", proto, sr.body, "12")
   370  			}
   371  		},
   372  	}.run(t)
   373  }
   374  
   375  // Tests that the HTTP/1 and HTTP/2 servers prevent handlers from
   376  // writing more than they declared. This test does not test whether
   377  // the transport deals with too much data, though, since the server
   378  // doesn't make it possible to send bogus data. For those tests, see
   379  // transport_test.go (for HTTP/1) or x/net/http2/transport_test.go
   380  // (for HTTP/2).
   381  func TestH12_HandlerWritesTooMuch(t *testing.T) {
   382  	h12Compare{
   383  		Handler: func(w ResponseWriter, r *Request) {
   384  			w.Header().Set("Content-Length", "3")
   385  			w.(Flusher).Flush()
   386  			io.WriteString(w, "123")
   387  			w.(Flusher).Flush()
   388  			n, err := io.WriteString(w, "x") // too many
   389  			if n > 0 || err == nil {
   390  				t.Errorf("for proto %q, final write = %v, %v; want 0, some error", r.Proto, n, err)
   391  			}
   392  		},
   393  	}.run(t)
   394  }
   395  
   396  // Verify that both our HTTP/1 and HTTP/2 request and auto-decompress gzip.
   397  // Some hosts send gzip even if you don't ask for it; see golang.org/issue/13298
   398  func TestH12_AutoGzip(t *testing.T) {
   399  	h12Compare{
   400  		Handler: func(w ResponseWriter, r *Request) {
   401  			if ae := r.Header.Get("Accept-Encoding"); ae != "gzip" {
   402  				t.Errorf("%s Accept-Encoding = %q; want gzip", r.Proto, ae)
   403  			}
   404  			w.Header().Set("Content-Encoding", "gzip")
   405  			gz := gzip.NewWriter(w)
   406  			io.WriteString(gz, "I am some gzipped content. Go go go go go go go go go go go go should compress well.")
   407  			gz.Close()
   408  		},
   409  	}.run(t)
   410  }
   411  
   412  func TestH12_AutoGzip_Disabled(t *testing.T) {
   413  	h12Compare{
   414  		Opts: []interface{}{
   415  			func(tr *Transport) { tr.DisableCompression = true },
   416  		},
   417  		Handler: func(w ResponseWriter, r *Request) {
   418  			fmt.Fprintf(w, "%q", r.Header["Accept-Encoding"])
   419  			if ae := r.Header.Get("Accept-Encoding"); ae != "" {
   420  				t.Errorf("%s Accept-Encoding = %q; want empty", r.Proto, ae)
   421  			}
   422  		},
   423  	}.run(t)
   424  }
   425  
   426  // Test304Responses verifies that 304s don't declare that they're
   427  // chunking in their response headers and aren't allowed to produce
   428  // output.
   429  func Test304Responses_h1(t *testing.T) { test304Responses(t, h1Mode) }
   430  func Test304Responses_h2(t *testing.T) { test304Responses(t, h2Mode) }
   431  
   432  func test304Responses(t *testing.T, h2 bool) {
   433  	defer afterTest(t)
   434  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   435  		w.WriteHeader(StatusNotModified)
   436  		_, err := w.Write([]byte("illegal body"))
   437  		if err != ErrBodyNotAllowed {
   438  			t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
   439  		}
   440  	}))
   441  	defer cst.close()
   442  	res, err := cst.c.Get(cst.ts.URL)
   443  	if err != nil {
   444  		t.Fatal(err)
   445  	}
   446  	if len(res.TransferEncoding) > 0 {
   447  		t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
   448  	}
   449  	body, err := ioutil.ReadAll(res.Body)
   450  	if err != nil {
   451  		t.Error(err)
   452  	}
   453  	if len(body) > 0 {
   454  		t.Errorf("got unexpected body %q", string(body))
   455  	}
   456  }
   457  
   458  func TestH12_ServerEmptyContentLength(t *testing.T) {
   459  	h12Compare{
   460  		Handler: func(w ResponseWriter, r *Request) {
   461  			w.Header()["Content-Type"] = []string{""}
   462  			io.WriteString(w, "<html><body>hi</body></html>")
   463  		},
   464  	}.run(t)
   465  }
   466  
   467  func TestH12_RequestContentLength_Known_NonZero(t *testing.T) {
   468  	h12requestContentLength(t, func() io.Reader { return strings.NewReader("FOUR") }, 4)
   469  }
   470  
   471  func TestH12_RequestContentLength_Known_Zero(t *testing.T) {
   472  	h12requestContentLength(t, func() io.Reader { return nil }, 0)
   473  }
   474  
   475  func TestH12_RequestContentLength_Unknown(t *testing.T) {
   476  	h12requestContentLength(t, func() io.Reader { return struct{ io.Reader }{strings.NewReader("Stuff")} }, -1)
   477  }
   478  
   479  func h12requestContentLength(t *testing.T, bodyfn func() io.Reader, wantLen int64) {
   480  	h12Compare{
   481  		Handler: func(w ResponseWriter, r *Request) {
   482  			w.Header().Set("Got-Length", fmt.Sprint(r.ContentLength))
   483  			fmt.Fprintf(w, "Req.ContentLength=%v", r.ContentLength)
   484  		},
   485  		ReqFunc: func(c *Client, url string) (*Response, error) {
   486  			return c.Post(url, "text/plain", bodyfn())
   487  		},
   488  		CheckResponse: func(proto string, res *Response) {
   489  			if got, want := res.Header.Get("Got-Length"), fmt.Sprint(wantLen); got != want {
   490  				t.Errorf("Proto %q got length %q; want %q", proto, got, want)
   491  			}
   492  		},
   493  	}.run(t)
   494  }
   495  
   496  // Tests that closing the Request.Cancel channel also while still
   497  // reading the response body. Issue 13159.
   498  func TestCancelRequestMidBody_h1(t *testing.T) { testCancelRequestMidBody(t, h1Mode) }
   499  func TestCancelRequestMidBody_h2(t *testing.T) { testCancelRequestMidBody(t, h2Mode) }
   500  func testCancelRequestMidBody(t *testing.T, h2 bool) {
   501  	defer afterTest(t)
   502  	unblock := make(chan bool)
   503  	didFlush := make(chan bool, 1)
   504  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   505  		io.WriteString(w, "Hello")
   506  		w.(Flusher).Flush()
   507  		didFlush <- true
   508  		<-unblock
   509  		io.WriteString(w, ", world.")
   510  	}))
   511  	defer cst.close()
   512  	defer close(unblock)
   513  
   514  	req, _ := NewRequest("GET", cst.ts.URL, nil)
   515  	cancel := make(chan struct{})
   516  	req.Cancel = cancel
   517  
   518  	res, err := cst.c.Do(req)
   519  	if err != nil {
   520  		t.Fatal(err)
   521  	}
   522  	defer res.Body.Close()
   523  	<-didFlush
   524  
   525  	// Read a bit before we cancel. (Issue 13626)
   526  	// We should have "Hello" at least sitting there.
   527  	firstRead := make([]byte, 10)
   528  	n, err := res.Body.Read(firstRead)
   529  	if err != nil {
   530  		t.Fatal(err)
   531  	}
   532  	firstRead = firstRead[:n]
   533  
   534  	close(cancel)
   535  
   536  	rest, err := ioutil.ReadAll(res.Body)
   537  	all := string(firstRead) + string(rest)
   538  	if all != "Hello" {
   539  		t.Errorf("Read %q (%q + %q); want Hello", all, firstRead, rest)
   540  	}
   541  	if !reflect.DeepEqual(err, ExportErrRequestCanceled) {
   542  		t.Errorf("ReadAll error = %v; want %v", err, ExportErrRequestCanceled)
   543  	}
   544  }
   545  
   546  // Tests that clients can send trailers to a server and that the server can read them.
   547  func TestTrailersClientToServer_h1(t *testing.T) { testTrailersClientToServer(t, h1Mode) }
   548  func TestTrailersClientToServer_h2(t *testing.T) { testTrailersClientToServer(t, h2Mode) }
   549  
   550  func testTrailersClientToServer(t *testing.T, h2 bool) {
   551  	defer afterTest(t)
   552  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   553  		var decl []string
   554  		for k := range r.Trailer {
   555  			decl = append(decl, k)
   556  		}
   557  		sort.Strings(decl)
   558  
   559  		slurp, err := ioutil.ReadAll(r.Body)
   560  		if err != nil {
   561  			t.Errorf("Server reading request body: %v", err)
   562  		}
   563  		if string(slurp) != "foo" {
   564  			t.Errorf("Server read request body %q; want foo", slurp)
   565  		}
   566  		if r.Trailer == nil {
   567  			io.WriteString(w, "nil Trailer")
   568  		} else {
   569  			fmt.Fprintf(w, "decl: %v, vals: %s, %s",
   570  				decl,
   571  				r.Trailer.Get("Client-Trailer-A"),
   572  				r.Trailer.Get("Client-Trailer-B"))
   573  		}
   574  	}))
   575  	defer cst.close()
   576  
   577  	var req *Request
   578  	req, _ = NewRequest("POST", cst.ts.URL, io.MultiReader(
   579  		eofReaderFunc(func() {
   580  			req.Trailer["Client-Trailer-A"] = []string{"valuea"}
   581  		}),
   582  		strings.NewReader("foo"),
   583  		eofReaderFunc(func() {
   584  			req.Trailer["Client-Trailer-B"] = []string{"valueb"}
   585  		}),
   586  	))
   587  	req.Trailer = Header{
   588  		"Client-Trailer-A": nil, //  to be set later
   589  		"Client-Trailer-B": nil, //  to be set later
   590  	}
   591  	req.ContentLength = -1
   592  	res, err := cst.c.Do(req)
   593  	if err != nil {
   594  		t.Fatal(err)
   595  	}
   596  	if err := wantBody(res, err, "decl: [Client-Trailer-A Client-Trailer-B], vals: valuea, valueb"); err != nil {
   597  		t.Error(err)
   598  	}
   599  }
   600  
   601  // Tests that servers send trailers to a client and that the client can read them.
   602  func TestTrailersServerToClient_h1(t *testing.T)       { testTrailersServerToClient(t, h1Mode, false) }
   603  func TestTrailersServerToClient_h2(t *testing.T)       { testTrailersServerToClient(t, h2Mode, false) }
   604  func TestTrailersServerToClient_Flush_h1(t *testing.T) { testTrailersServerToClient(t, h1Mode, true) }
   605  func TestTrailersServerToClient_Flush_h2(t *testing.T) { testTrailersServerToClient(t, h2Mode, true) }
   606  
   607  func testTrailersServerToClient(t *testing.T, h2, flush bool) {
   608  	defer afterTest(t)
   609  	const body = "Some body"
   610  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   611  		w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
   612  		w.Header().Add("Trailer", "Server-Trailer-C")
   613  
   614  		io.WriteString(w, body)
   615  		if flush {
   616  			w.(Flusher).Flush()
   617  		}
   618  
   619  		// How handlers set Trailers: declare it ahead of time
   620  		// with the Trailer header, and then mutate the
   621  		// Header() of those values later, after the response
   622  		// has been written (we wrote to w above).
   623  		w.Header().Set("Server-Trailer-A", "valuea")
   624  		w.Header().Set("Server-Trailer-C", "valuec") // skipping B
   625  		w.Header().Set("Server-Trailer-NotDeclared", "should be omitted")
   626  	}))
   627  	defer cst.close()
   628  
   629  	res, err := cst.c.Get(cst.ts.URL)
   630  	if err != nil {
   631  		t.Fatal(err)
   632  	}
   633  
   634  	wantHeader := Header{
   635  		"Content-Type": {"text/plain; charset=utf-8"},
   636  	}
   637  	wantLen := -1
   638  	if h2 && !flush {
   639  		// In HTTP/1.1, any use of trailers forces HTTP/1.1
   640  		// chunking and a flush at the first write. That's
   641  		// unnecessary with HTTP/2's framing, so the server
   642  		// is able to calculate the length while still sending
   643  		// trailers afterwards.
   644  		wantLen = len(body)
   645  		wantHeader["Content-Length"] = []string{fmt.Sprint(wantLen)}
   646  	}
   647  	if res.ContentLength != int64(wantLen) {
   648  		t.Errorf("ContentLength = %v; want %v", res.ContentLength, wantLen)
   649  	}
   650  
   651  	delete(res.Header, "Date") // irrelevant for test
   652  	if !reflect.DeepEqual(res.Header, wantHeader) {
   653  		t.Errorf("Header = %v; want %v", res.Header, wantHeader)
   654  	}
   655  
   656  	if got, want := res.Trailer, (Header{
   657  		"Server-Trailer-A": nil,
   658  		"Server-Trailer-B": nil,
   659  		"Server-Trailer-C": nil,
   660  	}); !reflect.DeepEqual(got, want) {
   661  		t.Errorf("Trailer before body read = %v; want %v", got, want)
   662  	}
   663  
   664  	if err := wantBody(res, nil, body); err != nil {
   665  		t.Fatal(err)
   666  	}
   667  
   668  	if got, want := res.Trailer, (Header{
   669  		"Server-Trailer-A": {"valuea"},
   670  		"Server-Trailer-B": nil,
   671  		"Server-Trailer-C": {"valuec"},
   672  	}); !reflect.DeepEqual(got, want) {
   673  		t.Errorf("Trailer after body read = %v; want %v", got, want)
   674  	}
   675  }
   676  
   677  // Don't allow a Body.Read after Body.Close. Issue 13648.
   678  func TestResponseBodyReadAfterClose_h1(t *testing.T) { testResponseBodyReadAfterClose(t, h1Mode) }
   679  func TestResponseBodyReadAfterClose_h2(t *testing.T) { testResponseBodyReadAfterClose(t, h2Mode) }
   680  
   681  func testResponseBodyReadAfterClose(t *testing.T, h2 bool) {
   682  	defer afterTest(t)
   683  	const body = "Some body"
   684  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   685  		io.WriteString(w, body)
   686  	}))
   687  	defer cst.close()
   688  	res, err := cst.c.Get(cst.ts.URL)
   689  	if err != nil {
   690  		t.Fatal(err)
   691  	}
   692  	res.Body.Close()
   693  	data, err := ioutil.ReadAll(res.Body)
   694  	if len(data) != 0 || err == nil {
   695  		t.Fatalf("ReadAll returned %q, %v; want error", data, err)
   696  	}
   697  }
   698  
   699  func TestConcurrentReadWriteReqBody_h1(t *testing.T) { testConcurrentReadWriteReqBody(t, h1Mode) }
   700  func TestConcurrentReadWriteReqBody_h2(t *testing.T) { testConcurrentReadWriteReqBody(t, h2Mode) }
   701  func testConcurrentReadWriteReqBody(t *testing.T, h2 bool) {
   702  	defer afterTest(t)
   703  	const reqBody = "some request body"
   704  	const resBody = "some response body"
   705  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   706  		var wg sync.WaitGroup
   707  		wg.Add(2)
   708  		didRead := make(chan bool, 1)
   709  		// Read in one goroutine.
   710  		go func() {
   711  			defer wg.Done()
   712  			data, err := ioutil.ReadAll(r.Body)
   713  			if string(data) != reqBody {
   714  				t.Errorf("Handler read %q; want %q", data, reqBody)
   715  			}
   716  			if err != nil {
   717  				t.Errorf("Handler Read: %v", err)
   718  			}
   719  			didRead <- true
   720  		}()
   721  		// Write in another goroutine.
   722  		go func() {
   723  			defer wg.Done()
   724  			if !h2 {
   725  				// our HTTP/1 implementation intentionally
   726  				// doesn't permit writes during read (mostly
   727  				// due to it being undefined); if that is ever
   728  				// relaxed, change this.
   729  				<-didRead
   730  			}
   731  			io.WriteString(w, resBody)
   732  		}()
   733  		wg.Wait()
   734  	}))
   735  	defer cst.close()
   736  	req, _ := NewRequest("POST", cst.ts.URL, strings.NewReader(reqBody))
   737  	req.Header.Add("Expect", "100-continue") // just to complicate things
   738  	res, err := cst.c.Do(req)
   739  	if err != nil {
   740  		t.Fatal(err)
   741  	}
   742  	data, err := ioutil.ReadAll(res.Body)
   743  	defer res.Body.Close()
   744  	if err != nil {
   745  		t.Fatal(err)
   746  	}
   747  	if string(data) != resBody {
   748  		t.Errorf("read %q; want %q", data, resBody)
   749  	}
   750  }
   751  
   752  func TestConnectRequest_h1(t *testing.T) { testConnectRequest(t, h1Mode) }
   753  func TestConnectRequest_h2(t *testing.T) { testConnectRequest(t, h2Mode) }
   754  func testConnectRequest(t *testing.T, h2 bool) {
   755  	defer afterTest(t)
   756  	gotc := make(chan *Request, 1)
   757  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   758  		gotc <- r
   759  	}))
   760  	defer cst.close()
   761  
   762  	u, err := url.Parse(cst.ts.URL)
   763  	if err != nil {
   764  		t.Fatal(err)
   765  	}
   766  
   767  	tests := []struct {
   768  		req  *Request
   769  		want string
   770  	}{
   771  		{
   772  			req: &Request{
   773  				Method: "CONNECT",
   774  				Header: Header{},
   775  				URL:    u,
   776  			},
   777  			want: u.Host,
   778  		},
   779  		{
   780  			req: &Request{
   781  				Method: "CONNECT",
   782  				Header: Header{},
   783  				URL:    u,
   784  				Host:   "example.com:123",
   785  			},
   786  			want: "example.com:123",
   787  		},
   788  	}
   789  
   790  	for i, tt := range tests {
   791  		res, err := cst.c.Do(tt.req)
   792  		if err != nil {
   793  			t.Errorf("%d. RoundTrip = %v", i, err)
   794  			continue
   795  		}
   796  		res.Body.Close()
   797  		req := <-gotc
   798  		if req.Method != "CONNECT" {
   799  			t.Errorf("method = %q; want CONNECT", req.Method)
   800  		}
   801  		if req.Host != tt.want {
   802  			t.Errorf("Host = %q; want %q", req.Host, tt.want)
   803  		}
   804  		if req.URL.Host != tt.want {
   805  			t.Errorf("URL.Host = %q; want %q", req.URL.Host, tt.want)
   806  		}
   807  	}
   808  }
   809  
   810  func TestTransportUserAgent_h1(t *testing.T) { testTransportUserAgent(t, h1Mode) }
   811  func TestTransportUserAgent_h2(t *testing.T) { testTransportUserAgent(t, h2Mode) }
   812  func testTransportUserAgent(t *testing.T, h2 bool) {
   813  	defer afterTest(t)
   814  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   815  		fmt.Fprintf(w, "%q", r.Header["User-Agent"])
   816  	}))
   817  	defer cst.close()
   818  
   819  	either := func(a, b string) string {
   820  		if h2 {
   821  			return b
   822  		}
   823  		return a
   824  	}
   825  
   826  	tests := []struct {
   827  		setup func(*Request)
   828  		want  string
   829  	}{
   830  		{
   831  			func(r *Request) {},
   832  			either(`["Go-http-client/1.1"]`, `["Go-http-client/2.0"]`),
   833  		},
   834  		{
   835  			func(r *Request) { r.Header.Set("User-Agent", "foo/1.2.3") },
   836  			`["foo/1.2.3"]`,
   837  		},
   838  		{
   839  			func(r *Request) { r.Header["User-Agent"] = []string{"single", "or", "multiple"} },
   840  			`["single"]`,
   841  		},
   842  		{
   843  			func(r *Request) { r.Header.Set("User-Agent", "") },
   844  			`[]`,
   845  		},
   846  		{
   847  			func(r *Request) { r.Header["User-Agent"] = nil },
   848  			`[]`,
   849  		},
   850  	}
   851  	for i, tt := range tests {
   852  		req, _ := NewRequest("GET", cst.ts.URL, nil)
   853  		tt.setup(req)
   854  		res, err := cst.c.Do(req)
   855  		if err != nil {
   856  			t.Errorf("%d. RoundTrip = %v", i, err)
   857  			continue
   858  		}
   859  		slurp, err := ioutil.ReadAll(res.Body)
   860  		res.Body.Close()
   861  		if err != nil {
   862  			t.Errorf("%d. read body = %v", i, err)
   863  			continue
   864  		}
   865  		if string(slurp) != tt.want {
   866  			t.Errorf("%d. body mismatch.\n got: %s\nwant: %s\n", i, slurp, tt.want)
   867  		}
   868  	}
   869  }
   870  
   871  func TestStarRequestFoo_h1(t *testing.T)     { testStarRequest(t, "FOO", h1Mode) }
   872  func TestStarRequestFoo_h2(t *testing.T)     { testStarRequest(t, "FOO", h2Mode) }
   873  func TestStarRequestOptions_h1(t *testing.T) { testStarRequest(t, "OPTIONS", h1Mode) }
   874  func TestStarRequestOptions_h2(t *testing.T) { testStarRequest(t, "OPTIONS", h2Mode) }
   875  func testStarRequest(t *testing.T, method string, h2 bool) {
   876  	defer afterTest(t)
   877  	gotc := make(chan *Request, 1)
   878  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
   879  		w.Header().Set("foo", "bar")
   880  		gotc <- r
   881  		w.(Flusher).Flush()
   882  	}))
   883  	defer cst.close()
   884  
   885  	u, err := url.Parse(cst.ts.URL)
   886  	if err != nil {
   887  		t.Fatal(err)
   888  	}
   889  	u.Path = "*"
   890  
   891  	req := &Request{
   892  		Method: method,
   893  		Header: Header{},
   894  		URL:    u,
   895  	}
   896  
   897  	res, err := cst.c.Do(req)
   898  	if err != nil {
   899  		t.Fatalf("RoundTrip = %v", err)
   900  	}
   901  	res.Body.Close()
   902  
   903  	wantFoo := "bar"
   904  	wantLen := int64(-1)
   905  	if method == "OPTIONS" {
   906  		wantFoo = ""
   907  		wantLen = 0
   908  	}
   909  	if res.StatusCode != 200 {
   910  		t.Errorf("status code = %v; want %d", res.Status, 200)
   911  	}
   912  	if res.ContentLength != wantLen {
   913  		t.Errorf("content length = %v; want %d", res.ContentLength, wantLen)
   914  	}
   915  	if got := res.Header.Get("foo"); got != wantFoo {
   916  		t.Errorf("response \"foo\" header = %q; want %q", got, wantFoo)
   917  	}
   918  	select {
   919  	case req = <-gotc:
   920  	default:
   921  		req = nil
   922  	}
   923  	if req == nil {
   924  		if method != "OPTIONS" {
   925  			t.Fatalf("handler never got request")
   926  		}
   927  		return
   928  	}
   929  	if req.Method != method {
   930  		t.Errorf("method = %q; want %q", req.Method, method)
   931  	}
   932  	if req.URL.Path != "*" {
   933  		t.Errorf("URL.Path = %q; want *", req.URL.Path)
   934  	}
   935  	if req.RequestURI != "*" {
   936  		t.Errorf("RequestURI = %q; want *", req.RequestURI)
   937  	}
   938  }
   939  
   940  // Issue 13957
   941  func TestTransportDiscardsUnneededConns(t *testing.T) {
   942  	setParallel(t)
   943  	defer afterTest(t)
   944  	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
   945  		fmt.Fprintf(w, "Hello, %v", r.RemoteAddr)
   946  	}))
   947  	defer cst.close()
   948  
   949  	var numOpen, numClose int32 // atomic
   950  
   951  	tlsConfig := &tls.Config{InsecureSkipVerify: true}
   952  	tr := &Transport{
   953  		TLSClientConfig: tlsConfig,
   954  		DialTLS: func(_, addr string) (net.Conn, error) {
   955  			time.Sleep(10 * time.Millisecond)
   956  			rc, err := net.Dial("tcp", addr)
   957  			if err != nil {
   958  				return nil, err
   959  			}
   960  			atomic.AddInt32(&numOpen, 1)
   961  			c := noteCloseConn{rc, func() { atomic.AddInt32(&numClose, 1) }}
   962  			return tls.Client(c, tlsConfig), nil
   963  		},
   964  	}
   965  	if err := ExportHttp2ConfigureTransport(tr); err != nil {
   966  		t.Fatal(err)
   967  	}
   968  	defer tr.CloseIdleConnections()
   969  
   970  	c := &Client{Transport: tr}
   971  
   972  	const N = 10
   973  	gotBody := make(chan string, N)
   974  	var wg sync.WaitGroup
   975  	for i := 0; i < N; i++ {
   976  		wg.Add(1)
   977  		go func() {
   978  			defer wg.Done()
   979  			resp, err := c.Get(cst.ts.URL)
   980  			if err != nil {
   981  				t.Errorf("Get: %v", err)
   982  				return
   983  			}
   984  			defer resp.Body.Close()
   985  			slurp, err := ioutil.ReadAll(resp.Body)
   986  			if err != nil {
   987  				t.Error(err)
   988  			}
   989  			gotBody <- string(slurp)
   990  		}()
   991  	}
   992  	wg.Wait()
   993  	close(gotBody)
   994  
   995  	var last string
   996  	for got := range gotBody {
   997  		if last == "" {
   998  			last = got
   999  			continue
  1000  		}
  1001  		if got != last {
  1002  			t.Errorf("Response body changed: %q -> %q", last, got)
  1003  		}
  1004  	}
  1005  
  1006  	var open, close int32
  1007  	for i := 0; i < 150; i++ {
  1008  		open, close = atomic.LoadInt32(&numOpen), atomic.LoadInt32(&numClose)
  1009  		if open < 1 {
  1010  			t.Fatalf("open = %d; want at least", open)
  1011  		}
  1012  		if close == open-1 {
  1013  			// Success
  1014  			return
  1015  		}
  1016  		time.Sleep(10 * time.Millisecond)
  1017  	}
  1018  	t.Errorf("%d connections opened, %d closed; want %d to close", open, close, open-1)
  1019  }
  1020  
  1021  // tests that Transport doesn't retain a pointer to the provided request.
  1022  func TestTransportGCRequest_Body_h1(t *testing.T)   { testTransportGCRequest(t, h1Mode, true) }
  1023  func TestTransportGCRequest_Body_h2(t *testing.T)   { testTransportGCRequest(t, h2Mode, true) }
  1024  func TestTransportGCRequest_NoBody_h1(t *testing.T) { testTransportGCRequest(t, h1Mode, false) }
  1025  func TestTransportGCRequest_NoBody_h2(t *testing.T) { testTransportGCRequest(t, h2Mode, false) }
  1026  func testTransportGCRequest(t *testing.T, h2, body bool) {
  1027  	setParallel(t)
  1028  	defer afterTest(t)
  1029  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  1030  		ioutil.ReadAll(r.Body)
  1031  		if body {
  1032  			io.WriteString(w, "Hello.")
  1033  		}
  1034  	}))
  1035  	defer cst.close()
  1036  
  1037  	didGC := make(chan struct{})
  1038  	(func() {
  1039  		body := strings.NewReader("some body")
  1040  		req, _ := NewRequest("POST", cst.ts.URL, body)
  1041  		runtime.SetFinalizer(req, func(*Request) { close(didGC) })
  1042  		res, err := cst.c.Do(req)
  1043  		if err != nil {
  1044  			t.Fatal(err)
  1045  		}
  1046  		if _, err := ioutil.ReadAll(res.Body); err != nil {
  1047  			t.Fatal(err)
  1048  		}
  1049  		if err := res.Body.Close(); err != nil {
  1050  			t.Fatal(err)
  1051  		}
  1052  	})()
  1053  	timeout := time.NewTimer(5 * time.Second)
  1054  	defer timeout.Stop()
  1055  	for {
  1056  		select {
  1057  		case <-didGC:
  1058  			return
  1059  		case <-time.After(100 * time.Millisecond):
  1060  			runtime.GC()
  1061  		case <-timeout.C:
  1062  			t.Fatal("never saw GC of request")
  1063  		}
  1064  	}
  1065  }
  1066  
  1067  func TestTransportRejectsInvalidHeaders_h1(t *testing.T) {
  1068  	testTransportRejectsInvalidHeaders(t, h1Mode)
  1069  }
  1070  func TestTransportRejectsInvalidHeaders_h2(t *testing.T) {
  1071  	testTransportRejectsInvalidHeaders(t, h2Mode)
  1072  }
  1073  func testTransportRejectsInvalidHeaders(t *testing.T, h2 bool) {
  1074  	setParallel(t)
  1075  	defer afterTest(t)
  1076  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  1077  		fmt.Fprintf(w, "Handler saw headers: %q", r.Header)
  1078  	}))
  1079  	defer cst.close()
  1080  	cst.tr.DisableKeepAlives = true
  1081  
  1082  	tests := []struct {
  1083  		key, val string
  1084  		ok       bool
  1085  	}{
  1086  		{"Foo", "capital-key", true}, // verify h2 allows capital keys
  1087  		{"Foo", "foo\x00bar", false}, // \x00 byte in value not allowed
  1088  		{"Foo", "two\nlines", false}, // \n byte in value not allowed
  1089  		{"bogus\nkey", "v", false},   // \n byte also not allowed in key
  1090  		{"A space", "v", false},      // spaces in keys not allowed
  1091  		{"имя", "v", false},          // key must be ascii
  1092  		{"name", "валю", true},       // value may be non-ascii
  1093  		{"", "v", false},             // key must be non-empty
  1094  		{"k", "", true},              // value may be empty
  1095  	}
  1096  	for _, tt := range tests {
  1097  		dialedc := make(chan bool, 1)
  1098  		cst.tr.Dial = func(netw, addr string) (net.Conn, error) {
  1099  			dialedc <- true
  1100  			return net.Dial(netw, addr)
  1101  		}
  1102  		req, _ := NewRequest("GET", cst.ts.URL, nil)
  1103  		req.Header[tt.key] = []string{tt.val}
  1104  		res, err := cst.c.Do(req)
  1105  		var body []byte
  1106  		if err == nil {
  1107  			body, _ = ioutil.ReadAll(res.Body)
  1108  			res.Body.Close()
  1109  		}
  1110  		var dialed bool
  1111  		select {
  1112  		case <-dialedc:
  1113  			dialed = true
  1114  		default:
  1115  		}
  1116  
  1117  		if !tt.ok && dialed {
  1118  			t.Errorf("For key %q, value %q, transport dialed. Expected local failure. Response was: (%v, %v)\nServer replied with: %s", tt.key, tt.val, res, err, body)
  1119  		} else if (err == nil) != tt.ok {
  1120  			t.Errorf("For key %q, value %q; got err = %v; want ok=%v", tt.key, tt.val, err, tt.ok)
  1121  		}
  1122  	}
  1123  }
  1124  
  1125  // Tests that we support bogus under-100 HTTP statuses, because we historically
  1126  // have. This might change at some point, but not yet in Go 1.6.
  1127  func TestBogusStatusWorks_h1(t *testing.T) { testBogusStatusWorks(t, h1Mode) }
  1128  func TestBogusStatusWorks_h2(t *testing.T) { testBogusStatusWorks(t, h2Mode) }
  1129  func testBogusStatusWorks(t *testing.T, h2 bool) {
  1130  	defer afterTest(t)
  1131  	const code = 7
  1132  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  1133  		w.WriteHeader(code)
  1134  	}))
  1135  	defer cst.close()
  1136  
  1137  	res, err := cst.c.Get(cst.ts.URL)
  1138  	if err != nil {
  1139  		t.Fatal(err)
  1140  	}
  1141  	if res.StatusCode != code {
  1142  		t.Errorf("StatusCode = %d; want %d", res.StatusCode, code)
  1143  	}
  1144  }
  1145  
  1146  func TestInterruptWithPanic_h1(t *testing.T) { testInterruptWithPanic(t, h1Mode) }
  1147  func TestInterruptWithPanic_h2(t *testing.T) { testInterruptWithPanic(t, h2Mode) }
  1148  func testInterruptWithPanic(t *testing.T, h2 bool) {
  1149  	log.SetOutput(ioutil.Discard) // is noisy otherwise
  1150  	defer log.SetOutput(os.Stderr)
  1151  
  1152  	const msg = "hello"
  1153  	defer afterTest(t)
  1154  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  1155  		io.WriteString(w, msg)
  1156  		w.(Flusher).Flush()
  1157  		panic("no more")
  1158  	}))
  1159  	defer cst.close()
  1160  	res, err := cst.c.Get(cst.ts.URL)
  1161  	if err != nil {
  1162  		t.Fatal(err)
  1163  	}
  1164  	defer res.Body.Close()
  1165  	slurp, err := ioutil.ReadAll(res.Body)
  1166  	if string(slurp) != msg {
  1167  		t.Errorf("client read %q; want %q", slurp, msg)
  1168  	}
  1169  	if err == nil {
  1170  		t.Errorf("client read all successfully; want some error")
  1171  	}
  1172  }
  1173  
  1174  // Issue 15366
  1175  func TestH12_AutoGzipWithDumpResponse(t *testing.T) {
  1176  	h12Compare{
  1177  		Handler: func(w ResponseWriter, r *Request) {
  1178  			h := w.Header()
  1179  			h.Set("Content-Encoding", "gzip")
  1180  			h.Set("Content-Length", "23")
  1181  			h.Set("Connection", "keep-alive")
  1182  			io.WriteString(w, "\x1f\x8b\b\x00\x00\x00\x00\x00\x00\x00s\xf3\xf7\a\x00\xab'\xd4\x1a\x03\x00\x00\x00")
  1183  		},
  1184  		EarlyCheckResponse: func(proto string, res *Response) {
  1185  			if !res.Uncompressed {
  1186  				t.Errorf("%s: expected Uncompressed to be set", proto)
  1187  			}
  1188  			dump, err := httputil.DumpResponse(res, true)
  1189  			if err != nil {
  1190  				t.Errorf("%s: DumpResponse: %v", proto, err)
  1191  				return
  1192  			}
  1193  			if strings.Contains(string(dump), "Connection: close") {
  1194  				t.Errorf("%s: should not see \"Connection: close\" in dump; got:\n%s", proto, dump)
  1195  			}
  1196  			if !strings.Contains(string(dump), "FOO") {
  1197  				t.Errorf("%s: should see \"FOO\" in response; got:\n%s", proto, dump)
  1198  			}
  1199  		},
  1200  	}.run(t)
  1201  }
  1202  
  1203  // Issue 14607
  1204  func TestCloseIdleConnections_h1(t *testing.T) { testCloseIdleConnections(t, h1Mode) }
  1205  func TestCloseIdleConnections_h2(t *testing.T) { testCloseIdleConnections(t, h2Mode) }
  1206  func testCloseIdleConnections(t *testing.T, h2 bool) {
  1207  	setParallel(t)
  1208  	defer afterTest(t)
  1209  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  1210  		w.Header().Set("X-Addr", r.RemoteAddr)
  1211  	}))
  1212  	defer cst.close()
  1213  	get := func() string {
  1214  		res, err := cst.c.Get(cst.ts.URL)
  1215  		if err != nil {
  1216  			t.Fatal(err)
  1217  		}
  1218  		res.Body.Close()
  1219  		v := res.Header.Get("X-Addr")
  1220  		if v == "" {
  1221  			t.Fatal("didn't get X-Addr")
  1222  		}
  1223  		return v
  1224  	}
  1225  	a1 := get()
  1226  	cst.tr.CloseIdleConnections()
  1227  	a2 := get()
  1228  	if a1 == a2 {
  1229  		t.Errorf("didn't close connection")
  1230  	}
  1231  }
  1232  
  1233  type noteCloseConn struct {
  1234  	net.Conn
  1235  	closeFunc func()
  1236  }
  1237  
  1238  func (x noteCloseConn) Close() error {
  1239  	x.closeFunc()
  1240  	return x.Conn.Close()
  1241  }
  1242  
  1243  type testErrorReader struct{ t *testing.T }
  1244  
  1245  func (r testErrorReader) Read(p []byte) (n int, err error) {
  1246  	r.t.Error("unexpected Read call")
  1247  	return 0, io.EOF
  1248  }
  1249  
  1250  func TestNoSniffExpectRequestBody_h1(t *testing.T) { testNoSniffExpectRequestBody(t, h1Mode) }
  1251  func TestNoSniffExpectRequestBody_h2(t *testing.T) { testNoSniffExpectRequestBody(t, h2Mode) }
  1252  
  1253  func testNoSniffExpectRequestBody(t *testing.T, h2 bool) {
  1254  	defer afterTest(t)
  1255  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  1256  		w.WriteHeader(StatusUnauthorized)
  1257  	}))
  1258  	defer cst.close()
  1259  
  1260  	// Set ExpectContinueTimeout non-zero so RoundTrip won't try to write it.
  1261  	cst.tr.ExpectContinueTimeout = 10 * time.Second
  1262  
  1263  	req, err := NewRequest("POST", cst.ts.URL, testErrorReader{t})
  1264  	if err != nil {
  1265  		t.Fatal(err)
  1266  	}
  1267  	req.ContentLength = 0 // so transport is tempted to sniff it
  1268  	req.Header.Set("Expect", "100-continue")
  1269  	res, err := cst.tr.RoundTrip(req)
  1270  	if err != nil {
  1271  		t.Fatal(err)
  1272  	}
  1273  	defer res.Body.Close()
  1274  	if res.StatusCode != StatusUnauthorized {
  1275  		t.Errorf("status code = %v; want %v", res.StatusCode, StatusUnauthorized)
  1276  	}
  1277  }
  1278  
  1279  func TestServerUndeclaredTrailers_h1(t *testing.T) { testServerUndeclaredTrailers(t, h1Mode) }
  1280  func TestServerUndeclaredTrailers_h2(t *testing.T) { testServerUndeclaredTrailers(t, h2Mode) }
  1281  func testServerUndeclaredTrailers(t *testing.T, h2 bool) {
  1282  	defer afterTest(t)
  1283  	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
  1284  		w.Header().Set("Foo", "Bar")
  1285  		w.Header().Set("Trailer:Foo", "Baz")
  1286  		w.(Flusher).Flush()
  1287  		w.Header().Add("Trailer:Foo", "Baz2")
  1288  		w.Header().Set("Trailer:Bar", "Quux")
  1289  	}))
  1290  	defer cst.close()
  1291  	res, err := cst.c.Get(cst.ts.URL)
  1292  	if err != nil {
  1293  		t.Fatal(err)
  1294  	}
  1295  	if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
  1296  		t.Fatal(err)
  1297  	}
  1298  	res.Body.Close()
  1299  	delete(res.Header, "Date")
  1300  	delete(res.Header, "Content-Type")
  1301  
  1302  	if want := (Header{"Foo": {"Bar"}}); !reflect.DeepEqual(res.Header, want) {
  1303  		t.Errorf("Header = %#v; want %#v", res.Header, want)
  1304  	}
  1305  	if want := (Header{"Foo": {"Baz", "Baz2"}, "Bar": {"Quux"}}); !reflect.DeepEqual(res.Trailer, want) {
  1306  		t.Errorf("Trailer = %#v; want %#v", res.Trailer, want)
  1307  	}
  1308  }