diff options
Diffstat (limited to 'src/net/http/client_test.go')
| -rw-r--r-- | src/net/http/client_test.go | 337 |
1 files changed, 134 insertions, 203 deletions
diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go index 44b532ae1f..8b53c41687 100644 --- a/src/net/http/client_test.go +++ b/src/net/http/client_test.go @@ -67,11 +67,9 @@ func (w chanWriter) Write(p []byte) (n int, err error) { return len(p), nil } -func TestClient(t *testing.T) { - setParallel(t) - defer afterTest(t) - ts := httptest.NewServer(robotsTxtHandler) - defer ts.Close() +func TestClient(t *testing.T) { run(t, testClient) } +func testClient(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, robotsTxtHandler).ts c := ts.Client() r, err := c.Get(ts.URL) @@ -87,14 +85,9 @@ func TestClient(t *testing.T) { } } -func TestClientHead_h1(t *testing.T) { testClientHead(t, h1Mode) } -func TestClientHead_h2(t *testing.T) { testClientHead(t, h2Mode) } - -func testClientHead(t *testing.T, h2 bool) { - defer afterTest(t) - cst := newClientServerTest(t, h2, robotsTxtHandler) - defer cst.close() - +func TestClientHead(t *testing.T) { run(t, testClientHead) } +func testClientHead(t *testing.T, mode testMode) { + cst := newClientServerTest(t, mode, robotsTxtHandler) r, err := cst.c.Head(cst.ts.URL) if err != nil { t.Fatal(err) @@ -200,11 +193,10 @@ func TestPostFormRequestFormat(t *testing.T) { } } -func TestClientRedirects(t *testing.T) { - setParallel(t) - defer afterTest(t) +func TestClientRedirects(t *testing.T) { run(t, testClientRedirects) } +func testClientRedirects(t *testing.T, mode testMode) { var ts *httptest.Server - ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts = newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { n, _ := strconv.Atoi(r.FormValue("n")) // Test Referer header. (7 is arbitrary position to test at) if n == 7 { @@ -217,8 +209,7 @@ func TestClientRedirects(t *testing.T) { return } fmt.Fprintf(w, "n=%d", n) - })) - defer ts.Close() + })).ts c := ts.Client() _, err := c.Get(ts.URL) @@ -299,13 +290,11 @@ func TestClientRedirects(t *testing.T) { } // Tests that Client redirects' contexts are derived from the original request's context. -func TestClientRedirectContext(t *testing.T) { - setParallel(t) - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { +func TestClientRedirectsContext(t *testing.T) { run(t, testClientRedirectsContext) } +func testClientRedirectsContext(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { Redirect(w, r, "/", StatusTemporaryRedirect) - })) - defer ts.Close() + })).ts ctx, cancel := context.WithCancel(context.Background()) c := ts.Client() @@ -373,7 +362,9 @@ func TestPostRedirects(t *testing.T) { `POST /?code=404 "c404"`, } want := strings.Join(wantSegments, "\n") - testRedirectsByMethod(t, "POST", postRedirectTests, want) + run(t, func(t *testing.T, mode testMode) { + testRedirectsByMethod(t, mode, "POST", postRedirectTests, want) + }) } func TestDeleteRedirects(t *testing.T) { @@ -410,17 +401,18 @@ func TestDeleteRedirects(t *testing.T) { `DELETE /?code=404 "c404"`, } want := strings.Join(wantSegments, "\n") - testRedirectsByMethod(t, "DELETE", deleteRedirectTests, want) + run(t, func(t *testing.T, mode testMode) { + testRedirectsByMethod(t, mode, "DELETE", deleteRedirectTests, want) + }) } -func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, want string) { - defer afterTest(t) +func testRedirectsByMethod(t *testing.T, mode testMode, method string, table []redirectTest, want string) { var log struct { sync.Mutex bytes.Buffer } var ts *httptest.Server - ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts = newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { log.Lock() slurp, _ := io.ReadAll(r.Body) fmt.Fprintf(&log.Buffer, "%s %s %q", r.Method, r.RequestURI, slurp) @@ -445,8 +437,7 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa } w.WriteHeader(code) } - })) - defer ts.Close() + })).ts c := ts.Client() for _, tt := range table { @@ -491,12 +482,11 @@ func removeCommonLines(a, b string) (asuffix, bsuffix string, commonLines int) { } } -func TestClientRedirectUseResponse(t *testing.T) { - setParallel(t) - defer afterTest(t) +func TestClientRedirectUseResponse(t *testing.T) { run(t, testClientRedirectUseResponse) } +func testClientRedirectUseResponse(t *testing.T, mode testMode) { const body = "Hello, world." var ts *httptest.Server - ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts = newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { if strings.Contains(r.URL.Path, "/other") { io.WriteString(w, "wrong body") } else { @@ -504,8 +494,7 @@ func TestClientRedirectUseResponse(t *testing.T) { w.WriteHeader(StatusFound) io.WriteString(w, body) } - })) - defer ts.Close() + })).ts c := ts.Client() c.CheckRedirect = func(req *Request, via []*Request) error { @@ -533,18 +522,16 @@ func TestClientRedirectUseResponse(t *testing.T) { // Issues 17773 and 49281: don't follow a 3xx if the response doesn't // have a Location header. -func TestClientRedirectNoLocation(t *testing.T) { +func TestClientRedirectNoLocation(t *testing.T) { run(t, testClientRedirectNoLocation) } +func testClientRedirectNoLocation(t *testing.T, mode testMode) { for _, code := range []int{301, 308} { t.Run(fmt.Sprint(code), func(t *testing.T) { setParallel(t) - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.Header().Set("Foo", "Bar") w.WriteHeader(code) })) - defer ts.Close() - c := ts.Client() - res, err := c.Get(ts.URL) + res, err := cst.c.Get(cst.ts.URL) if err != nil { t.Fatal(err) } @@ -560,15 +547,13 @@ func TestClientRedirectNoLocation(t *testing.T) { } // Don't follow a 307/308 if we can't resent the request body. -func TestClientRedirect308NoGetBody(t *testing.T) { - setParallel(t) - defer afterTest(t) +func TestClientRedirect308NoGetBody(t *testing.T) { run(t, testClientRedirect308NoGetBody) } +func testClientRedirect308NoGetBody(t *testing.T, mode testMode) { const fakeURL = "https://localhost:1234/" // won't be hit - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.Header().Set("Location", fakeURL) w.WriteHeader(308) - })) - defer ts.Close() + })).ts req, err := NewRequest("POST", ts.URL, strings.NewReader("some body")) if err != nil { t.Fatal(err) @@ -659,12 +644,10 @@ func (j *TestJar) Cookies(u *url.URL) []*Cookie { return j.perURL[u.Host] } -func TestRedirectCookiesJar(t *testing.T) { - setParallel(t) - defer afterTest(t) +func TestRedirectCookiesJar(t *testing.T) { run(t, testRedirectCookiesJar) } +func testRedirectCookiesJar(t *testing.T, mode testMode) { var ts *httptest.Server - ts = httptest.NewServer(echoCookiesRedirectHandler) - defer ts.Close() + ts = newClientServerTest(t, mode, echoCookiesRedirectHandler).ts c := ts.Client() c.Jar = new(TestJar) u, _ := url.Parse(ts.URL) @@ -696,9 +679,9 @@ func matchReturnedCookies(t *testing.T, expected, given []*Cookie) { } } -func TestJarCalls(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { +func TestJarCalls(t *testing.T) { run(t, testJarCalls, []testMode{http1Mode}) } +func testJarCalls(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { pathSuffix := r.RequestURI[1:] if r.RequestURI == "/nosetcookie" { return // don't set cookies for this path @@ -707,8 +690,7 @@ func TestJarCalls(t *testing.T) { if r.RequestURI == "/" { Redirect(w, r, "http://secondhost.fake/secondpath", 302) } - })) - defer ts.Close() + })).ts jar := new(RecordingJar) c := ts.Client() c.Jar = jar @@ -757,20 +739,16 @@ func (j *RecordingJar) logf(format string, args ...any) { fmt.Fprintf(&j.log, format, args...) } -func TestStreamingGet_h1(t *testing.T) { testStreamingGet(t, h1Mode) } -func TestStreamingGet_h2(t *testing.T) { testStreamingGet(t, h2Mode) } - -func testStreamingGet(t *testing.T, h2 bool) { - defer afterTest(t) +func TestStreamingGet(t *testing.T) { run(t, testStreamingGet) } +func testStreamingGet(t *testing.T, mode testMode) { say := make(chan string) - cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.(Flusher).Flush() for str := range say { w.Write([]byte(str)) w.(Flusher).Flush() } })) - defer cst.close() c := cst.c res, err := c.Get(cst.ts.URL) @@ -811,11 +789,10 @@ func (c *writeCountingConn) Write(p []byte) (int, error) { // TestClientWrites verifies that client requests are buffered and we // don't send a TCP packet per line of the http request + body. -func TestClientWrites(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { - })) - defer ts.Close() +func TestClientWrites(t *testing.T) { run(t, testClientWrites, []testMode{http1Mode}) } +func testClientWrites(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { + })).ts writes := 0 dialer := func(netz string, addr string) (net.Conn, error) { @@ -847,11 +824,12 @@ func TestClientWrites(t *testing.T) { } func TestClientInsecureTransport(t *testing.T) { - setParallel(t) - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { + run(t, testClientInsecureTransport, []testMode{https1Mode, http2Mode}) +} +func testClientInsecureTransport(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.Write([]byte("Hello")) - })) + })).ts errc := make(chanWriter, 10) // but only expecting 1 ts.Config.ErrorLog = log.New(errc, "", 0) defer ts.Close() @@ -898,15 +876,15 @@ func TestClientErrorWithRequestURI(t *testing.T) { } func TestClientWithCorrectTLSServerName(t *testing.T) { - defer afterTest(t) - + run(t, testClientWithCorrectTLSServerName, []testMode{https1Mode, http2Mode}) +} +func testClientWithCorrectTLSServerName(t *testing.T, mode testMode) { const serverName = "example.com" - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { if r.TLS.ServerName != serverName { t.Errorf("expected client to set ServerName %q, got: %q", serverName, r.TLS.ServerName) } - })) - defer ts.Close() + })).ts c := ts.Client() c.Transport.(*Transport).TLSClientConfig.ServerName = serverName @@ -916,9 +894,10 @@ func TestClientWithCorrectTLSServerName(t *testing.T) { } func TestClientWithIncorrectTLSServerName(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) - defer ts.Close() + run(t, testClientWithIncorrectTLSServerName, []testMode{https1Mode, http2Mode}) +} +func testClientWithIncorrectTLSServerName(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {})).ts errc := make(chanWriter, 10) // but only expecting 1 ts.Config.ErrorLog = log.New(errc, "", 0) @@ -951,11 +930,12 @@ func TestClientWithIncorrectTLSServerName(t *testing.T) { // // The httptest.Server has a cert with "example.com" as its name. func TestTransportUsesTLSConfigServerName(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { + run(t, testTransportUsesTLSConfigServerName, []testMode{https1Mode, http2Mode}) +} +func testTransportUsesTLSConfigServerName(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.Write([]byte("Hello")) - })) - defer ts.Close() + })).ts c := ts.Client() tr := c.Transport.(*Transport) @@ -971,11 +951,12 @@ func TestTransportUsesTLSConfigServerName(t *testing.T) { } func TestResponseSetsTLSConnectionState(t *testing.T) { - defer afterTest(t) - ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { + run(t, testResponseSetsTLSConnectionState, []testMode{https1Mode}) +} +func testResponseSetsTLSConnectionState(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.Write([]byte("Hello")) - })) - defer ts.Close() + })).ts c := ts.Client() tr := c.Transport.(*Transport) @@ -1001,10 +982,11 @@ func TestResponseSetsTLSConnectionState(t *testing.T) { // to determine that the server is speaking HTTP. // See golang.org/issue/11111. func TestHTTPSClientDetectsHTTPServer(t *testing.T) { - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) + run(t, testHTTPSClientDetectsHTTPServer, []testMode{http1Mode}) +} +func testHTTPSClientDetectsHTTPServer(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {})).ts ts.Config.ErrorLog = quietLog - defer ts.Close() _, err := Get(strings.Replace(ts.URL, "http", "https", 1)) if got := err.Error(); !strings.Contains(got, "HTTP response to HTTPS client") { @@ -1013,22 +995,13 @@ func TestHTTPSClientDetectsHTTPServer(t *testing.T) { } // Verify Response.ContentLength is populated. https://golang.org/issue/4126 -func TestClientHeadContentLength_h1(t *testing.T) { - testClientHeadContentLength(t, h1Mode) -} - -func TestClientHeadContentLength_h2(t *testing.T) { - testClientHeadContentLength(t, h2Mode) -} - -func testClientHeadContentLength(t *testing.T, h2 bool) { - defer afterTest(t) - cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { +func TestClientHeadContentLength(t *testing.T) { run(t, testClientHeadContentLength) } +func testClientHeadContentLength(t *testing.T, mode testMode) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { if v := r.FormValue("cl"); v != "" { w.Header().Set("Content-Length", v) } })) - defer cst.close() tests := []struct { suffix string want int64 @@ -1056,11 +1029,10 @@ func testClientHeadContentLength(t *testing.T, h2 bool) { } } -func TestEmptyPasswordAuth(t *testing.T) { - setParallel(t) - defer afterTest(t) +func TestEmptyPasswordAuth(t *testing.T) { run(t, testEmptyPasswordAuth) } +func testEmptyPasswordAuth(t *testing.T, mode testMode) { gopher := "gopher" - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { auth := r.Header.Get("Authorization") if strings.HasPrefix(auth, "Basic ") { encoded := auth[6:] @@ -1076,7 +1048,7 @@ func TestEmptyPasswordAuth(t *testing.T) { } else { t.Errorf("Invalid auth %q", auth) } - })) + })).ts defer ts.Close() req, err := NewRequest("GET", ts.URL, nil) if err != nil { @@ -1205,19 +1177,14 @@ func TestStripPasswordFromError(t *testing.T) { } } -func TestClientTimeout_h1(t *testing.T) { testClientTimeout(t, h1Mode) } -func TestClientTimeout_h2(t *testing.T) { testClientTimeout(t, h2Mode) } - -func testClientTimeout(t *testing.T, h2 bool) { - setParallel(t) - defer afterTest(t) - +func TestClientTimeout(t *testing.T) { run(t, testClientTimeout) } +func testClientTimeout(t *testing.T, mode testMode) { var ( mu sync.Mutex nonce string // a unique per-request string sawSlowNonce bool // true if the handler saw /slow?nonce=<nonce> ) - cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { _ = r.ParseForm() if r.URL.Path == "/" { Redirect(w, r, "/slow?nonce="+r.Form.Get("nonce"), StatusFound) @@ -1238,7 +1205,6 @@ func testClientTimeout(t *testing.T, h2 bool) { return } })) - defer cst.close() // Try to trigger a timeout after reading part of the response body. // The initial timeout is emprically usually long enough on a decently fast @@ -1308,18 +1274,13 @@ func testClientTimeout(t *testing.T, h2 bool) { } } -func TestClientTimeout_Headers_h1(t *testing.T) { testClientTimeout_Headers(t, h1Mode) } -func TestClientTimeout_Headers_h2(t *testing.T) { testClientTimeout_Headers(t, h2Mode) } - // Client.Timeout firing before getting to the body -func testClientTimeout_Headers(t *testing.T, h2 bool) { - setParallel(t) - defer afterTest(t) +func TestClientTimeout_Headers(t *testing.T) { run(t, testClientTimeout_Headers) } +func testClientTimeout_Headers(t *testing.T, mode testMode) { donec := make(chan bool, 1) - cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { <-donec }), optQuietLog) - defer cst.close() // Note that we use a channel send here and not a close. // The race detector doesn't know that we're waiting for a timeout // and thinks that the waitgroup inside httptest.Server is added to concurrently @@ -1355,18 +1316,15 @@ func testClientTimeout_Headers(t *testing.T, h2 bool) { // Issue 16094: if Client.Timeout is set but not hit, a Timeout error shouldn't be // returned. -func TestClientTimeoutCancel(t *testing.T) { - setParallel(t) - defer afterTest(t) - +func TestClientTimeoutCancel(t *testing.T) { run(t, testClientTimeoutCancel) } +func testClientTimeoutCancel(t *testing.T, mode testMode) { testDone := make(chan struct{}) ctx, cancel := context.WithCancel(context.Background()) - cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.(Flusher).Flush() <-testDone })) - defer cst.close() defer close(testDone) cst.c.Timeout = 1 * time.Hour @@ -1383,18 +1341,12 @@ func TestClientTimeoutCancel(t *testing.T) { } } -func TestClientTimeoutDoesNotExpire_h1(t *testing.T) { testClientTimeoutDoesNotExpire(t, h1Mode) } -func TestClientTimeoutDoesNotExpire_h2(t *testing.T) { testClientTimeoutDoesNotExpire(t, h2Mode) } - // Issue 49366: if Client.Timeout is set but not hit, no error should be returned. -func testClientTimeoutDoesNotExpire(t *testing.T, h2 bool) { - setParallel(t) - defer afterTest(t) - - cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { +func TestClientTimeoutDoesNotExpire(t *testing.T) { run(t, testClientTimeoutDoesNotExpire) } +func testClientTimeoutDoesNotExpire(t *testing.T, mode testMode) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.Write([]byte("body")) })) - defer cst.close() cst.c.Timeout = 1 * time.Hour req, _ := NewRequest("GET", cst.ts.URL, nil) @@ -1410,19 +1362,15 @@ func testClientTimeoutDoesNotExpire(t *testing.T, h2 bool) { } } -func TestClientRedirectEatsBody_h1(t *testing.T) { testClientRedirectEatsBody(t, h1Mode) } -func TestClientRedirectEatsBody_h2(t *testing.T) { testClientRedirectEatsBody(t, h2Mode) } -func testClientRedirectEatsBody(t *testing.T, h2 bool) { - setParallel(t) - defer afterTest(t) +func TestClientRedirectEatsBody_h1(t *testing.T) { run(t, testClientRedirectEatsBody) } +func testClientRedirectEatsBody(t *testing.T, mode testMode) { saw := make(chan string, 2) - cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { saw <- r.RemoteAddr if r.URL.Path == "/" { Redirect(w, r, "/foo", StatusFound) // which includes a body } })) - defer cst.close() res, err := cst.c.Get(cst.ts.URL) if err != nil { @@ -1522,13 +1470,14 @@ func TestClientRedirectResponseWithoutRequest(t *testing.T) { } // Issue 4800: copy (some) headers when Client follows a redirect. -func TestClientCopyHeadersOnRedirect(t *testing.T) { +func TestClientCopyHeadersOnRedirect(t *testing.T) { run(t, testClientCopyHeadersOnRedirect) } +func testClientCopyHeadersOnRedirect(t *testing.T, mode testMode) { const ( ua = "some-agent/1.2" xfoo = "foo-val" ) var ts2URL string - ts1 := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts1 := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { want := Header{ "User-Agent": []string{ua}, "X-Foo": []string{xfoo}, @@ -1543,12 +1492,10 @@ func TestClientCopyHeadersOnRedirect(t *testing.T) { } else { w.Header().Set("Result", "ok") } - })) - defer ts1.Close() - ts2 := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + })).ts + ts2 := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { Redirect(w, r, ts1.URL, StatusFound) - })) - defer ts2.Close() + })).ts ts2URL = ts2.URL c := ts1.Client() @@ -1583,22 +1530,24 @@ func TestClientCopyHeadersOnRedirect(t *testing.T) { } // Issue 22233: copy host when Client follows a relative redirect. -func TestClientCopyHostOnRedirect(t *testing.T) { +func TestClientCopyHostOnRedirect(t *testing.T) { run(t, testClientCopyHostOnRedirect) } +func testClientCopyHostOnRedirect(t *testing.T, mode testMode) { // Virtual hostname: should not receive any request. - virtual := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + virtual := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { t.Errorf("Virtual host received request %v", r.URL) w.WriteHeader(403) io.WriteString(w, "should not see this response") - })) + })).ts defer virtual.Close() virtualHost := strings.TrimPrefix(virtual.URL, "http://") + virtualHost = strings.TrimPrefix(virtualHost, "https://") t.Logf("Virtual host is %v", virtualHost) // Actual hostname: should not receive any request. const wantBody = "response body" var tsURL string var tsHost string - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { switch r.URL.Path { case "/": // Relative redirect. @@ -1630,10 +1579,10 @@ func TestClientCopyHostOnRedirect(t *testing.T) { t.Errorf("Serving unexpected path %q", r.URL.Path) w.WriteHeader(404) } - })) - defer ts.Close() + })).ts tsURL = ts.URL tsHost = strings.TrimPrefix(ts.URL, "http://") + tsHost = strings.TrimPrefix(tsHost, "https://") t.Logf("Server host is %v", tsHost) c := ts.Client() @@ -1653,7 +1602,8 @@ func TestClientCopyHostOnRedirect(t *testing.T) { } // Issue 17494: cookies should be altered when Client follows redirects. -func TestClientAltersCookiesOnRedirect(t *testing.T) { +func TestClientAltersCookiesOnRedirect(t *testing.T) { run(t, testClientAltersCookiesOnRedirect) } +func testClientAltersCookiesOnRedirect(t *testing.T, mode testMode) { cookieMap := func(cs []*Cookie) map[string][]string { m := make(map[string][]string) for _, c := range cs { @@ -1662,7 +1612,7 @@ func TestClientAltersCookiesOnRedirect(t *testing.T) { return m } - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { var want map[string][]string got := cookieMap(r.Cookies()) @@ -1717,8 +1667,7 @@ func TestClientAltersCookiesOnRedirect(t *testing.T) { if !reflect.DeepEqual(got, want) { t.Errorf("redirect %s, Cookie = %v, want %v", c.Value, got, want) } - })) - defer ts.Close() + })).ts jar, _ := cookiejar.New(nil) c := ts.Client() @@ -1790,10 +1739,8 @@ func TestShouldCopyHeaderOnRedirect(t *testing.T) { } } -func TestClientRedirectTypes(t *testing.T) { - setParallel(t) - defer afterTest(t) - +func TestClientRedirectTypes(t *testing.T) { run(t, testClientRedirectTypes) } +func testClientRedirectTypes(t *testing.T, mode testMode) { tests := [...]struct { method string serverStatus int @@ -1838,11 +1785,10 @@ func TestClientRedirectTypes(t *testing.T) { handlerc := make(chan HandlerFunc, 1) - ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) { + ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) { h := <-handlerc h(rw, req) - })) - defer ts.Close() + })).ts c := ts.Client() for i, tt := range tests { @@ -1898,18 +1844,16 @@ func (b issue18239Body) Close() error { // Issue 18239: make sure the Transport doesn't retry requests with bodies // if Request.GetBody is not defined. -func TestTransportBodyReadError(t *testing.T) { - setParallel(t) - defer afterTest(t) - ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { +func TestTransportBodyReadError(t *testing.T) { run(t, testTransportBodyReadError) } +func testTransportBodyReadError(t *testing.T, mode testMode) { + ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { if r.URL.Path == "/ping" { return } buf := make([]byte, 1) n, err := r.Body.Read(buf) w.Header().Set("X-Body-Read", fmt.Sprintf("%v, %v", n, err)) - })) - defer ts.Close() + })).ts c := ts.Client() tr := c.Transport.(*Transport) @@ -1993,22 +1937,13 @@ func TestClientPropagatesTimeoutToContext(t *testing.T) { c.Get("https://example.tld/") } -func TestClientDoCanceledVsTimeout_h1(t *testing.T) { - testClientDoCanceledVsTimeout(t, h1Mode) -} - -func TestClientDoCanceledVsTimeout_h2(t *testing.T) { - testClientDoCanceledVsTimeout(t, h2Mode) -} - // Issue 33545: lock-in the behavior promised by Client.Do's // docs about request cancellation vs timing out. -func testClientDoCanceledVsTimeout(t *testing.T, h2 bool) { - defer afterTest(t) - cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { +func TestClientDoCanceledVsTimeout(t *testing.T) { run(t, testClientDoCanceledVsTimeout) } +func testClientDoCanceledVsTimeout(t *testing.T, mode testMode) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.Write([]byte("Hello, World!")) })) - defer cst.close() cases := []string{"timeout", "canceled"} @@ -2084,13 +2019,11 @@ func TestClientPopulatesNilResponseBody(t *testing.T) { } // Issue 40382: Client calls Close multiple times on Request.Body. -func TestClientCallsCloseOnlyOnce(t *testing.T) { - setParallel(t) - defer afterTest(t) - cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) { +func TestClientCallsCloseOnlyOnce(t *testing.T) { run(t, testClientCallsCloseOnlyOnce) } +func testClientCallsCloseOnlyOnce(t *testing.T, mode testMode) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { w.WriteHeader(StatusNoContent) })) - defer cst.close() // Issue occurred non-deterministically: needed to occur after a successful // write (into TCP buffer) but before end of body. @@ -2140,17 +2073,15 @@ func (b *issue40382Body) Close() error { return nil } -func TestProbeZeroLengthBody(t *testing.T) { - setParallel(t) - defer afterTest(t) +func TestProbeZeroLengthBody(t *testing.T) { run(t, testProbeZeroLengthBody) } +func testProbeZeroLengthBody(t *testing.T, mode testMode) { reqc := make(chan struct{}) - cst := newClientServerTest(t, false, HandlerFunc(func(w ResponseWriter, r *Request) { + cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) { close(reqc) if _, err := io.Copy(w, r.Body); err != nil { t.Errorf("error copying request body: %v", err) } })) - defer cst.close() bodyr, bodyw := io.Pipe() var gotBody string |
