]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: returned typed error on Transport proxy dial
authorQuentin Renard <contact@asticode.com>
Sat, 8 Oct 2016 13:52:25 +0000 (15:52 +0200)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 31 Oct 2016 17:39:50 +0000 (17:39 +0000)
Fixes #16997

Change-Id: I9ca27d8cff1905584862997d0e8a11ce3c4c21cb
Reviewed-on: https://go-review.googlesource.com/30750
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/http/transport.go
src/net/http/transport_test.go

index 8162f9a998905e7b1edc6f0b023b606955923e57..e227b3764a3a378fe7ae818939ce53cd1285766c 100644 (file)
@@ -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
                }
index 083fedefe0d9069dbda132b8b4acc051bcd9ec5e..a5c86989d1c8da639fb6d19810ecbde83594632b 100644 (file)
@@ -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