diff options
Diffstat (limited to 'vendor/golang.org/x/net/http2/transport_test.go')
-rw-r--r-- | vendor/golang.org/x/net/http2/transport_test.go | 147 |
1 files changed, 137 insertions, 10 deletions
diff --git a/vendor/golang.org/x/net/http2/transport_test.go b/vendor/golang.org/x/net/http2/transport_test.go index 96d0a0867..f9287e575 100644 --- a/vendor/golang.org/x/net/http2/transport_test.go +++ b/vendor/golang.org/x/net/http2/transport_test.go @@ -39,6 +39,13 @@ var ( var tlsConfigInsecure = &tls.Config{InsecureSkipVerify: true} +type testContext struct{} + +func (testContext) Done() <-chan struct{} { return make(chan struct{}) } +func (testContext) Err() error { panic("should not be called") } +func (testContext) Deadline() (deadline time.Time, ok bool) { return time.Time{}, false } +func (testContext) Value(key interface{}) interface{} { return nil } + func TestTransportExternal(t *testing.T) { if !*extNet { t.Skip("skipping external network test") @@ -52,6 +59,16 @@ func TestTransportExternal(t *testing.T) { res.Write(os.Stdout) } +type fakeTLSConn struct { + net.Conn +} + +func (c *fakeTLSConn) ConnectionState() tls.ConnectionState { + return tls.ConnectionState{ + Version: tls.VersionTLS12, + } +} + func startH2cServer(t *testing.T) net.Listener { h2Server := &Server{} l := newLocalListener(t) @@ -61,8 +78,8 @@ func startH2cServer(t *testing.T) net.Listener { t.Error(err) return } - h2Server.ServeConn(conn, &ServeConnOpts{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Hello, %v", r.URL.Path) + h2Server.ServeConn(&fakeTLSConn{conn}, &ServeConnOpts{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hello, %v, http: %v", r.URL.Path, r.TLS == nil) })}) }() return l @@ -92,7 +109,7 @@ func TestTransportH2c(t *testing.T) { if err != nil { t.Fatal(err) } - if got, want := string(body), "Hello, /foobar"; got != want { + if got, want := string(body), "Hello, /foobar, http: true"; got != want { t.Fatalf("response got %v, want %v", got, want) } } @@ -374,6 +391,40 @@ func randString(n int) string { return string(b) } +type panicReader struct{} + +func (panicReader) Read([]byte) (int, error) { panic("unexpected Read") } +func (panicReader) Close() error { panic("unexpected Close") } + +func TestActualContentLength(t *testing.T) { + tests := []struct { + req *http.Request + want int64 + }{ + // Verify we don't read from Body: + 0: { + req: &http.Request{Body: panicReader{}}, + want: -1, + }, + // nil Body means 0, regardless of ContentLength: + 1: { + req: &http.Request{Body: nil, ContentLength: 5}, + want: 0, + }, + // ContentLength is used if set. + 2: { + req: &http.Request{Body: panicReader{}, ContentLength: 5}, + want: 5, + }, + } + for i, tt := range tests { + got := actualContentLength(tt.req) + if got != tt.want { + t.Errorf("test[%d]: got %d; want %d", i, got, tt.want) + } + } +} + func TestTransportBody(t *testing.T) { bodyTests := []struct { body string @@ -381,8 +432,6 @@ func TestTransportBody(t *testing.T) { }{ {body: "some message"}, {body: "some message", noContentLen: true}, - {body: ""}, - {body: "", noContentLen: true}, {body: strings.Repeat("a", 1<<20), noContentLen: true}, {body: strings.Repeat("a", 1<<20)}, {body: randString(16<<10 - 1)}, @@ -1690,12 +1739,12 @@ func TestTransportRejectsConnHeaders(t *testing.T) { { key: "Upgrade", value: []string{"anything"}, - want: "ERROR: http2: invalid Upgrade request header", + want: "ERROR: http2: invalid Upgrade request header: [\"anything\"]", }, { key: "Connection", value: []string{"foo"}, - want: "ERROR: http2: invalid Connection request header", + want: "ERROR: http2: invalid Connection request header: [\"foo\"]", }, { key: "Connection", @@ -1705,7 +1754,7 @@ func TestTransportRejectsConnHeaders(t *testing.T) { { key: "Connection", value: []string{"close", "something-else"}, - want: "ERROR: http2: invalid Connection request header", + want: "ERROR: http2: invalid Connection request header: [\"close\" \"something-else\"]", }, { key: "Connection", @@ -1725,7 +1774,7 @@ func TestTransportRejectsConnHeaders(t *testing.T) { { key: "Transfer-Encoding", value: []string{"foo"}, - want: "ERROR: http2: invalid Transfer-Encoding request header", + want: "ERROR: http2: invalid Transfer-Encoding request header: [\"foo\"]", }, { key: "Transfer-Encoding", @@ -1735,7 +1784,7 @@ func TestTransportRejectsConnHeaders(t *testing.T) { { key: "Transfer-Encoding", value: []string{"chunked", "other"}, - want: "ERROR: http2: invalid Transfer-Encoding request header", + want: "ERROR: http2: invalid Transfer-Encoding request header: [\"chunked\" \"other\"]", }, { key: "Content-Length", @@ -1898,8 +1947,17 @@ func TestTransportNewTLSConfig(t *testing.T) { }, } for i, tt := range tests { + // Ignore the session ticket keys part, which ends up populating + // unexported fields in the Config: + if tt.conf != nil { + tt.conf.SessionTicketsDisabled = true + } + tr := &Transport{TLSClientConfig: tt.conf} got := tr.newTLSConfig(tt.host) + + got.SessionTicketsDisabled = false + if !reflect.DeepEqual(got, tt.want) { t.Errorf("%d. got %#v; want %#v", i, got, tt.want) } @@ -2618,3 +2676,72 @@ func TestRoundTripDoesntConsumeRequestBodyEarly(t *testing.T) { t.Errorf("Body = %q; want %q", slurp, body) } } + +func TestClientConnPing(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, optOnlyServer) + defer st.Close() + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + cc, err := tr.dialClientConn(st.ts.Listener.Addr().String(), false) + if err != nil { + t.Fatal(err) + } + if err = cc.Ping(testContext{}); err != nil { + t.Fatal(err) + } +} + +// Issue 16974: if the server sent a DATA frame after the user +// canceled the Transport's Request, the Transport previously wrote to a +// closed pipe, got an error, and ended up closing the whole TCP +// connection. +func TestTransportCancelDataResponseRace(t *testing.T) { + cancel := make(chan struct{}) + clientGotError := make(chan bool, 1) + + const msg = "Hello." + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + if strings.Contains(r.URL.Path, "/hello") { + time.Sleep(50 * time.Millisecond) + io.WriteString(w, msg) + return + } + for i := 0; i < 50; i++ { + io.WriteString(w, "Some data.") + w.(http.Flusher).Flush() + if i == 2 { + close(cancel) + <-clientGotError + } + time.Sleep(10 * time.Millisecond) + } + }, optOnlyServer) + defer st.Close() + + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + + c := &http.Client{Transport: tr} + req, _ := http.NewRequest("GET", st.ts.URL, nil) + req.Cancel = cancel + res, err := c.Do(req) + if err != nil { + t.Fatal(err) + } + if _, err = io.Copy(ioutil.Discard, res.Body); err == nil { + t.Fatal("unexpected success") + } + clientGotError <- true + + res, err = c.Get(st.ts.URL + "/hello") + if err != nil { + t.Fatal(err) + } + slurp, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + if string(slurp) != msg { + t.Errorf("Got = %q; want %q", slurp, msg) + } +} |