"bytes"
"context"
"crypto/tls"
- "crypto/x509"
"encoding/base64"
"errors"
"fmt"
ts := httptest.NewServer(robotsTxtHandler)
defer ts.Close()
- c := &Client{Transport: &Transport{DisableKeepAlives: true}}
+ c := ts.Client()
r, err := c.Get(ts.URL)
var b []byte
if err == nil {
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
-
- c := &Client{Transport: tr}
+ c := ts.Client()
_, err := c.Get(ts.URL)
if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
t.Errorf("with default client Get, expected error %q, got %q", e, g)
var checkErr error
var lastVia []*Request
var lastReq *Request
- c = &Client{
- Transport: tr,
- CheckRedirect: func(req *Request, via []*Request) error {
- lastReq = req
- lastVia = via
- return checkErr
- },
+ c.CheckRedirect = func(req *Request, via []*Request) error {
+ lastReq = req
+ lastVia = via
+ return checkErr
}
res, err := c.Get(ts.URL)
if err != nil {
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
-
ctx, cancel := context.WithCancel(context.Background())
- c := &Client{
- Transport: tr,
- CheckRedirect: func(req *Request, via []*Request) error {
- cancel()
- select {
- case <-req.Context().Done():
- return nil
- case <-time.After(5 * time.Second):
- return errors.New("redirected request's context never expired after root request canceled")
- }
- },
+ c := ts.Client()
+ c.CheckRedirect = func(req *Request, via []*Request) error {
+ cancel()
+ select {
+ case <-req.Context().Done():
+ return nil
+ case <-time.After(5 * time.Second):
+ return errors.New("redirected request's context never expired after root request canceled")
+ }
}
req, _ := NewRequest("GET", ts.URL, nil)
req = req.WithContext(ctx)
}))
defer ts.Close()
+ c := ts.Client()
for _, tt := range table {
content := tt.redirectBody
req, _ := NewRequest(method, ts.URL+tt.suffix, strings.NewReader(content))
req.GetBody = func() (io.ReadCloser, error) { return ioutil.NopCloser(strings.NewReader(content)), nil }
- res, err := DefaultClient.Do(req)
+ res, err := c.Do(req)
if err != nil {
t.Fatal(err)
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
-
- c := &Client{
- Transport: tr,
- CheckRedirect: func(req *Request, via []*Request) error {
- if req.Response == nil {
- t.Error("expected non-nil Request.Response")
- }
- return ErrUseLastResponse
- },
+ c := ts.Client()
+ c.CheckRedirect = func(req *Request, via []*Request) error {
+ if req.Response == nil {
+ t.Error("expected non-nil Request.Response")
+ }
+ return ErrUseLastResponse
}
res, err := c.Get(ts.URL)
if err != nil {
w.WriteHeader(308)
}))
defer ts.Close()
- c := &Client{Transport: &Transport{DisableKeepAlives: true}}
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
t.Fatal(err)
if err != nil {
t.Fatal(err)
}
- c := &Client{Transport: &Transport{DisableKeepAlives: true}}
+ c := ts.Client()
req.GetBody = nil // so it can't rewind.
res, err := c.Do(req)
if err != nil {
var ts *httptest.Server
ts = httptest.NewServer(echoCookiesRedirectHandler)
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{
- Transport: tr,
- Jar: new(TestJar),
- }
+ c := ts.Client()
+ c.Jar = new(TestJar)
u, _ := url.Parse(ts.URL)
c.Jar.SetCookies(u, []*Cookie{expectedCookies[0]})
resp, err := c.Get(ts.URL)
}))
defer ts.Close()
jar := new(RecordingJar)
- c := &Client{
- Jar: jar,
- Transport: &Transport{
- Dial: func(_ string, _ string) (net.Conn, error) {
- return net.Dial("tcp", ts.Listener.Addr().String())
- },
- },
+ c := ts.Client()
+ c.Jar = jar
+ c.Transport.(*Transport).Dial = func(_ string, _ string) (net.Conn, error) {
+ return net.Dial("tcp", ts.Listener.Addr().String())
}
_, err := c.Get("http://firsthost.fake/")
if err != nil {
}
return c, err
}
- c := &Client{Transport: &Transport{Dial: dialer}}
+ c := ts.Client()
+ c.Transport.(*Transport).Dial = dialer
_, err := c.Get(ts.URL)
if err != nil {
// TODO(bradfitz): add tests for skipping hostname checks too?
// would require a new cert for testing, and probably
// redundant with these tests.
+ c := ts.Client()
for _, insecure := range []bool{true, false} {
- tr := &Transport{
- TLSClientConfig: &tls.Config{
- InsecureSkipVerify: insecure,
- },
+ c.Transport.(*Transport).TLSClientConfig = &tls.Config{
+ InsecureSkipVerify: insecure,
}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
res, err := c.Get(ts.URL)
if (err == nil) != insecure {
t.Errorf("insecure=%v: got unexpected err=%v", insecure, err)
}
}
-func newTLSTransport(t *testing.T, ts *httptest.Server) *Transport {
- certs := x509.NewCertPool()
- for _, c := range ts.TLS.Certificates {
- roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
- if err != nil {
- t.Fatalf("error parsing server's root cert: %v", err)
- }
- for _, root := range roots {
- certs.AddCert(root)
- }
- }
- return &Transport{
- TLSClientConfig: &tls.Config{RootCAs: certs},
- }
-}
-
func TestClientWithCorrectTLSServerName(t *testing.T) {
defer afterTest(t)
}))
defer ts.Close()
- trans := newTLSTransport(t, ts)
- trans.TLSClientConfig.ServerName = serverName
- c := &Client{Transport: trans}
+ c := ts.Client()
+ c.Transport.(*Transport).TLSClientConfig.ServerName = serverName
if _, err := c.Get(ts.URL); err != nil {
t.Fatalf("expected successful TLS connection, got error: %v", err)
}
errc := make(chanWriter, 10) // but only expecting 1
ts.Config.ErrorLog = log.New(errc, "", 0)
- trans := newTLSTransport(t, ts)
- trans.TLSClientConfig.ServerName = "badserver"
- c := &Client{Transport: trans}
+ c := ts.Client()
+ c.Transport.(*Transport).TLSClientConfig.ServerName = "badserver"
_, err := c.Get(ts.URL)
if err == nil {
t.Fatalf("expected an error")
}))
defer ts.Close()
- tr := newTLSTransport(t, ts)
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
tr.TLSClientConfig.ServerName = "example.com" // one of httptest's Server cert names
tr.Dial = func(netw, addr string) (net.Conn, error) {
return net.Dial(netw, ts.Listener.Addr().String())
}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
res, err := c.Get("https://some-other-host.tld/")
if err != nil {
t.Fatal(err)
}))
defer ts.Close()
- tr := newTLSTransport(t, ts)
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
tr.TLSClientConfig.CipherSuites = []uint16{tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA}
tr.Dial = func(netw, addr string) (net.Conn, error) {
return net.Dial(netw, ts.Listener.Addr().String())
}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
res, err := c.Get("https://example.com/")
if err != nil {
t.Fatal(err)
}
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
req, err := NewRequest("GET", ts.URL, nil)
if err != nil {
t.Fatal(err)
}
req.URL.User = url.User(gopher)
+ c := ts.Client()
resp, err := c.Do(req)
if err != nil {
t.Fatal(err)
defer ts2.Close()
ts2URL = ts2.URL
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{
- Transport: tr,
- CheckRedirect: func(r *Request, via []*Request) error {
- want := Header{
- "User-Agent": []string{ua},
- "X-Foo": []string{xfoo},
- "Referer": []string{ts2URL},
- }
- if !reflect.DeepEqual(r.Header, want) {
- t.Errorf("CheckRedirect Request.Header = %#v; want %#v", r.Header, want)
- }
- return nil
- },
+ c := ts1.Client()
+ c.CheckRedirect = func(r *Request, via []*Request) error {
+ want := Header{
+ "User-Agent": []string{ua},
+ "X-Foo": []string{xfoo},
+ "Referer": []string{ts2URL},
+ }
+ if !reflect.DeepEqual(r.Header, want) {
+ t.Errorf("CheckRedirect Request.Header = %#v; want %#v", r.Header, want)
+ }
+ return nil
}
req, _ := NewRequest("GET", ts2.URL, nil)
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
jar, _ := cookiejar.New(nil)
- c := &Client{
- Transport: tr,
- Jar: jar,
- }
+ c := ts.Client()
+ c.Jar = jar
u, _ := url.Parse(ts.URL)
req, _ := NewRequest("GET", ts.URL, nil)
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
-
+ c := ts.Client()
for i, tt := range tests {
handlerc <- func(w ResponseWriter, r *Request) {
w.Header().Set("Location", ts.URL)
continue
}
- c := &Client{Transport: tr}
c.CheckRedirect = func(req *Request, via []*Request) error {
if got, want := req.Method, tt.wantMethod; got != want {
return fmt.Errorf("#%d: got next method %q; want %q", i, got, want)
w.Header().Set("X-Body-Read", fmt.Sprintf("%v, %v", n, err))
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
// Do one initial successful request to create an idle TCP connection
// for the subsequent request to reuse. (The Transport only retries
ServeFile(w, r, "testdata/file")
}))
defer ts.Close()
+ c := ts.Client()
var err error
req.Method = "GET"
// straight GET
- _, body := getBody(t, "straight get", req)
+ _, body := getBody(t, "straight get", req, c)
if !bytes.Equal(body, file) {
t.Fatalf("body mismatch: got %q, want %q", body, file)
}
if rt.r != "" {
req.Header.Set("Range", rt.r)
}
- resp, body := getBody(t, fmt.Sprintf("range test %q", rt.r), req)
+ resp, body := getBody(t, fmt.Sprintf("range test %q", rt.r), req, c)
if resp.StatusCode != rt.code {
t.Errorf("range=%q: StatusCode=%d, want %d", rt.r, resp.StatusCode, rt.code)
}
req, _ := NewRequest("GET", ts.URL, nil)
req.Header.Set("If-Modified-Since", lastMod)
- res, err = DefaultClient.Do(req)
+ c := ts.Client()
+ res, err = c.Do(req)
if err != nil {
t.Fatal(err)
}
// Advance the index.html file's modtime, but not the directory's.
indexFile.modtime = indexFile.modtime.Add(1 * time.Hour)
- res, err = DefaultClient.Do(req)
+ res, err = c.Do(req)
if err != nil {
t.Fatal(err)
}
for k, v := range tt.reqHeader {
req.Header.Set(k, v)
}
- res, err := DefaultClient.Do(req)
+
+ c := ts.Client()
+ res, err := c.Do(req)
if err != nil {
t.Fatal(err)
}
}
ts := httptest.NewServer(FileServer(fs))
defer ts.Close()
+ c := ts.Client()
for _, code := range []int{403, 404, 500} {
- res, err := DefaultClient.Get(fmt.Sprintf("%s/%d", ts.URL, code))
+ res, err := c.Get(fmt.Sprintf("%s/%d", ts.URL, code))
if err != nil {
t.Errorf("Error fetching /%d: %v", code, err)
continue
}
}
-func getBody(t *testing.T, testName string, req Request) (*Response, []byte) {
- r, err := DefaultClient.Do(&req)
+func getBody(t *testing.T, testName string, req Request, client *Client) (*Response, []byte) {
+ r, err := client.Do(&req)
if err != nil {
t.Fatalf("%s: for URL %q, send error: %v", testName, req.URL.String(), err)
}
return &Server{
Listener: newLocalListener(),
Config: &http.Server{Handler: handler},
- client: &http.Client{},
+ client: &http.Client{
+ Transport: &http.Transport{},
+ },
}
}
t.Errorf("got %q, want hello", string(got))
}
}
+
+// Tests that the Server.Client.Transport interface is implemented
+// by a *http.Transport.
+func TestServerClientTransportType(t *testing.T) {
+ ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ }))
+ defer ts.Close()
+ client := ts.Client()
+ if _, ok := client.Transport.(*http.Transport); !ok {
+ t.Errorf("got %T, want *http.Transport", client.Transport)
+ }
+}
+
+// Tests that the TLS Server.Client.Transport interface is implemented
+// by a *http.Transport.
+func TestTLSServerClientTransportType(t *testing.T) {
+ ts := NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ }))
+ defer ts.Close()
+ client := ts.Client()
+ if _, ok := client.Transport.(*http.Transport); !ok {
+ t.Errorf("got %T, want *http.Transport", client.Transport)
+ }
+}
proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
frontend := httptest.NewServer(proxyHandler)
defer frontend.Close()
+ frontendClient := frontend.Client()
getReq, _ := http.NewRequest("GET", frontend.URL, nil)
getReq.Host = "some-name"
getReq.Header.Set("Proxy-Connection", "should be deleted")
getReq.Header.Set("Upgrade", "foo")
getReq.Close = true
- res, err := http.DefaultClient.Do(getReq)
+ res, err := frontendClient.Do(getReq)
if err != nil {
t.Fatalf("Get: %v", err)
}
// a response results in a StatusBadGateway.
getReq, _ = http.NewRequest("GET", frontend.URL+"/?mode=hangup", nil)
getReq.Close = true
- res, err = http.DefaultClient.Do(getReq)
+ res, err = frontendClient.Do(getReq)
if err != nil {
t.Fatal(err)
}
getReq.Header.Set("Connection", "Upgrade, "+fakeConnectionToken)
getReq.Header.Set("Upgrade", "original value")
getReq.Header.Set(fakeConnectionToken, "should be deleted")
- res, err := http.DefaultClient.Do(getReq)
+ res, err := frontend.Client().Do(getReq)
if err != nil {
t.Fatalf("Get: %v", err)
}
getReq.Header.Set("Connection", "close")
getReq.Header.Set("X-Forwarded-For", prevForwardedFor)
getReq.Close = true
- res, err := http.DefaultClient.Do(getReq)
+ res, err := frontend.Client().Do(getReq)
if err != nil {
t.Fatalf("Get: %v", err)
}
frontend := httptest.NewServer(NewSingleHostReverseProxy(backendURL))
req, _ := http.NewRequest("GET", frontend.URL+tt.reqSuffix, nil)
req.Close = true
- res, err := http.DefaultClient.Do(req)
+ res, err := frontend.Client().Do(req)
if err != nil {
t.Fatalf("%d. Get: %v", i, err)
}
req, _ := http.NewRequest("GET", frontend.URL, nil)
req.Close = true
- res, err := http.DefaultClient.Do(req)
+ res, err := frontend.Client().Do(req)
if err != nil {
t.Fatalf("Get: %v", err)
}
frontend := httptest.NewServer(proxyHandler)
defer frontend.Close()
+ frontendClient := frontend.Client()
getReq, _ := http.NewRequest("GET", frontend.URL, nil)
go func() {
<-reqInFlight
- http.DefaultTransport.(*http.Transport).CancelRequest(getReq)
+ frontendClient.Transport.(*http.Transport).CancelRequest(getReq)
}()
- res, err := http.DefaultClient.Do(getReq)
+ res, err := frontendClient.Do(getReq)
if res != nil {
t.Errorf("got response %v; want nil", res.Status)
}
// This should be an error like:
// Get http://127.0.0.1:58079: read tcp 127.0.0.1:58079:
// use of closed network connection
- t.Error("DefaultClient.Do() returned nil error; want non-nil error")
+ t.Error("Server.Client().Do() returned nil error; want non-nil error")
}
}
proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
frontend := httptest.NewServer(proxyHandler)
defer frontend.Close()
+ frontendClient := frontend.Client()
getReq, _ := http.NewRequest("GET", frontend.URL, nil)
getReq.Header.Set("User-Agent", explicitUA)
getReq.Close = true
- res, err := http.DefaultClient.Do(getReq)
+ res, err := frontendClient.Do(getReq)
if err != nil {
t.Fatalf("Get: %v", err)
}
getReq, _ = http.NewRequest("GET", frontend.URL+"/noua", nil)
getReq.Header.Set("User-Agent", "")
getReq.Close = true
- res, err = http.DefaultClient.Do(getReq)
+ res, err = frontendClient.Do(getReq)
if err != nil {
t.Fatalf("Get: %v", err)
}
req, _ := http.NewRequest("GET", frontend.URL, nil)
req.Close = true
- res, err := http.DefaultClient.Do(req)
+ res, err := frontend.Client().Do(req)
if err != nil {
t.Fatalf("Get: %v", err)
}
defer frontend.Close()
postReq, _ := http.NewRequest("POST", frontend.URL, bytes.NewReader(requestBody))
- res, err := http.DefaultClient.Do(postReq)
+ res, err := frontend.Client().Do(postReq)
if err != nil {
t.Fatalf("Do: %v", err)
}
frontend := httptest.NewServer(proxyHandler)
defer frontend.Close()
- res, err := http.DefaultClient.Get(frontend.URL)
+ res, err := frontend.Client().Get(frontend.URL)
if err != nil {
t.Fatal(err)
}
}
return err
}
-
-func closeClient(c *http.Client) {
- c.Transport.(*http.Transport).CloseIdleConnections()
-}
"bufio"
"bytes"
"crypto/tls"
+ "crypto/x509"
"fmt"
"io"
"io/ioutil"
// Normal request, without NPN.
{
- tr := newTLSTransport(t, ts)
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
-
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
t.Fatal(err)
// Request to an advertised but unhandled NPN protocol.
// Server will hang up.
{
- tr := newTLSTransport(t, ts)
- tr.TLSClientConfig.NextProtos = []string{"unhandled-proto"}
+ certPool := x509.NewCertPool()
+ certPool.AddCert(ts.Certificate())
+ tr := &Transport{
+ TLSClientConfig: &tls.Config{
+ RootCAs: certPool,
+ NextProtos: []string{"unhandled-proto"},
+ },
+ }
defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
-
+ c := &Client{
+ Transport: tr,
+ }
res, err := c.Get(ts.URL)
if err == nil {
defer res.Body.Close()
// Request using the "tls-0.9" protocol, which we register here.
// It is HTTP/0.9 over TLS.
{
- tlsConfig := newTLSTransport(t, ts).TLSClientConfig
+ c := ts.Client()
+ tlsConfig := c.Transport.(*Transport).TLSClientConfig
tlsConfig.NextProtos = []string{"tls-0.9"}
conn, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig)
if err != nil {
defer ts.Close()
// Hit the HTTP server successfully.
- tr := &Transport{DisableKeepAlives: true} // they interfere with this test
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
r, err := c.Get(ts.URL)
if err != nil {
t.Fatalf("http Get #1: %v", err)
ts.StartTLS()
defer ts.Close()
- tr := newTLSTransport(t, ts)
- defer tr.CloseIdleConnections()
- if err := ExportHttp2ConfigureTransport(tr); err != nil {
+ c := ts.Client()
+ if err := ExportHttp2ConfigureTransport(c.Transport.(*Transport)); err != nil {
t.Fatal(err)
}
- c := &Client{Transport: tr}
for i := 1; i <= 3; i++ {
req, err := NewRequest("GET", ts.URL, nil)
ts.Start()
defer ts.Close()
- tr := &Transport{DisableKeepAlives: false}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
errc := make(chan error)
go func() {
ts := httptest.NewServer(handler)
defer ts.Close()
- c := &Client{Transport: new(Transport)}
- defer closeClient(c)
+ c := ts.Client()
// Note: this relies on the assumption (which is true) that
// Get sends HTTP/1.1 or greater requests. Otherwise the
ts.Start()
defer ts.Close()
- tr := &Transport{DisableKeepAlives: true}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr, Timeout: time.Second}
+ c := ts.Client()
+ c.Timeout = time.Second
fetch := func(num int, response chan<- string) {
resp, err := c.Get(ts.URL)
}))
defer ts.Close()
- c := &Client{Transport: new(Transport)}
- defer closeClient(c)
-
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
t.Fatalf("Get error: %v", err)
t.Errorf("expected test TLS server to start with https://, got %q", ts.URL)
return
}
- noVerifyTransport := &Transport{
- TLSClientConfig: &tls.Config{
- InsecureSkipVerify: true,
- },
- }
- client := &Client{Transport: noVerifyTransport}
+ client := ts.Client()
res, err := client.Get(ts.URL)
if err != nil {
t.Error(err)
ts := httptest.NewServer(TimeoutHandler(delayHi, 20*time.Millisecond, ""))
defer ts.Close()
- c := &Client{Transport: new(Transport)}
- defer closeClient(c)
+ c := ts.Client()
var wg sync.WaitGroup
gate := make(chan bool, 10)
if testing.Short() {
n = 10
}
- c := &Client{Transport: new(Transport)}
- defer closeClient(c)
+
+ c := ts.Client()
for i := 0; i < n; i++ {
gate <- true
wg.Add(1)
ts := httptest.NewServer(TimeoutHandler(handler, timeout, ""))
defer ts.Close()
- c := &Client{Transport: new(Transport)}
- defer closeClient(c)
+ c := ts.Client()
// Issue was caused by the timeout handler starting the timer when
// was created, not when the request. So wait for more than the timeout
ts := httptest.NewServer(TimeoutHandler(handler, timeout, ""))
defer ts.Close()
- c := &Client{Transport: new(Transport)}
- defer closeClient(c)
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
ts.Start()
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
t.Fatal(err)
ts := httptest.NewServer(StripPrefix("/foo", h))
defer ts.Close()
- c := &Client{Transport: new(Transport)}
- defer closeClient(c)
+ c := ts.Client()
res, err := c.Get(ts.URL + "/foo/bar")
if err != nil {
}
ts.Start()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
mustGet := func(url string, headers ...string) {
req, err := NewRequest("GET", url, nil)
b.ResetTimer()
b.SetParallelism(parallelism)
b.RunParallel(func(pb *testing.PB) {
- noVerifyTransport := &Transport{
- TLSClientConfig: &tls.Config{
- InsecureSkipVerify: true,
- },
- }
- defer noVerifyTransport.CloseIdleConnections()
- client := &Client{Transport: noVerifyTransport}
+ c := ts.Client()
for pb.Next() {
- res, err := client.Get(ts.URL)
+ res, err := c.Get(ts.URL)
if err != nil {
b.Logf("Get: %v", err)
continue
ts.Config.IdleTimeout = 2 * time.Second
ts.Start()
defer ts.Close()
-
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
get := func() string {
res, err := c.Get(ts.URL)
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
get := func() string { return get(t, c, ts.URL) }
ts.Start()
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
ts := httptest.NewServer(hostPortHandler)
defer ts.Close()
+ c := ts.Client()
for _, disableKeepAlive := range []bool{false, true} {
- tr := &Transport{DisableKeepAlives: disableKeepAlive}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
-
+ c.Transport.(*Transport).DisableKeepAlives = disableKeepAlive
fetch := func(n int) string {
res, err := c.Get(ts.URL)
if err != nil {
connSet, testDial := makeTestDial(t)
- for _, connectionClose := range []bool{false, true} {
- tr := &Transport{
- Dial: testDial,
- }
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
+ tr.Dial = testDial
+ for _, connectionClose := range []bool{false, true} {
fetch := func(n int) string {
req := new(Request)
var err error
connSet, testDial := makeTestDial(t)
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
+ tr.Dial = testDial
for _, connectionClose := range []bool{false, true} {
- tr := &Transport{
- Dial: testDial,
- }
- c := &Client{Transport: tr}
-
fetch := func(n int) string {
req := new(Request)
var err error
ts := httptest.NewServer(hostPortHandler)
defer ts.Close()
- tr := &Transport{
- DisableKeepAlives: true,
- }
- c := &Client{Transport: tr}
+ c := ts.Client()
+ c.Transport.(*Transport).DisableKeepAlives = true
+
res, err := c.Get(ts.URL)
if err != nil {
t.Fatal(err)
defer afterTest(t)
ts := httptest.NewServer(hostPortHandler)
defer ts.Close()
-
- tr := &Transport{DisableKeepAlives: false}
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
}
}))
defer ts.Close()
+
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
maxIdleConnsPerHost := 2
- tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConnsPerHost}
- c := &Client{Transport: tr}
+ tr.MaxIdleConnsPerHost = maxIdleConnsPerHost
// Start 3 outstanding requests and wait for the server to get them.
// Their responses will hang until we write to resch, though.
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
doReq := func(name string) string {
// Do a POST instead of a GET to prevent the Transport's
defer afterTest(t)
ts := httptest.NewServer(hostPortHandler)
defer ts.Close()
-
- tr := &Transport{}
- c := &Client{Transport: tr}
+ c := ts.Client()
fetch := func(n, retries int) string {
condFatalf := func(format string, arg ...interface{}) {
conn.Close()
}))
defer ts.Close()
-
- tr := &Transport{DisableKeepAlives: false}
- c := &Client{Transport: tr}
- defer tr.CloseIdleConnections()
+ c := ts.Client()
// Do a bunch of traffic from different goroutines. Send to activityc
// after each request completes, regardless of whether it failed.
w.WriteHeader(200)
}))
defer ts.Close()
+ c := ts.Client()
- tr := &Transport{DisableKeepAlives: false}
- c := &Client{Transport: tr}
for i := 0; i < 2; i++ {
res, err := c.Head(ts.URL)
if err != nil {
w.WriteHeader(200)
}))
defer ts.Close()
-
- tr := &Transport{DisableKeepAlives: false}
- c := &Client{Transport: tr}
- defer tr.CloseIdleConnections()
+ c := ts.Client()
// Ensure that we wait for the readLoop to complete before
// calling Head again
}
}))
defer ts.Close()
+ tr := ts.Client().Transport.(*Transport)
for i, test := range roundTripTests {
// Test basic request (no accept-encoding)
if test.accept != "" {
req.Header.Set("Accept-Encoding", test.accept)
}
- res, err := DefaultTransport.RoundTrip(req)
+ res, err := tr.RoundTrip(req)
var body []byte
if test.compressed {
var r *gzip.Reader
gz.Close()
}))
defer ts.Close()
+ c := ts.Client()
for _, chunked := range []string{"1", "0"} {
- c := &Client{Transport: &Transport{}}
-
// First fetch something large, but only read some of it.
res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
if err != nil {
}
// And a HEAD request too, because they're always weird.
- c := &Client{Transport: &Transport{}}
res, err := c.Head(ts.URL)
if err != nil {
t.Fatalf("Head: %v", err)
{path: "/timeout", body: []byte("hello"), sent: 5, status: 200}, // Timeout exceeded and entire body is sent.
}
+ c := ts.Client()
for i, v := range tests {
- tr := &Transport{ExpectContinueTimeout: 2 * time.Second}
+ tr := &Transport{
+ ExpectContinueTimeout: 2 * time.Second,
+ }
defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
-
+ c.Transport = tr
body := bytes.NewReader(v.body)
req, err := NewRequest("PUT", ts.URL+v.path, body)
if err != nil {
if err != nil {
t.Fatal(err)
}
- c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
+ c := ts.Client()
+ c.Transport.(*Transport).Proxy = ProxyURL(pu)
if _, err := c.Head(ts.URL); err != nil {
t.Error(err)
}
if err != nil {
t.Fatal(err)
}
- c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
+ c := ts.Client()
+ c.Transport.(*Transport).Proxy = ProxyURL(pu)
if _, err := c.Head(ts.URL); err != nil {
t.Error(err)
}
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
t.Fatal(err)
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
t.Fatal(err)
w.WriteHeader(204)
}))
defer ts.Close()
-
- tr := &Transport{}
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
n0 := runtime.NumGoroutine()
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
}))
defer ts.Close()
-
- tr := &Transport{}
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
n0 := runtime.NumGoroutine()
body := []byte("Hello")
// This used to crash; https://golang.org/issue/3266
func TestTransportIdleConnCrash(t *testing.T) {
defer afterTest(t)
- tr := &Transport{}
- c := &Client{Transport: tr}
+ var tr *Transport
unblockCh := make(chan bool, 1)
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
tr.CloseIdleConnections()
}))
defer ts.Close()
+ c := ts.Client()
+ tr = c.Transport.(*Transport)
didreq := make(chan bool)
go func() {
}
}))
defer ts.Close()
- tr := &Transport{}
- c := &Client{Transport: tr}
+ c := ts.Client()
res, err := c.Get(ts.URL)
if err != nil {
t.Fatal(err)
Error(w, deniedMsg, StatusUnauthorized)
}))
defer ts.Close()
- tr := &Transport{}
- c := &Client{Transport: tr}
+ c := ts.Client()
res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
if err != nil {
t.Errorf("Post: %v", err)
}))
defer ts.Close()
+ c := ts.Client()
for _, closeBody := range []bool{true, false} {
- c := &Client{Transport: &Transport{}}
const n = 4
for i := 1; i <= n; i++ {
res, err := c.Get(ts.URL)
SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
defer SetPendingDialHooks(nil, nil)
- tr := &Transport{}
- defer tr.CloseIdleConnections()
-
- c := &Client{Transport: tr}
+ c := ts.Client()
reqs := make(chan string)
defer close(reqs)
io.Copy(w, neverEnding('a'))
})
ts := httptest.NewServer(mux)
+ defer ts.Close()
timeout := 100 * time.Millisecond
- client := &Client{
- Transport: &Transport{
- Dial: func(n, addr string) (net.Conn, error) {
- conn, err := net.Dial(n, addr)
- if err != nil {
- return nil, err
- }
- conn.SetDeadline(time.Now().Add(timeout))
- if debug {
- conn = NewLoggingConn("client", conn)
- }
- return conn, nil
- },
- DisableKeepAlives: true,
- },
+ c := ts.Client()
+ c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
+ conn, err := net.Dial(n, addr)
+ if err != nil {
+ return nil, err
+ }
+ conn.SetDeadline(time.Now().Add(timeout))
+ if debug {
+ conn = NewLoggingConn("client", conn)
+ }
+ return conn, nil
}
getFailed := false
if debug {
println("run", i+1, "of", nRuns)
}
- sres, err := client.Get(ts.URL + "/get")
+ sres, err := c.Get(ts.URL + "/get")
if err != nil {
if !getFailed {
// Make the timeout longer, once.
if debug {
println("tests complete; waiting for handlers to finish")
}
- ts.Close()
}
func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
ts := httptest.NewServer(mux)
timeout := 100 * time.Millisecond
- client := &Client{
- Transport: &Transport{
- Dial: func(n, addr string) (net.Conn, error) {
- conn, err := net.Dial(n, addr)
- if err != nil {
- return nil, err
- }
- conn.SetDeadline(time.Now().Add(timeout))
- if debug {
- conn = NewLoggingConn("client", conn)
- }
- return conn, nil
- },
- DisableKeepAlives: true,
- },
+ c := ts.Client()
+ c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
+ conn, err := net.Dial(n, addr)
+ if err != nil {
+ return nil, err
+ }
+ conn.SetDeadline(time.Now().Add(timeout))
+ if debug {
+ conn = NewLoggingConn("client", conn)
+ }
+ return conn, nil
}
getFailed := false
if debug {
println("run", i+1, "of", nRuns)
}
- sres, err := client.Get(ts.URL + "/get")
+ sres, err := c.Get(ts.URL + "/get")
if err != nil {
if !getFailed {
// Make the timeout longer, once.
break
}
req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
- _, err = client.Do(req)
+ _, err = c.Do(req)
if err == nil {
sres.Body.Close()
t.Errorf("Unexpected successful PUT")
ts := httptest.NewServer(mux)
defer ts.Close()
- tr := &Transport{
- ResponseHeaderTimeout: 500 * time.Millisecond,
- }
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
+ c.Transport.(*Transport).ResponseHeaderTimeout = 500 * time.Millisecond
tests := []struct {
path string
defer ts.Close()
defer close(unblockc)
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
req, _ := NewRequest("GET", ts.URL, nil)
res, err := c.Do(req)
defer ts.Close()
defer close(unblockc)
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
req, _ := NewRequest("GET", ts.URL, nil)
ch := make(chan struct{})
defer ts.Close()
defer close(unblockc)
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
req, _ := NewRequest("GET", ts.URL, nil)
if withCtx {
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
req, _ := NewRequest("GET", ts.URL, nil)
defer tr.CancelRequest(req)
defer ts.Close()
dialGate := make(chan bool, 1)
- tr := &Transport{
- Dial: func(n, addr string) (net.Conn, error) {
- if <-dialGate {
- return net.Dial(n, addr)
- }
- return nil, errors.New("manually closed")
- },
- DisableKeepAlives: false,
- }
- defer tr.CloseIdleConnections()
- c := &Client{
- Transport: tr,
+ c := ts.Client()
+ c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
+ if <-dialGate {
+ return net.Dial(n, addr)
+ }
+ return nil, errors.New("manually closed")
}
dialGate <- true // only allow one dial
SetReadLoopBeforeNextReadHook(func() { didRead <- true })
defer SetReadLoopBeforeNextReadHook(nil)
- tr := &Transport{
- Dial: func(netw, addr string) (net.Conn, error) {
- return net.Dial(netw, ts.Listener.Addr().String())
- },
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
+ tr.Dial = func(netw, addr string) (net.Conn, error) {
+ return net.Dial(netw, ts.Listener.Addr().String())
}
- defer tr.CloseIdleConnections()
-
- c := &Client{Transport: tr}
// First, without keep-alives.
for _, disableKeep := range []bool{true, false} {
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- cl := &Client{Transport: tr}
+ c := ts.Client()
closes := 0
- res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
+ res, err := c.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
if err != nil {
t.Fatal(err)
}
fmt.Fprintf(w, "hello")
}))
defer ts.Close()
- tr := &Transport{
- TLSClientConfig: &tls.Config{
- InsecureSkipVerify: true,
- },
- }
- defer tr.CloseIdleConnections()
- client := &Client{Transport: tr}
+
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
var nSuccess = 0
var errs []error
const trials = 20
for i := 0; i < trials; i++ {
tr.CloseIdleConnections()
- res, err := client.Get(ts.URL + "/keep-alive-then-die")
+ res, err := c.Get(ts.URL + "/keep-alive-then-die")
if err != nil {
t.Fatal(err)
}
// Now try again and see if we successfully
// pick a new connection.
- res, err = client.Get(ts.URL + "/")
+ res, err = c.Get(ts.URL + "/")
if err != nil {
errs = append(errs, err)
continue
go io.Copy(ioutil.Discard, conn)
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- client := &Client{Transport: tr}
+ c := ts.Client()
const bodySize = 256 << 10
finalBit := make(byteFromChanReader, 1)
req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
req.ContentLength = bodySize
- res, err := client.Do(req)
+ res, err := c.Do(req)
if err := wantBody(res, err, "foo"); err != nil {
t.Errorf("POST response: %v", err)
}
donec := make(chan bool)
go func() {
defer close(donec)
- res, err = client.Get(ts.URL)
+ res, err = c.Get(ts.URL)
if err := wantBody(res, err, "bar"); err != nil {
t.Errorf("GET response: %v", err)
return
conn.Close()
}))
defer ts.Close()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- cl := &Client{Transport: tr}
- res, err := cl.Get(ts.URL)
+ c := ts.Client()
+
+ res, err := c.Get(ts.URL)
if err != nil {
t.Fatalf("Get: %v", err)
}
defer ts.Close()
var writeNumAtomic int32
- tr := &Transport{
- Dial: func(network, addr string) (net.Conn, error) {
- logf("Dial")
- c, err := net.Dial(network, ts.Listener.Addr().String())
- if err != nil {
- logf("Dial error: %v", err)
- return nil, err
- }
- return &writerFuncConn{
- Conn: c,
- write: func(p []byte) (n int, err error) {
- if atomic.AddInt32(&writeNumAtomic, 1) == 2 {
- logf("intentional write failure")
- return 0, errors.New("second write fails")
- }
- logf("Write(%q)", p)
- return c.Write(p)
- },
- }, nil
- },
+ c := ts.Client()
+ c.Transport.(*Transport).Dial = func(network, addr string) (net.Conn, error) {
+ logf("Dial")
+ c, err := net.Dial(network, ts.Listener.Addr().String())
+ if err != nil {
+ logf("Dial error: %v", err)
+ return nil, err
+ }
+ return &writerFuncConn{
+ Conn: c,
+ write: func(p []byte) (n int, err error) {
+ if atomic.AddInt32(&writeNumAtomic, 1) == 2 {
+ logf("intentional write failure")
+ return 0, errors.New("second write fails")
+ }
+ logf("Write(%q)", p)
+ return c.Write(p)
+ },
+ }, nil
}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
SetRoundTripRetried(func() {
logf("Retried.")
readBody <- err
}))
defer ts.Close()
+ c := ts.Client()
fakeErr := errors.New("fake error")
didClose := make(chan bool, 1)
req, _ := NewRequest("POST", ts.URL, struct {
return nil
}),
})
- res, err := DefaultClient.Do(req)
+ res, err := c.Do(req)
if res != nil {
defer res.Body.Close()
}
mu.Unlock()
}))
defer ts.Close()
- tr := &Transport{
- DialTLS: func(netw, addr string) (net.Conn, error) {
- mu.Lock()
- didDial = true
- mu.Unlock()
- c, err := tls.Dial(netw, addr, &tls.Config{
- InsecureSkipVerify: true,
- })
- if err != nil {
- return nil, err
- }
- return c, c.Handshake()
- },
+ c := ts.Client()
+ c.Transport.(*Transport).DialTLS = func(netw, addr string) (net.Conn, error) {
+ mu.Lock()
+ didDial = true
+ mu.Unlock()
+ c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig)
+ if err != nil {
+ return nil, err
+ }
+ return c, c.Handshake()
}
- defer tr.CloseIdleConnections()
- client := &Client{Transport: tr}
- res, err := client.Get(ts.URL)
+
+ res, err := c.Get(ts.URL)
if err != nil {
t.Fatal(err)
}
reqc <- r
}))
defer ts.Close()
+ c := ts.Client()
req, _ := NewRequest("GET", ts.URL, nil)
req.Header.Set("Range", "bytes=7-11")
- res, err := DefaultClient.Do(req)
+ res, err := c.Do(req)
if err != nil {
t.Fatal(err)
}
w.Write(b[:])
}))
defer ts.Close()
-
- tr := &Transport{}
- defer tr.CloseIdleConnections()
+ tr := ts.Client().Transport.(*Transport)
req, err := NewRequest("GET", ts.URL, nil)
if err != nil {
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
defer ts.Close()
-
- tr := &Transport{}
- defer tr.CloseIdleConnections()
+ tr := ts.Client().Transport.(*Transport)
req, err := NewRequest("GET", ts.URL, nil)
if err != nil {
w.WriteHeader(StatusOK)
}))
defer ts.Close()
+ c := ts.Client()
fail := 0
count := 100
if err != nil {
t.Fatal(err)
}
- tr := new(Transport)
- defer tr.CloseIdleConnections()
- client := &Client{Transport: tr}
- resp, err := client.Do(req)
+ resp, err := c.Do(req)
if err != nil {
fail++
t.Logf("%d = %#v", i, err)
w.Write(rgz) // arbitrary gzip response
}))
defer ts.Close()
+ c := ts.Client()
- tr := &Transport{}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
for i := 0; i < 2; i++ {
res, err := c.Get(ts.URL)
if err != nil {
}
}))
defer ts.Close()
+ c := ts.Client()
+ c.Transport.(*Transport).MaxResponseHeaderBytes = 512 << 10
- tr := &Transport{
- MaxResponseHeaderBytes: 512 << 10,
- }
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
if res, err := c.Get(ts.URL); err != nil {
t.Fatal(err)
} else {
// connections. The http2 test is done in TestTransportEventTrace_h2
func TestTLSHandshakeTrace(t *testing.T) {
defer afterTest(t)
- s := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
- defer s.Close()
+ ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+ defer ts.Close()
var mu sync.Mutex
var start, done bool
},
}
- tr := &Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
- req, err := NewRequest("GET", s.URL, nil)
+ c := ts.Client()
+ req, err := NewRequest("GET", ts.URL, nil)
if err != nil {
t.Fatal("Unable to construct test request:", err)
}
// No body for convenience.
}))
defer ts.Close()
- tr := &Transport{
- MaxIdleConns: 4,
- }
- defer tr.CloseIdleConnections()
+ c := ts.Client()
+ tr := c.Transport.(*Transport)
+ tr.MaxIdleConns = 4
ip, port, err := net.SplitHostPort(ts.Listener.Addr().String())
if err != nil {
t.Fatal(err)
}
- c := &Client{Transport: tr}
ctx := context.WithValue(context.Background(), nettrace.LookupIPAltResolverKey{}, func(ctx context.Context, host string) ([]net.IPAddr, error) {
return []net.IPAddr{{IP: net.ParseIP(ip)}}, nil
})
c.Close()
}))
defer ts.Close()
- tr := &Transport{
- ProxyConnectHeader: Header{
- "User-Agent": {"foo"},
- "Other": {"bar"},
- },
- Proxy: func(r *Request) (*url.URL, error) {
- return url.Parse(ts.URL)
- },
+
+ c := ts.Client()
+ c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) {
+ return url.Parse(ts.URL)
}
- defer tr.CloseIdleConnections()
- c := &Client{Transport: tr}
+ c.Transport.(*Transport).ProxyConnectHeader = Header{
+ "User-Agent": {"foo"},
+ "Other": {"bar"},
+ }
+
res, err := c.Get("https://dummy.tld/") // https to force a CONNECT
if err == nil {
res.Body.Close()