summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/net/http2/transport_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/http2/transport_test.go')
-rw-r--r--vendor/golang.org/x/net/http2/transport_test.go147
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)
+ }
+}