diff options
author | Emmanuel T Odeke <emmanuel@orijtech.com> | 2019-10-19 23:50:15 -0700 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2019-10-21 17:10:59 +0000 |
commit | ff9f7bc9da45b66689d8e61b6c674b555517de20 (patch) | |
tree | f6b520b2349135c2b4c3fd7f90a36ececce92042 /src/net/http/transport_test.go | |
parent | a7ce2ca52f6de38e7db0a67bbdf697a6b5dc122a (diff) | |
download | go-ff9f7bc9da45b66689d8e61b6c674b555517de20.tar.gz go-ff9f7bc9da45b66689d8e61b6c674b555517de20.zip |
net/http: make Transport.RoundTrip close body on any invalid request
Fixes #35015
Change-Id: I7a1ed9cfa219ad88014aad033e3a01f9dffc3eb3
Reviewed-on: https://go-review.googlesource.com/c/go/+/202239
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net/http/transport_test.go')
-rw-r--r-- | src/net/http/transport_test.go | 92 |
1 files changed, 79 insertions, 13 deletions
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go index 0fe1283d97..c84d3ea1d6 100644 --- a/src/net/http/transport_test.go +++ b/src/net/http/transport_test.go @@ -5730,21 +5730,87 @@ func (bc *bodyCloser) Read(b []byte) (n int, err error) { return 0, io.EOF } -func TestInvalidMethodClosesBody(t *testing.T) { - cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) +// Issue 35015: ensure that Transport closes the body on any error +// with an invalid request, as promised by Client.Do docs. +func TestTransportClosesBodyOnInvalidRequests(t *testing.T) { + cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + t.Errorf("Should not have been invoked") + })) defer cst.Close() - var bc bodyCloser + u, _ := url.Parse(cst.URL) - req := &Request{ - Method: " ", - URL: u, - Body: &bc, - } - _, err := DefaultClient.Do(req) - if err == nil { - t.Fatal("Expected an error") + + tests := []struct { + name string + req *Request + wantErr string + }{ + { + name: "invalid method", + req: &Request{ + Method: " ", + URL: u, + }, + wantErr: "invalid method", + }, + { + name: "nil URL", + req: &Request{ + Method: "GET", + }, + wantErr: "nil Request.URL", + }, + { + name: "invalid header key", + req: &Request{ + Method: "GET", + Header: Header{"💡": {"emoji"}}, + URL: u, + }, + wantErr: "invalid header field name", + }, + { + name: "invalid header value", + req: &Request{ + Method: "POST", + Header: Header{"key": {"\x19"}}, + URL: u, + }, + wantErr: "invalid header field value", + }, + { + name: "non HTTP(s) scheme", + req: &Request{ + Method: "POST", + URL: &url.URL{Scheme: "faux"}, + }, + wantErr: "unsupported protocol scheme", + }, + { + name: "no Host in URL", + req: &Request{ + Method: "POST", + URL: &url.URL{Scheme: "http"}, + }, + wantErr: "no Host", + }, } - if !bc { - t.Fatal("Expected body to have been closed") + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var bc bodyCloser + req := tt.req + req.Body = &bc + _, err := DefaultClient.Do(tt.req) + if err == nil { + t.Fatal("Expected an error") + } + if !bc { + t.Fatal("Expected body to have been closed") + } + if g, w := err.Error(), tt.wantErr; !strings.Contains(g, w) { + t.Fatalf("Error mismatch\n\t%q\ndoes not contain\n\t%q", g, w) + } + }) } } |