From 61ffec4b52f64793ad450d1a2d8c4144fa3d5f18 Mon Sep 17 00:00:00 2001 From: Quentin Renard Date: Sat, 8 Oct 2016 15:52:25 +0200 Subject: [PATCH] net/http: returned typed error on Transport proxy dial Fixes #16997 Change-Id: I9ca27d8cff1905584862997d0e8a11ce3c4c21cb Reviewed-on: https://go-review.googlesource.com/30750 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/net/http/transport.go | 3 ++- src/net/http/transport_test.go | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/net/http/transport.go b/src/net/http/transport.go index 8162f9a998..e227b3764a 100644 --- a/src/net/http/transport.go +++ b/src/net/http/transport.go @@ -991,7 +991,8 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (*persistCon conn, err := t.dial(ctx, "tcp", cm.addr()) if err != nil { if cm.proxyURL != nil { - err = fmt.Errorf("http: error connecting to proxy %s: %v", cm.proxyURL, err) + // Return a typed error, per Issue 16997: + err = &net.OpError{Op: "proxyconnect", Net: "tcp", Err: err} } return nil, err } diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go index 083fedefe0..a5c86989d1 100644 --- a/src/net/http/transport_test.go +++ b/src/net/http/transport_test.go @@ -963,6 +963,48 @@ func TestTransportProxy(t *testing.T) { } } +// Issue 16997: test transport dial preserves typed errors +func TestTransportDialPreservesNetOpProxyError(t *testing.T) { + defer afterTest(t) + + var errDial = errors.New("some dial error") + + tr := &Transport{ + Proxy: func(*Request) (*url.URL, error) { + return url.Parse("http://proxy.fake.tld/") + }, + Dial: func(string, string) (net.Conn, error) { + return nil, errDial + }, + } + defer tr.CloseIdleConnections() + + c := &Client{Transport: tr} + req, _ := NewRequest("GET", "http://fake.tld", nil) + res, err := c.Do(req) + if err == nil { + res.Body.Close() + t.Fatal("wanted a non-nil error") + } + + uerr, ok := err.(*url.Error) + if !ok { + t.Fatalf("got %T, want *url.Error", err) + } + oe, ok := uerr.Err.(*net.OpError) + if !ok { + t.Fatalf("url.Error.Err = %T; want *net.OpError", uerr.Err) + } + want := &net.OpError{ + Op: "proxyconnect", + Net: "tcp", + Err: errDial, // original error, unwrapped. + } + if !reflect.DeepEqual(oe, want) { + t.Errorf("Got error %#v; want %#v", oe, want) + } +} + // TestTransportGzipRecursive sends a gzip quine and checks that the // client gets the same value back. This is more cute than anything, // but checks that we don't recurse forever, and checks that -- 2.48.1