mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
net/http: run more tests in http2 mode
Failing ones are marked skipped. Fixes #13543 (was just a test issue) Updates #13555 (to be fixed later) Updates #13556 (to be fixed later) Updates #13557 (to be fixed later) Fixes bug in golang.org/cl/17428 (http1 now uses HTTP status 431, not 413) Change-Id: I8f7431fee35f2fc081cfe2c232ae75a00800a60b Reviewed-on: https://go-review.googlesource.com/17683 Reviewed-by: Blake Mizerany <blake.mizerany@gmail.com> Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com> Reviewed-by: Burcu Dogan <jbd@google.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
07f9c25b35
commit
c2ef005486
7 changed files with 144 additions and 105 deletions
|
|
@ -83,8 +83,8 @@ func TestClient(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientHead_h1(t *testing.T) { testClientHead(t, false) }
|
func TestClientHead_h1(t *testing.T) { testClientHead(t, h1Mode) }
|
||||||
func TestClientHead_h2(t *testing.T) { testClientHead(t, true) }
|
func TestClientHead_h2(t *testing.T) { testClientHead(t, h2Mode) }
|
||||||
|
|
||||||
func testClientHead(t *testing.T, h2 bool) {
|
func testClientHead(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
@ -496,8 +496,8 @@ func (j *RecordingJar) logf(format string, args ...interface{}) {
|
||||||
fmt.Fprintf(&j.log, format, args...)
|
fmt.Fprintf(&j.log, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamingGet_h1(t *testing.T) { testStreamingGet(t, false) }
|
func TestStreamingGet_h1(t *testing.T) { testStreamingGet(t, h1Mode) }
|
||||||
func TestStreamingGet_h2(t *testing.T) { testStreamingGet(t, true) }
|
func TestStreamingGet_h2(t *testing.T) { testStreamingGet(t, h2Mode) }
|
||||||
|
|
||||||
func testStreamingGet(t *testing.T, h2 bool) {
|
func testStreamingGet(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
@ -772,11 +772,11 @@ func TestHTTPSClientDetectsHTTPServer(t *testing.T) {
|
||||||
|
|
||||||
// Verify Response.ContentLength is populated. https://golang.org/issue/4126
|
// Verify Response.ContentLength is populated. https://golang.org/issue/4126
|
||||||
func TestClientHeadContentLength_h1(t *testing.T) {
|
func TestClientHeadContentLength_h1(t *testing.T) {
|
||||||
testClientHeadContentLength(t, false)
|
testClientHeadContentLength(t, h1Mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientHeadContentLength_h2(t *testing.T) {
|
func TestClientHeadContentLength_h2(t *testing.T) {
|
||||||
testClientHeadContentLength(t, true)
|
testClientHeadContentLength(t, h2Mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testClientHeadContentLength(t *testing.T, h2 bool) {
|
func testClientHeadContentLength(t *testing.T, h2 bool) {
|
||||||
|
|
@ -1037,14 +1037,8 @@ func TestClientTimeout_Headers(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientRedirectEatsBody_h1(t *testing.T) {
|
func TestClientRedirectEatsBody_h1(t *testing.T) { testClientRedirectEatsBody(t, h1Mode) }
|
||||||
testClientRedirectEatsBody(t, false)
|
func TestClientRedirectEatsBody_h2(t *testing.T) { testClientRedirectEatsBody(t, h2Mode) }
|
||||||
}
|
|
||||||
|
|
||||||
func TestClientRedirectEatsBody_h2(t *testing.T) {
|
|
||||||
testClientRedirectEatsBody(t, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testClientRedirectEatsBody(t *testing.T, h2 bool) {
|
func testClientRedirectEatsBody(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
saw := make(chan string, 2)
|
saw := make(chan string, 2)
|
||||||
|
|
@ -1093,9 +1087,14 @@ func (f eofReaderFunc) Read(p []byte) (n int, err error) {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientTrailers(t *testing.T) {
|
func TestClientTrailers_h1(t *testing.T) { testClientTrailers(t, h1Mode) }
|
||||||
|
func TestClientTrailers_h2(t *testing.T) {
|
||||||
|
t.Skip("skipping in http2 mode; golang.org/issue/13557")
|
||||||
|
testClientTrailers(t, h2Mode)
|
||||||
|
}
|
||||||
|
func testClientTrailers(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
w.Header().Set("Connection", "close")
|
w.Header().Set("Connection", "close")
|
||||||
w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
|
w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
|
||||||
w.Header().Add("Trailer", "Server-Trailer-C")
|
w.Header().Add("Trailer", "Server-Trailer-C")
|
||||||
|
|
@ -1129,10 +1128,10 @@ func TestClientTrailers(t *testing.T) {
|
||||||
w.Header().Set("Server-Trailer-A", "valuea")
|
w.Header().Set("Server-Trailer-A", "valuea")
|
||||||
w.Header().Set("Server-Trailer-C", "valuec") // skipping B
|
w.Header().Set("Server-Trailer-C", "valuec") // skipping B
|
||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer cst.close()
|
||||||
|
|
||||||
var req *Request
|
var req *Request
|
||||||
req, _ = NewRequest("POST", ts.URL, io.MultiReader(
|
req, _ = NewRequest("POST", cst.ts.URL, io.MultiReader(
|
||||||
eofReaderFunc(func() {
|
eofReaderFunc(func() {
|
||||||
req.Trailer["Client-Trailer-A"] = []string{"valuea"}
|
req.Trailer["Client-Trailer-A"] = []string{"valuea"}
|
||||||
}),
|
}),
|
||||||
|
|
@ -1146,7 +1145,7 @@ func TestClientTrailers(t *testing.T) {
|
||||||
"Client-Trailer-B": nil, // to be set later
|
"Client-Trailer-B": nil, // to be set later
|
||||||
}
|
}
|
||||||
req.ContentLength = -1
|
req.ContentLength = -1
|
||||||
res, err := DefaultClient.Do(req)
|
res, err := cst.c.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,11 @@ func (t *clientServerTest) close() {
|
||||||
t.ts.Close()
|
t.ts.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
h1Mode = false
|
||||||
|
h2Mode = true
|
||||||
|
)
|
||||||
|
|
||||||
func newClientServerTest(t *testing.T, h2 bool, h Handler) *clientServerTest {
|
func newClientServerTest(t *testing.T, h2 bool, h Handler) *clientServerTest {
|
||||||
cst := &clientServerTest{
|
cst := &clientServerTest{
|
||||||
t: t,
|
t: t,
|
||||||
|
|
@ -87,8 +92,8 @@ func TestNewClientServerTest(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChunkedResponseHeaders_h1(t *testing.T) { testChunkedResponseHeaders(t, false) }
|
func TestChunkedResponseHeaders_h1(t *testing.T) { testChunkedResponseHeaders(t, h1Mode) }
|
||||||
func TestChunkedResponseHeaders_h2(t *testing.T) { testChunkedResponseHeaders(t, true) }
|
func TestChunkedResponseHeaders_h2(t *testing.T) { testChunkedResponseHeaders(t, h2Mode) }
|
||||||
|
|
||||||
func testChunkedResponseHeaders(t *testing.T, h2 bool) {
|
func testChunkedResponseHeaders(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
@ -354,8 +359,6 @@ func TestH12_HandlerWritesTooMuch(t *testing.T) {
|
||||||
}.run(t)
|
}.run(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: TestH12_Trailers
|
|
||||||
|
|
||||||
// Verify that both our HTTP/1 and HTTP/2 request and auto-decompress gzip.
|
// Verify that both our HTTP/1 and HTTP/2 request and auto-decompress gzip.
|
||||||
// Some hosts send gzip even if you don't ask for it; see golang.org/issue/13298
|
// Some hosts send gzip even if you don't ask for it; see golang.org/issue/13298
|
||||||
func TestH12_AutoGzip(t *testing.T) {
|
func TestH12_AutoGzip(t *testing.T) {
|
||||||
|
|
@ -375,8 +378,8 @@ func TestH12_AutoGzip(t *testing.T) {
|
||||||
// Test304Responses verifies that 304s don't declare that they're
|
// Test304Responses verifies that 304s don't declare that they're
|
||||||
// chunking in their response headers and aren't allowed to produce
|
// chunking in their response headers and aren't allowed to produce
|
||||||
// output.
|
// output.
|
||||||
func Test304Responses_h1(t *testing.T) { test304Responses(t, false) }
|
func Test304Responses_h1(t *testing.T) { test304Responses(t, h1Mode) }
|
||||||
func Test304Responses_h2(t *testing.T) { test304Responses(t, true) }
|
func Test304Responses_h2(t *testing.T) { test304Responses(t, h2Mode) }
|
||||||
|
|
||||||
func test304Responses(t *testing.T, h2 bool) {
|
func test304Responses(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
|
||||||
|
|
@ -477,14 +477,27 @@ func TestServeFileFromCWD(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServeFileWithContentEncoding(t *testing.T) {
|
// Tests that ServeFile doesn't add a Content-Length if a Content-Encoding is
|
||||||
|
// specified.
|
||||||
|
func TestServeFileWithContentEncoding_h1(t *testing.T) { testServeFileWithContentEncoding(t, h1Mode) }
|
||||||
|
func TestServeFileWithContentEncoding_h2(t *testing.T) { testServeFileWithContentEncoding(t, h2Mode) }
|
||||||
|
func testServeFileWithContentEncoding(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
w.Header().Set("Content-Encoding", "foo")
|
w.Header().Set("Content-Encoding", "foo")
|
||||||
ServeFile(w, r, "testdata/file")
|
ServeFile(w, r, "testdata/file")
|
||||||
|
|
||||||
|
// Because the testdata is so small, it would fit in
|
||||||
|
// both the h1 and h2 Server's write buffers. For h1,
|
||||||
|
// sendfile is used, though, forcing a header flush at
|
||||||
|
// the io.Copy. http2 doesn't do a header flush so
|
||||||
|
// buffers all 11 bytes and then adds its own
|
||||||
|
// Content-Length. To prevent the Server's
|
||||||
|
// Content-Length and test ServeFile only, flush here.
|
||||||
|
w.(Flusher).Flush()
|
||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer cst.close()
|
||||||
resp, err := Get(ts.URL)
|
resp, err := cst.c.Get(cst.ts.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -176,9 +176,8 @@ func TestParseMultipartForm(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRedirect_h1(t *testing.T) { testRedirect(t, false) }
|
func TestRedirect_h1(t *testing.T) { testRedirect(t, h1Mode) }
|
||||||
func TestRedirect_h2(t *testing.T) { testRedirect(t, true) }
|
func TestRedirect_h2(t *testing.T) { testRedirect(t, h2Mode) }
|
||||||
|
|
||||||
func testRedirect(t *testing.T, h2 bool) {
|
func testRedirect(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
|
|
|
||||||
|
|
@ -735,8 +735,8 @@ func TestHandlersCanSetConnectionClose10(t *testing.T) {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetsRemoteAddr_h1(t *testing.T) { testSetsRemoteAddr(t, false) }
|
func TestSetsRemoteAddr_h1(t *testing.T) { testSetsRemoteAddr(t, h1Mode) }
|
||||||
func TestSetsRemoteAddr_h2(t *testing.T) { testSetsRemoteAddr(t, true) }
|
func TestSetsRemoteAddr_h2(t *testing.T) { testSetsRemoteAddr(t, h2Mode) }
|
||||||
|
|
||||||
func testSetsRemoteAddr(t *testing.T, h2 bool) {
|
func testSetsRemoteAddr(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
@ -890,8 +890,8 @@ func TestIdentityResponseHeaders(t *testing.T) {
|
||||||
|
|
||||||
// TestHeadResponses verifies that all MIME type sniffing and Content-Length
|
// TestHeadResponses verifies that all MIME type sniffing and Content-Length
|
||||||
// counting of GET requests also happens on HEAD requests.
|
// counting of GET requests also happens on HEAD requests.
|
||||||
func TestHeadResponses_h1(t *testing.T) { testHeadResponses(t, false) }
|
func TestHeadResponses_h1(t *testing.T) { testHeadResponses(t, h1Mode) }
|
||||||
func TestHeadResponses_h2(t *testing.T) { testHeadResponses(t, true) }
|
func TestHeadResponses_h2(t *testing.T) { testHeadResponses(t, h2Mode) }
|
||||||
|
|
||||||
func testHeadResponses(t *testing.T, h2 bool) {
|
func testHeadResponses(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
@ -1654,9 +1654,8 @@ func TestRequestBodyTimeoutClosesConnection(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeoutHandler_h1(t *testing.T) { testTimeoutHandler(t, false) }
|
func TestTimeoutHandler_h1(t *testing.T) { testTimeoutHandler(t, h1Mode) }
|
||||||
func TestTimeoutHandler_h2(t *testing.T) { testTimeoutHandler(t, true) }
|
func TestTimeoutHandler_h2(t *testing.T) { testTimeoutHandler(t, h2Mode) }
|
||||||
|
|
||||||
func testTimeoutHandler(t *testing.T, h2 bool) {
|
func testTimeoutHandler(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
sendHi := make(chan bool, 1)
|
sendHi := make(chan bool, 1)
|
||||||
|
|
@ -1826,10 +1825,10 @@ func TestRedirectBadPath(t *testing.T) {
|
||||||
// the previous request's body, which is not optimal for zero-lengthed bodies,
|
// the previous request's body, which is not optimal for zero-lengthed bodies,
|
||||||
// as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
|
// as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
|
||||||
func TestZeroLengthPostAndResponse_h1(t *testing.T) {
|
func TestZeroLengthPostAndResponse_h1(t *testing.T) {
|
||||||
testZeroLengthPostAndResponse(t, false)
|
testZeroLengthPostAndResponse(t, h1Mode)
|
||||||
}
|
}
|
||||||
func TestZeroLengthPostAndResponse_h2(t *testing.T) {
|
func TestZeroLengthPostAndResponse_h2(t *testing.T) {
|
||||||
testZeroLengthPostAndResponse(t, true)
|
testZeroLengthPostAndResponse(t, h2Mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testZeroLengthPostAndResponse(t *testing.T, h2 bool) {
|
func testZeroLengthPostAndResponse(t *testing.T, h2 bool) {
|
||||||
|
|
@ -1871,19 +1870,26 @@ func testZeroLengthPostAndResponse(t *testing.T, h2 bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlerPanicNil(t *testing.T) {
|
func TestHandlerPanicNil_h1(t *testing.T) { testHandlerPanic(t, false, h1Mode, nil) }
|
||||||
testHandlerPanic(t, false, nil)
|
func TestHandlerPanicNil_h2(t *testing.T) {
|
||||||
|
t.Skip("known failure; golang.org/issue/13555")
|
||||||
|
testHandlerPanic(t, false, h2Mode, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlerPanic(t *testing.T) {
|
func TestHandlerPanic_h1(t *testing.T) {
|
||||||
testHandlerPanic(t, false, "intentional death for testing")
|
testHandlerPanic(t, false, h1Mode, "intentional death for testing")
|
||||||
|
}
|
||||||
|
func TestHandlerPanic_h2(t *testing.T) {
|
||||||
|
t.Skip("known failure; golang.org/issue/13555")
|
||||||
|
testHandlerPanic(t, false, h2Mode, "intentional death for testing")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlerPanicWithHijack(t *testing.T) {
|
func TestHandlerPanicWithHijack(t *testing.T) {
|
||||||
testHandlerPanic(t, true, "intentional death for testing")
|
// Only testing HTTP/1, and our http2 server doesn't support hijacking.
|
||||||
|
testHandlerPanic(t, true, h1Mode, "intentional death for testing")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
|
func testHandlerPanic(t *testing.T, withHijack, h2 bool, panicValue interface{}) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
// Unlike the other tests that set the log output to ioutil.Discard
|
// Unlike the other tests that set the log output to ioutil.Discard
|
||||||
// to quiet the output, this test uses a pipe. The pipe serves three
|
// to quiet the output, this test uses a pipe. The pipe serves three
|
||||||
|
|
@ -1906,7 +1912,7 @@ func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
|
||||||
defer log.SetOutput(os.Stderr)
|
defer log.SetOutput(os.Stderr)
|
||||||
defer pw.Close()
|
defer pw.Close()
|
||||||
|
|
||||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
if withHijack {
|
if withHijack {
|
||||||
rwc, _, err := w.(Hijacker).Hijack()
|
rwc, _, err := w.(Hijacker).Hijack()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1916,7 +1922,7 @@ func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
|
||||||
}
|
}
|
||||||
panic(panicValue)
|
panic(panicValue)
|
||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer cst.close()
|
||||||
|
|
||||||
// Do a blocking read on the log output pipe so its logging
|
// Do a blocking read on the log output pipe so its logging
|
||||||
// doesn't bleed into the next test. But wait only 5 seconds
|
// doesn't bleed into the next test. But wait only 5 seconds
|
||||||
|
|
@ -1932,7 +1938,7 @@ func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
|
||||||
done <- true
|
done <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
_, err := Get(ts.URL)
|
_, err := cst.c.Get(cst.ts.URL)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Logf("expected an error")
|
t.Logf("expected an error")
|
||||||
}
|
}
|
||||||
|
|
@ -1949,17 +1955,19 @@ func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerNoDate(t *testing.T) { testServerNoHeader(t, "Date") }
|
func TestServerNoDate_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Date") }
|
||||||
func TestServerNoContentType(t *testing.T) { testServerNoHeader(t, "Content-Type") }
|
func TestServerNoDate_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Date") }
|
||||||
|
func TestServerNoContentType_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Content-Type") }
|
||||||
|
func TestServerNoContentType_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Content-Type") }
|
||||||
|
|
||||||
func testServerNoHeader(t *testing.T, header string) {
|
func testServerNoHeader(t *testing.T, h2 bool, header string) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
w.Header()[header] = nil
|
w.Header()[header] = nil
|
||||||
io.WriteString(w, "<html>foo</html>") // non-empty
|
io.WriteString(w, "<html>foo</html>") // non-empty
|
||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer cst.close()
|
||||||
res, err := Get(ts.URL)
|
res, err := cst.c.Get(cst.ts.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -1996,18 +2004,20 @@ func TestStripPrefix(t *testing.T) {
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRequestLimit(t *testing.T) {
|
func TestRequestLimit_h1(t *testing.T) { testRequestLimit(t, h1Mode) }
|
||||||
|
func TestRequestLimit_h2(t *testing.T) { testRequestLimit(t, h2Mode) }
|
||||||
|
func testRequestLimit(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
t.Fatalf("didn't expect to get request in Handler")
|
t.Fatalf("didn't expect to get request in Handler")
|
||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer cst.close()
|
||||||
req, _ := NewRequest("GET", ts.URL, nil)
|
req, _ := NewRequest("GET", cst.ts.URL, nil)
|
||||||
var bytesPerHeader = len("header12345: val12345\r\n")
|
var bytesPerHeader = len("header12345: val12345\r\n")
|
||||||
for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
|
for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
|
||||||
req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
|
req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
|
||||||
}
|
}
|
||||||
res, err := DefaultClient.Do(req)
|
res, err := cst.c.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Some HTTP clients may fail on this undefined behavior (server replying and
|
// Some HTTP clients may fail on this undefined behavior (server replying and
|
||||||
// closing the connection while the request is still being written), but
|
// closing the connection while the request is still being written), but
|
||||||
|
|
@ -2015,8 +2025,8 @@ func TestRequestLimit(t *testing.T) {
|
||||||
t.Fatalf("Do: %v", err)
|
t.Fatalf("Do: %v", err)
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
if res.StatusCode != 413 {
|
if res.StatusCode != 431 {
|
||||||
t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status)
|
t.Fatalf("expected 431 response status; got: %d %s", res.StatusCode, res.Status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2040,9 +2050,8 @@ func (cr countReader) Read(p []byte) (n int, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRequestBodyLimit_h1(t *testing.T) { testRequestBodyLimit(t, false) }
|
func TestRequestBodyLimit_h1(t *testing.T) { testRequestBodyLimit(t, h1Mode) }
|
||||||
func TestRequestBodyLimit_h2(t *testing.T) { testRequestBodyLimit(t, true) }
|
func TestRequestBodyLimit_h2(t *testing.T) { testRequestBodyLimit(t, h2Mode) }
|
||||||
|
|
||||||
func testRequestBodyLimit(t *testing.T, h2 bool) {
|
func testRequestBodyLimit(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
const limit = 1 << 20
|
const limit = 1 << 20
|
||||||
|
|
@ -2181,9 +2190,8 @@ func TestServerGracefulClose(t *testing.T) {
|
||||||
<-writeErr
|
<-writeErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCaseSensitiveMethod_h1(t *testing.T) { testCaseSensitiveMethod(t, false) }
|
func TestCaseSensitiveMethod_h1(t *testing.T) { testCaseSensitiveMethod(t, h1Mode) }
|
||||||
func TestCaseSensitiveMethod_h2(t *testing.T) { testCaseSensitiveMethod(t, true) }
|
func TestCaseSensitiveMethod_h2(t *testing.T) { testCaseSensitiveMethod(t, h2Mode) }
|
||||||
|
|
||||||
func testCaseSensitiveMethod(t *testing.T, h2 bool) {
|
func testCaseSensitiveMethod(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
|
|
@ -2692,11 +2700,13 @@ func TestHTTP10ConnectionHeader(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// See golang.org/issue/5660
|
// See golang.org/issue/5660
|
||||||
func TestServerReaderFromOrder(t *testing.T) {
|
func TestServerReaderFromOrder_h1(t *testing.T) { testServerReaderFromOrder(t, h1Mode) }
|
||||||
|
func TestServerReaderFromOrder_h2(t *testing.T) { testServerReaderFromOrder(t, h2Mode) }
|
||||||
|
func testServerReaderFromOrder(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
pr, pw := io.Pipe()
|
pr, pw := io.Pipe()
|
||||||
const size = 3 << 20
|
const size = 3 << 20
|
||||||
ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
|
||||||
rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path
|
rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path
|
||||||
done := make(chan bool)
|
done := make(chan bool)
|
||||||
go func() {
|
go func() {
|
||||||
|
|
@ -2716,13 +2726,13 @@ func TestServerReaderFromOrder(t *testing.T) {
|
||||||
pw.Close()
|
pw.Close()
|
||||||
<-done
|
<-done
|
||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer cst.close()
|
||||||
|
|
||||||
req, err := NewRequest("POST", ts.URL, io.LimitReader(neverEnding('a'), size))
|
req, err := NewRequest("POST", cst.ts.URL, io.LimitReader(neverEnding('a'), size))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
res, err := DefaultClient.Do(req)
|
res, err := cst.c.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -2790,24 +2800,34 @@ func TestContentTypeOkayOn204(t *testing.T) {
|
||||||
// proxy). So then two people own that Request.Body (both the server
|
// proxy). So then two people own that Request.Body (both the server
|
||||||
// and the http client), and both think they can close it on failure.
|
// and the http client), and both think they can close it on failure.
|
||||||
// Therefore, all incoming server requests Bodies need to be thread-safe.
|
// Therefore, all incoming server requests Bodies need to be thread-safe.
|
||||||
func TestTransportAndServerSharedBodyRace(t *testing.T) {
|
func TestTransportAndServerSharedBodyRace_h1(t *testing.T) {
|
||||||
|
testTransportAndServerSharedBodyRace(t, h1Mode)
|
||||||
|
}
|
||||||
|
func TestTransportAndServerSharedBodyRace_h2(t *testing.T) {
|
||||||
|
t.Skip("failing in http2 mode; golang.org/issue/13556")
|
||||||
|
testTransportAndServerSharedBodyRace(t, h2Mode)
|
||||||
|
}
|
||||||
|
func testTransportAndServerSharedBodyRace(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
||||||
const bodySize = 1 << 20
|
const bodySize = 1 << 20
|
||||||
|
|
||||||
unblockBackend := make(chan bool)
|
unblockBackend := make(chan bool)
|
||||||
backend := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
|
backend := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
|
||||||
io.CopyN(rw, req.Body, bodySize)
|
io.CopyN(rw, req.Body, bodySize)
|
||||||
<-unblockBackend
|
<-unblockBackend
|
||||||
}))
|
}))
|
||||||
defer backend.Close()
|
defer backend.close()
|
||||||
|
|
||||||
backendRespc := make(chan *Response, 1)
|
backendRespc := make(chan *Response, 1)
|
||||||
proxy := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
|
var proxy *clientServerTest
|
||||||
req2, _ := NewRequest("POST", backend.URL, req.Body)
|
proxy = newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
|
||||||
|
req2, _ := NewRequest("POST", backend.ts.URL, req.Body)
|
||||||
req2.ContentLength = bodySize
|
req2.ContentLength = bodySize
|
||||||
|
cancel := make(chan struct{})
|
||||||
|
req2.Cancel = cancel
|
||||||
|
|
||||||
bresp, err := DefaultClient.Do(req2)
|
bresp, err := proxy.c.Do(req2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Proxy outbound request: %v", err)
|
t.Errorf("Proxy outbound request: %v", err)
|
||||||
return
|
return
|
||||||
|
|
@ -2821,14 +2841,18 @@ func TestTransportAndServerSharedBodyRace(t *testing.T) {
|
||||||
|
|
||||||
// Try to cause a race: Both the DefaultTransport and the proxy handler's Server
|
// Try to cause a race: Both the DefaultTransport and the proxy handler's Server
|
||||||
// will try to read/close req.Body (aka req2.Body)
|
// will try to read/close req.Body (aka req2.Body)
|
||||||
DefaultTransport.(*Transport).CancelRequest(req2)
|
if h2 {
|
||||||
|
close(cancel)
|
||||||
|
} else {
|
||||||
|
proxy.c.Transport.(*Transport).CancelRequest(req2)
|
||||||
|
}
|
||||||
rw.Write([]byte("OK"))
|
rw.Write([]byte("OK"))
|
||||||
}))
|
}))
|
||||||
defer proxy.Close()
|
defer proxy.close()
|
||||||
|
|
||||||
defer close(unblockBackend)
|
defer close(unblockBackend)
|
||||||
req, _ := NewRequest("POST", proxy.URL, io.LimitReader(neverEnding('a'), bodySize))
|
req, _ := NewRequest("POST", proxy.ts.URL, io.LimitReader(neverEnding('a'), bodySize))
|
||||||
res, err := DefaultClient.Do(req)
|
res, err := proxy.c.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Original request: %v", err)
|
t.Fatalf("Original request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -2839,7 +2863,7 @@ func TestTransportAndServerSharedBodyRace(t *testing.T) {
|
||||||
case res := <-backendRespc:
|
case res := <-backendRespc:
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
default:
|
default:
|
||||||
// We failed earlier. (e.g. on DefaultClient.Do(req2))
|
// We failed earlier. (e.g. on proxy.c.Do(req2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3105,20 +3129,22 @@ func TestServerKeepAlivesEnabled(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// golang.org/issue/7856
|
// golang.org/issue/7856
|
||||||
func TestServerEmptyBodyRace(t *testing.T) {
|
func TestServerEmptyBodyRace_h1(t *testing.T) { testServerEmptyBodyRace(t, h1Mode) }
|
||||||
|
func TestServerEmptyBodyRace_h2(t *testing.T) { testServerEmptyBodyRace(t, h2Mode) }
|
||||||
|
func testServerEmptyBodyRace(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
var n int32
|
var n int32
|
||||||
ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
|
||||||
atomic.AddInt32(&n, 1)
|
atomic.AddInt32(&n, 1)
|
||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer cst.close()
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
const reqs = 20
|
const reqs = 20
|
||||||
for i := 0; i < reqs; i++ {
|
for i := 0; i < reqs; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
res, err := Get(ts.URL)
|
res, err := cst.c.Get(cst.ts.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
|
|
@ -3406,15 +3432,17 @@ func TestHandlerFinishSkipBigContentLengthRead(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlerSetsBodyNil(t *testing.T) {
|
func TestHandlerSetsBodyNil_h1(t *testing.T) { testHandlerSetsBodyNil(t, h1Mode) }
|
||||||
|
func TestHandlerSetsBodyNil_h2(t *testing.T) { testHandlerSetsBodyNil(t, h2Mode) }
|
||||||
|
func testHandlerSetsBodyNil(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
r.Body = nil
|
r.Body = nil
|
||||||
fmt.Fprintf(w, "%v", r.RemoteAddr)
|
fmt.Fprintf(w, "%v", r.RemoteAddr)
|
||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer cst.close()
|
||||||
get := func() string {
|
get := func() string {
|
||||||
res, err := Get(ts.URL)
|
res, err := cst.c.Get(cst.ts.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1341,7 +1341,7 @@ func (c *conn) serve() {
|
||||||
// responding to them and hanging up
|
// responding to them and hanging up
|
||||||
// while they're still writing their
|
// while they're still writing their
|
||||||
// request. Undefined behavior.
|
// request. Undefined behavior.
|
||||||
io.WriteString(c.rwc, "HTTP/1.1 413 Request Entity Too Large\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n413 Request Entity Too Large")
|
io.WriteString(c.rwc, "HTTP/1.1 431 Request Header Fields Too Large\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n431 Request Header Fields Too Large")
|
||||||
c.closeWriteAndWait()
|
c.closeWriteAndWait()
|
||||||
break
|
break
|
||||||
} else if err == io.EOF {
|
} else if err == io.EOF {
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ func TestDetectContentType(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerContentType_h1(t *testing.T) { testServerContentType(t, false) }
|
func TestServerContentType_h1(t *testing.T) { testServerContentType(t, h1Mode) }
|
||||||
func TestServerContentType_h2(t *testing.T) { testServerContentType(t, true) }
|
func TestServerContentType_h2(t *testing.T) { testServerContentType(t, h2Mode) }
|
||||||
|
|
||||||
func testServerContentType(t *testing.T, h2 bool) {
|
func testServerContentType(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
@ -87,9 +87,8 @@ func testServerContentType(t *testing.T, h2 bool) {
|
||||||
|
|
||||||
// Issue 5953: shouldn't sniff if the handler set a Content-Type header,
|
// Issue 5953: shouldn't sniff if the handler set a Content-Type header,
|
||||||
// even if it's the empty string.
|
// even if it's the empty string.
|
||||||
func TestServerIssue5953_h1(t *testing.T) { testServerIssue5953(t, false) }
|
func TestServerIssue5953_h1(t *testing.T) { testServerIssue5953(t, h1Mode) }
|
||||||
func TestServerIssue5953_h2(t *testing.T) { testServerIssue5953(t, true) }
|
func TestServerIssue5953_h2(t *testing.T) { testServerIssue5953(t, h2Mode) }
|
||||||
|
|
||||||
func testServerIssue5953(t *testing.T, h2 bool) {
|
func testServerIssue5953(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
|
|
@ -111,9 +110,8 @@ func testServerIssue5953(t *testing.T, h2 bool) {
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContentTypeWithCopy_h1(t *testing.T) { testContentTypeWithCopy(t, false) }
|
func TestContentTypeWithCopy_h1(t *testing.T) { testContentTypeWithCopy(t, h1Mode) }
|
||||||
func TestContentTypeWithCopy_h2(t *testing.T) { testContentTypeWithCopy(t, true) }
|
func TestContentTypeWithCopy_h2(t *testing.T) { testContentTypeWithCopy(t, h2Mode) }
|
||||||
|
|
||||||
func testContentTypeWithCopy(t *testing.T, h2 bool) {
|
func testContentTypeWithCopy(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
|
|
||||||
|
|
@ -148,9 +146,8 @@ func testContentTypeWithCopy(t *testing.T, h2 bool) {
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSniffWriteSize_h1(t *testing.T) { testSniffWriteSize(t, false) }
|
func TestSniffWriteSize_h1(t *testing.T) { testSniffWriteSize(t, h1Mode) }
|
||||||
func TestSniffWriteSize_h2(t *testing.T) { testSniffWriteSize(t, true) }
|
func TestSniffWriteSize_h2(t *testing.T) { testSniffWriteSize(t, h2Mode) }
|
||||||
|
|
||||||
func testSniffWriteSize(t *testing.T, h2 bool) {
|
func testSniffWriteSize(t *testing.T, h2 bool) {
|
||||||
defer afterTest(t)
|
defer afterTest(t)
|
||||||
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue