[net] proxy: add Dial, DialTimeout, and DialContext

370 views
Skip to first unread message

Gerrit Bot (Gerrit)

unread,
Mar 22, 2019, 11:22:28 PM3/22/19
to Ian Lance Taylor, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Gerrit Bot has uploaded this change for review.

View Change

proxy: add Dial, DialTimeout, and DialContext

The existing API does not allow client code to take advantage of Dialer
implementations that implement DialTimeout and DialContext receivers.
These functions provide a familiar API, see Dial and DialTimeout in the
net package.

Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
GitHub-Last-Rev: f4a08796885431483e9ee8ea7a8532b344d1dff3
GitHub-Pull-Request: golang/net#38
---
A proxy/dial.go
A proxy/dial_test.go
2 files changed, 363 insertions(+), 0 deletions(-)

diff --git a/proxy/dial.go b/proxy/dial.go
new file mode 100644
index 0000000..cf55687
--- /dev/null
+++ b/proxy/dial.go
@@ -0,0 +1,75 @@
+package proxy
+
+import (
+ "context"
+ "net"
+ "time"
+)
+
+// ContextDialer implements DialContext akin to net.Dialer#DialContext.
+type ContextDialer interface {
+ DialContext(ctx context.Context, network, address string) (net.Conn, error)
+}
+
+// TimeoutDialer implements DialTimeout much like net.DialTimeout.
+type TimeoutDialer interface {
+ DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
+}
+
+// Dial works like net.Dial but using a Dialer derived from the configured proxy environment.
+func Dial(network, address string) (net.Conn, error) {
+ var d = FromEnvironment()
+ return d.Dial(network, address)
+}
+
+// DialTimeout works like net.DialTimeout but using a Dialer derived from the configured proxy environment.
+// Custom dialers (registered via RegisterDialerType) that do not implement TimeoutDialer (or ContextDialer)
+// can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout.
+func DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
+ var d = FromEnvironment()
+ if td, ok := d.(TimeoutDialer); ok {
+ return td.DialTimeout(network, address, timeout)
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), timeout)
+ defer cancel()
+
+ if cd, ok := d.(ContextDialer); ok {
+ return cd.DialContext(ctx, network, address)
+ }
+ return dialContext(ctx, network, address, d)
+}
+
+// DialContext works like DialContext on net.Dialer but using a dialer derived from the configured proxy environment.
+// Custom dialers (registered via RegisterDialerType) that do not implement ContextDialer
+// can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout.
+func DialContext(ctx context.Context, network, address string) (net.Conn, error) {
+ var d = FromEnvironment()
+ if td, ok := d.(ContextDialer); ok {
+ return td.DialContext(ctx, network, address)
+ }
+ return dialContext(ctx, network, address, d)
+}
+
+// WARNING: for custom dialers that only implement proxy.Dialer this will leak a goroutine
+// that will live as long as it takes the underlying Dialer implementation to timeout
+func dialContext(ctx context.Context, network, address string, d Dialer) (net.Conn, error) {
+ var (
+ conn net.Conn
+ done = make(chan struct{}, 1)
+ err error
+ )
+ go func() {
+ conn, err = d.Dial(network, address)
+ close(done)
+ if conn != nil && ctx.Err() != nil {
+ conn.Close()
+ }
+ }()
+ select {
+ case <-ctx.Done():
+ err = ctx.Err()
+ case <-done:
+ }
+ return conn, err
+}
diff --git a/proxy/dial_test.go b/proxy/dial_test.go
new file mode 100644
index 0000000..3ed659a
--- /dev/null
+++ b/proxy/dial_test.go
@@ -0,0 +1,288 @@
+package proxy
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "os"
+ "testing"
+ "time"
+
+ "golang.org/x/net/internal/sockstest"
+)
+
+func TestDial(t *testing.T) {
+ t.Run("Direct", func(t *testing.T) {
+ defer ResetProxyEnv()
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer l.Close()
+ _, port, err := net.SplitHostPort(l.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("ALL_PROXY"); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ c, err := Dial(l.Addr().Network(), net.JoinHostPort("", port))
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+ })
+ t.Run("SOCKS5", func(t *testing.T) {
+ defer ResetProxyEnv()
+ s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer s.Close()
+ p := fmt.Sprintf("socks5://%s", s.Addr().String())
+ if err = os.Setenv("ALL_PROXY", p); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ c, err := Dial(s.TargetAddr().Network(), s.TargetAddr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+ })
+}
+
+func TestDialContext(t *testing.T) {
+ t.Run("DirectWithCancel", func(t *testing.T) {
+ defer ResetProxyEnv()
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer l.Close()
+ _, port, err := net.SplitHostPort(l.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("ALL_PROXY"); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ c, err := DialContext(ctx, l.Addr().Network(), net.JoinHostPort("", port))
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+ })
+ t.Run("DirectWithTimeout", func(t *testing.T) {
+ defer ResetProxyEnv()
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer l.Close()
+ _, port, err := net.SplitHostPort(l.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("ALL_PROXY"); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ c, err := DialContext(ctx, l.Addr().Network(), net.JoinHostPort("", port))
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+ })
+ t.Run("DirectWithTimeoutExceeded", func(t *testing.T) {
+ defer ResetProxyEnv()
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer l.Close()
+ _, port, err := net.SplitHostPort(l.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("ALL_PROXY"); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
+ time.Sleep(time.Millisecond)
+ defer cancel()
+ c, err := DialContext(ctx, l.Addr().Network(), net.JoinHostPort("", port))
+ if err == nil {
+ defer c.Close()
+ t.Fatal("failed to timeout")
+ }
+ })
+ t.Run("SOCKS5", func(t *testing.T) {
+ defer ResetProxyEnv()
+ s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer s.Close()
+ if err = os.Setenv("ALL_PROXY", fmt.Sprintf("socks5://%s", s.Addr().String())); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ c, err := DialContext(context.Background(), s.TargetAddr().Network(), s.TargetAddr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+ })
+ t.Run("SOCKS5WithTimeout", func(t *testing.T) {
+ defer ResetProxyEnv()
+ s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer s.Close()
+ if err = os.Setenv("ALL_PROXY", fmt.Sprintf("socks5://%s", s.Addr().String())); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ c, err := DialContext(ctx, s.TargetAddr().Network(), s.TargetAddr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+ })
+ t.Run("SOCKS5WithTimeoutExceeded", func(t *testing.T) {
+ defer ResetProxyEnv()
+ s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer s.Close()
+ if err = os.Setenv("ALL_PROXY", fmt.Sprintf("socks5://%s", s.Addr().String())); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
+ time.Sleep(time.Millisecond)
+ defer cancel()
+ c, err := DialContext(ctx, s.TargetAddr().Network(), s.TargetAddr().String())
+ if err == nil {
+ defer c.Close()
+ t.Fatal("failed to timeout")
+ }
+ })
+}
+
+func TestDialTimeout(t *testing.T) {
+ t.Run("Direct", func(t *testing.T) {
+ defer ResetProxyEnv()
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer l.Close()
+ _, port, err := net.SplitHostPort(l.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("ALL_PROXY"); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ c, err := DialTimeout(l.Addr().Network(), net.JoinHostPort("", port), 5*time.Second)
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+ })
+ t.Run("DirectTooSlow", func(t *testing.T) {
+ defer ResetProxyEnv()
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer l.Close()
+ _, port, err := net.SplitHostPort(l.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("ALL_PROXY"); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ c, err := DialTimeout(l.Addr().Network(), net.JoinHostPort("", port), time.Nanosecond)
+ if err == nil {
+ defer c.Close()
+ t.Fatal("failed to timeout")
+ }
+ })
+ t.Run("SOCKS5", func(t *testing.T) {
+ defer ResetProxyEnv()
+ s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer s.Close()
+ p := fmt.Sprintf("socks5://%s", s.Addr().String())
+ if err = os.Setenv("ALL_PROXY", p); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ c, err := DialTimeout(s.TargetAddr().Network(), s.TargetAddr().String(), 5*time.Second)
+ if err != nil {
+ t.Fatal(err)
+ }
+ c.Close()
+ })
+ t.Run("SOCKS5TooSlow", func(t *testing.T) {
+ defer ResetProxyEnv()
+ s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer s.Close()
+ p := fmt.Sprintf("socks5://%s", s.Addr().String())
+ if err = os.Setenv("ALL_PROXY", p); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.Unsetenv("all_proxy"); err != nil {
+ t.Fatal(err)
+ }
+ c, err := DialTimeout(s.TargetAddr().Network(), s.TargetAddr().String(), time.Nanosecond)
+ if err == nil {
+ defer c.Close()
+ t.Fatal("failed to timeout")
+ }
+ })
+}

To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: net
Gerrit-Branch: master
Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
Gerrit-Change-Number: 168921
Gerrit-PatchSet: 1
Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
Gerrit-MessageType: newchange

Gobot Gobot (Gerrit)

unread,
Mar 22, 2019, 11:22:32 PM3/22/19
to Gerrit Bot, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Congratulations on opening your first change. Thank you for your contribution!

Next steps:
Within the next week or so, a maintainer will review your change and provide
feedback. See https://golang.org/doc/contribute.html#review for more info and
tips to get your patch through code review.

Most changes in the Go project go through a few rounds of revision. This can be
surprising to people new to the project. The careful, iterative review process
is our way of helping mentor contributors and ensuring that their contributions
have a lasting impact.

During May-July and Nov-Jan the Go project is in a code freeze, during which
little code gets reviewed or merged. If a reviewer responds with a comment like
R=go1.11, it means that this CL will be reviewed as part of the next development
cycle. See https://golang.org/s/release for more details.

View Change

    To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: net
    Gerrit-Branch: master
    Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
    Gerrit-Change-Number: 168921
    Gerrit-PatchSet: 1
    Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
    Gerrit-CC: Gobot Gobot <go...@golang.org>
    Gerrit-Comment-Date: Sat, 23 Mar 2019 03:22:30 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: No
    Gerrit-MessageType: comment

    Gerrit Bot (Gerrit)

    unread,
    Mar 23, 2019, 7:57:28 PM3/23/19
    to goph...@pubsubhelper.golang.org, Ian Lance Taylor, Gobot Gobot, Brad Fitzpatrick, golang-co...@googlegroups.com

    Gerrit Bot uploaded patch set #2 to this change.

    View Change

    proxy: add Dial, DialTimeout, and DialContext

    The existing API does not allow client code to take advantage of Dialer
    implementations that implement DialTimeout and DialContext receivers.
    These functions provide a familiar API, see Dial and DialTimeout in the
    net package.

    Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

    Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
    GitHub-Last-Rev: d71cd4fe7a4ee78c4719c857673262b7e7138a22

    GitHub-Pull-Request: golang/net#38
    ---
    A proxy/dial.go
    A proxy/dial_test.go
    M proxy/direct.go
    M proxy/per_host.go
    M proxy/per_host_test.go
    M proxy/proxy.go
    M proxy/socks5.go
    7 files changed, 380 insertions(+), 18 deletions(-)

    To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: net
    Gerrit-Branch: master
    Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
    Gerrit-Change-Number: 168921
    Gerrit-PatchSet: 2
    Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
    Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
    Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
    Gerrit-CC: Gobot Gobot <go...@golang.org>
    Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
    Gerrit-MessageType: newpatchset

    Gerrit Bot (Gerrit)

    unread,
    Mar 23, 2019, 8:02:20 PM3/23/19
    to goph...@pubsubhelper.golang.org, Ian Lance Taylor, Gobot Gobot, Brad Fitzpatrick, golang-co...@googlegroups.com

    Gerrit Bot uploaded patch set #3 to this change.

    View Change

    proxy: add Dial, DialTimeout, and DialContext

    The existing API does not allow client code to take advantage of Dialer
    implementations that implement DialTimeout and DialContext receivers.
    These functions provide a familiar API, see Dial and DialTimeout in the
    net package.

    Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

    Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
    GitHub-Last-Rev: 3ac08a0762edcb1e53ccddc4c3125e5678da39b6

    GitHub-Pull-Request: golang/net#38
    ---
    A proxy/dial.go
    A proxy/dial_test.go
    M proxy/direct.go
    M proxy/per_host.go
    M proxy/per_host_test.go
    M proxy/proxy.go
    M proxy/socks5.go
    7 files changed, 374 insertions(+), 18 deletions(-)

    To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: net
    Gerrit-Branch: master
    Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
    Gerrit-Change-Number: 168921
    Gerrit-PatchSet: 3

    Jacob Blain Christen (Gerrit)

    unread,
    Mar 25, 2019, 2:05:11 AM3/25/19
    to Gerrit Bot, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

    Please note that I was aware of https://go-review.googlesource.com/c/net/+/37641 before submitting this PR/CR. With this in mind I chose to merely add the proxy.Dial, proxy.DialTimeout, and proxy.DialContext functions along with the proxy.ContextDialer single-method interface. The proxy.direct and proxy.PerHost types have been modified to also implement proxy.ContextDialer so as to curry the context as deeply into the stack as possible and therefore minimize goroutine leakage. Legacy implementations of proxy.Dialer, when invoked from DialTimeout or DialContext, will temporarily leak a goroutine for as long as the underlying dialer implementation takes to timeout. Without changing the public API this seemed to me the best that could be hoped for.

    View Change

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 3
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
      Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-CC: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-Comment-Date: Sun, 24 Mar 2019 06:56:50 +0000

      Gerrit Bot (Gerrit)

      unread,
      May 1, 2019, 1:42:01 PM5/1/19
      to Jacob Blain Christen, goph...@pubsubhelper.golang.org, Gobot Gobot, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

      Gerrit Bot uploaded patch set #4 to this change.

      View Change

      proxy: add Dial, DialTimeout, and DialContext

      The existing API does not allow client code to take advantage of Dialer
      implementations that implement DialTimeout and DialContext receivers.
      These functions provide a familiar API, see Dial and DialTimeout in the
      net package.

      Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

      Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      GitHub-Last-Rev: ad1e7a3cb68d79190cfa7e61b96e1d39171b18c2

      GitHub-Pull-Request: golang/net#38
      ---
      A proxy/dial.go
      A proxy/dial_test.go
      M proxy/direct.go
      M proxy/per_host.go
      M proxy/per_host_test.go
      M proxy/proxy.go
      M proxy/socks5.go
      7 files changed, 374 insertions(+), 18 deletions(-)

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 4
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
      Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-MessageType: newpatchset

      Brad Fitzpatrick (Gerrit)

      unread,
      May 1, 2019, 1:56:27 PM5/1/19
      to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

      View Change

      6 comments:

      • File proxy/dial.go:

        • Patch Set #4, Line 1: package proxy

          add the standard copyright header to all files in this change

        • Patch Set #4, Line 9: is a means to establish a connection, with context.

          dials using a context.

          Also, mention that ctx is only used for returning the Conn, not the lifetime of the Conn. You can find similar words in the std docs.

        • Patch Set #4, Line 14: // Dial works like net.Dial but using a Dialer derived from the configured proxy environment.

          reference where said environment is defined?

        • Patch Set #4, Line 15: func Dial(network, address string) (net.Conn, error) {

          Maybe we make this take a Context and name it Dial and delete DialTimeout.

          No reason to start out with deprecated APIs.

        • Patch Set #4, Line 24: func DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {

          I don't think we need this. Just DialContext.

          If anything, Timeout could be a field on a Dialer type later.

      • File proxy/proxy.go:

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 4
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
      Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Comment-Date: Wed, 01 May 2019 17:56:24 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Gerrit-MessageType: comment

      Gerrit Bot (Gerrit)

      unread,
      May 1, 2019, 3:23:56 PM5/1/19
      to Jacob Blain Christen, goph...@pubsubhelper.golang.org, Gobot Gobot, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

      Gerrit Bot uploaded patch set #5 to this change.

      View Change

      proxy: add Dial, DialTimeout, and DialContext

      The existing API does not allow client code to take advantage of Dialer
      implementations that implement DialTimeout and DialContext receivers.
      These functions provide a familiar API, see Dial and DialTimeout in the
      net package.

      Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

      Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      GitHub-Last-Rev: 52034fa7a957be77557c12b3028bd13b60665b06

      GitHub-Pull-Request: golang/net#38
      ---
      A proxy/dial.go
      A proxy/dial_test.go
      M proxy/direct.go
      M proxy/per_host.go
      M proxy/per_host_test.go
      M proxy/proxy.go
      M proxy/socks5.go
      7 files changed, 254 insertions(+), 18 deletions(-)

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 5
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
      Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-MessageType: newpatchset

      Gerrit Bot (Gerrit)

      unread,
      May 1, 2019, 3:27:52 PM5/1/19
      to Jacob Blain Christen, goph...@pubsubhelper.golang.org, Gobot Gobot, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

      Gerrit Bot uploaded patch set #6 to this change.

      View Change

      proxy: add Dial, DialTimeout, and DialContext

      The existing API does not allow client code to take advantage of Dialer
      implementations that implement DialTimeout and DialContext receivers.
      These functions provide a familiar API, see Dial and DialTimeout in the
      net package.

      Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

      Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      GitHub-Last-Rev: cc969317307d1a48526a474a0cd53cd4eaedbd8d

      GitHub-Pull-Request: golang/net#38
      ---
      A proxy/dial.go
      A proxy/dial_test.go
      M proxy/direct.go
      M proxy/per_host.go
      M proxy/per_host_test.go
      M proxy/proxy.go
      M proxy/socks5.go
      7 files changed, 254 insertions(+), 18 deletions(-)

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 6

      Jacob Blain Christen (Gerrit)

      unread,
      May 1, 2019, 3:28:29 PM5/1/19
      to Gerrit Bot, goph...@pubsubhelper.golang.org, Gobot Gobot, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

      Jacob Blain Christen uploaded patch set #7 to the change originally created by Gerrit Bot.

      View Change

      proxy: add Dial (with context)


      The existing API does not allow client code to take advantage of Dialer
      implementations that implement DialContext receivers. This a familiar
      API, see net.Dialer.


      Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

      Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      GitHub-Last-Rev: cc969317307d1a48526a474a0cd53cd4eaedbd8d

      GitHub-Pull-Request: golang/net#38
      ---
      A proxy/dial.go
      A proxy/dial_test.go
      M proxy/direct.go
      M proxy/per_host.go
      M proxy/per_host_test.go
      M proxy/proxy.go
      M proxy/socks5.go
      7 files changed, 254 insertions(+), 18 deletions(-)

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 7

      Gerrit Bot (Gerrit)

      unread,
      May 1, 2019, 3:29:39 PM5/1/19
      to Jacob Blain Christen, goph...@pubsubhelper.golang.org, Gobot Gobot, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

      Gerrit Bot uploaded patch set #8 to this change.

      View Change

      proxy: add Dial, DialTimeout, and DialContext

      The existing API does not allow client code to take advantage of Dialer
      implementations that implement DialTimeout and DialContext receivers.
      These functions provide a familiar API, see Dial and DialTimeout in the
      net package.

      Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

      Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      GitHub-Last-Rev: cc969317307d1a48526a474a0cd53cd4eaedbd8d

      GitHub-Pull-Request: golang/net#38
      ---
      A proxy/dial.go
      A proxy/dial_test.go
      M proxy/direct.go
      M proxy/per_host.go
      M proxy/per_host_test.go
      M proxy/proxy.go
      M proxy/socks5.go
      7 files changed, 254 insertions(+), 18 deletions(-)

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 8

      Jacob Blain Christen (Gerrit)

      unread,
      May 1, 2019, 3:29:48 PM5/1/19
      to Gerrit Bot, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

      Patch Set 4:

      (6 comments)

      Brad, thank you for the feedback. I have incorporated your suggestions.

      View Change

      6 comments:

        • Done

        • dials using a context. […]

          Ack

        • Patch Set #4, Line 14: // Dial works like net.Dial but using a Dialer derived from the configured proxy environment.

          reference where said environment is defined?

        • Ack

        • Maybe we make this take a Context and name it Dial and delete DialTimeout. […]

          Okay, this put the onus on deciding what to do with a timeout value of zero back onto client code, where it belongs.

        • Ack

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 7
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
      Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Comment-Date: Wed, 01 May 2019 19:29:46 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-MessageType: comment

      Gerrit Bot (Gerrit)

      unread,
      May 1, 2019, 3:32:51 PM5/1/19
      to Jacob Blain Christen, goph...@pubsubhelper.golang.org, Gobot Gobot, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

      Gerrit Bot uploaded patch set #9 to this change.

      View Change

      proxy: add Dial (with context)

      The existing API does not allow client code to take advantage of Dialer implementations that implement DialContext receivers. This a familiar API, see net.Dialer.


      Signed-off-by: Jacob Blain Christen <dweo...@gmail.com>

      Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      GitHub-Last-Rev: cc969317307d1a48526a474a0cd53cd4eaedbd8d

      GitHub-Pull-Request: golang/net#38
      ---
      A proxy/dial.go
      A proxy/dial_test.go
      M proxy/direct.go
      M proxy/per_host.go
      M proxy/per_host_test.go
      M proxy/proxy.go
      M proxy/socks5.go
      7 files changed, 254 insertions(+), 18 deletions(-)

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 9
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
      Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-MessageType: newpatchset

      Jacob Blain Christen (Gerrit)

      unread,
      May 1, 2019, 3:33:20 PM5/1/19
      to Gerrit Bot, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

      View Change

      1 comment:

        • Ack

          Done

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 9
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
      Gerrit-CC: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Comment-Date: Wed, 01 May 2019 19:33:17 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Brad Fitzpatrick <brad...@golang.org>
      Comment-In-Reply-To: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-MessageType: comment

      Brad Fitzpatrick (Gerrit)

      unread,
      May 1, 2019, 3:56:18 PM5/1/19
      to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, Gobot Gobot, golang-co...@googlegroups.com

      Patch set 9:Run-TryBot +1

      View Change

      4 comments:

      To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: net
      Gerrit-Branch: master
      Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
      Gerrit-Change-Number: 168921
      Gerrit-PatchSet: 9
      Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
      Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
      Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
      Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
      Gerrit-Comment-Date: Wed, 01 May 2019 19:56:15 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      Gerrit-MessageType: comment

      Gobot Gobot (Gerrit)

      unread,
      May 1, 2019, 3:56:21 PM5/1/19
      to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

      TryBots beginning. Status page: https://farmer.golang.org/try?commit=ca2c88a5

      View Change

        To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: net
        Gerrit-Branch: master
        Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
        Gerrit-Change-Number: 168921
        Gerrit-PatchSet: 9
        Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
        Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
        Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
        Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
        Gerrit-CC: Gobot Gobot <go...@golang.org>
        Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
        Gerrit-Comment-Date: Wed, 01 May 2019 19:56:18 +0000

        Gobot Gobot (Gerrit)

        unread,
        May 1, 2019, 4:00:10 PM5/1/19
        to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

        TryBots are happy.

        Patch set 9:TryBot-Result +1

        View Change

          To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: net
          Gerrit-Branch: master
          Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
          Gerrit-Change-Number: 168921
          Gerrit-PatchSet: 9
          Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
          Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
          Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
          Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Comment-Date: Wed, 01 May 2019 20:00:05 +0000
          Gerrit-HasComments: No
          Gerrit-Has-Labels: Yes
          Gerrit-MessageType: comment

          Gerrit Bot (Gerrit)

          unread,
          May 1, 2019, 4:45:20 PM5/1/19
          to Jacob Blain Christen, Gobot Gobot, Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Ian Lance Taylor, golang-co...@googlegroups.com

          Gerrit Bot uploaded patch set #10 to this change.

          View Change

          proxy: add Dial (with context)

          The existing API does not allow client code to take advantage of Dialer implementations that implement DialContext receivers. This a familiar API, see net.Dialer.

          Fixes golang/go#27874
          Fixes golang/go#19354
          Fixes golang/go#17759
          Fixes golang/go#13455

          Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
          GitHub-Last-Rev: cc969317307d1a48526a474a0cd53cd4eaedbd8d

          GitHub-Pull-Request: golang/net#38
          ---
          A proxy/dial.go
          A proxy/dial_test.go
          M proxy/direct.go
          M proxy/per_host.go
          M proxy/per_host_test.go
          M proxy/proxy.go
          M proxy/socks5.go
          7 files changed, 254 insertions(+), 18 deletions(-)

          To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: net
          Gerrit-Branch: master
          Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
          Gerrit-Change-Number: 168921
          Gerrit-PatchSet: 10
          Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
          Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
          Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
          Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
          Gerrit-MessageType: newpatchset

          Jacob Blain Christen (Gerrit)

          unread,
          May 1, 2019, 4:45:33 PM5/1/19
          to Gerrit Bot, goph...@pubsubhelper.golang.org, Gobot Gobot, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

          View Change

          2 comments:

            • Remove this line. Go doesn't use this convention. […]

              Done

            • Add lines like: […]

              Done

          To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: net
          Gerrit-Branch: master
          Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
          Gerrit-Change-Number: 168921
          Gerrit-PatchSet: 10
          Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
          Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
          Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
          Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Comment-Date: Wed, 01 May 2019 20:45:28 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          Comment-In-Reply-To: Brad Fitzpatrick <brad...@golang.org>
          Gerrit-MessageType: comment

          Brad Fitzpatrick (Gerrit)

          unread,
          May 1, 2019, 5:03:21 PM5/1/19
          to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

          See my other comments on dial.go and socks5.go?

          View Change

            To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: net
            Gerrit-Branch: master
            Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
            Gerrit-Change-Number: 168921
            Gerrit-PatchSet: 10
            Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
            Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
            Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
            Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
            Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
            Gerrit-Comment-Date: Wed, 01 May 2019 21:03:17 +0000

            Jacob Blain Christen (Gerrit)

            unread,
            May 1, 2019, 5:10:55 PM5/1/19
            to Gerrit Bot, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

            View Change

            1 comment:

            To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: net
            Gerrit-Branch: master
            Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
            Gerrit-Change-Number: 168921
            Gerrit-PatchSet: 10
            Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
            Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
            Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
            Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
            Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
            Gerrit-Comment-Date: Wed, 01 May 2019 21:10:52 +0000

            Jacob Blain Christen (Gerrit)

            unread,
            May 1, 2019, 5:11:50 PM5/1/19
            to Gerrit Bot, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

            Patch Set 10:

            See my other comments on dial.go and socks5.go?

            Yes, I will make the argument ordering change but I have a reply re: your `func ProxyDial` comment

            View Change

              To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: net
              Gerrit-Branch: master
              Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
              Gerrit-Change-Number: 168921
              Gerrit-PatchSet: 10
              Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
              Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
              Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
              Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
              Gerrit-Comment-Date: Wed, 01 May 2019 21:11:47 +0000

              Gerrit Bot (Gerrit)

              unread,
              May 1, 2019, 6:32:03 PM5/1/19
              to Jacob Blain Christen, Gobot Gobot, Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Ian Lance Taylor, golang-co...@googlegroups.com

              Gerrit Bot uploaded patch set #11 to this change.

              View Change

              proxy: add Dial (with context)

              The existing API does not allow client code to take advantage of Dialer implementations that implement DialContext receivers. This a familiar API, see net.Dialer.

              Fixes golang/go#27874
              Fixes golang/go#19354
              Fixes golang/go#17759
              Fixes golang/go#13455

              Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
              GitHub-Last-Rev: 72945cd4cc53f435072da1485eadae8f4f6ba1fb

              GitHub-Pull-Request: golang/net#38
              ---
              A proxy/dial.go
              A proxy/dial_test.go
              M proxy/direct.go
              M proxy/per_host.go
              M proxy/per_host_test.go
              M proxy/proxy.go
              M proxy/socks5.go
              7 files changed, 254 insertions(+), 18 deletions(-)

              To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: net
              Gerrit-Branch: master
              Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
              Gerrit-Change-Number: 168921
              Gerrit-PatchSet: 11
              Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
              Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
              Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
              Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
              Gerrit-MessageType: newpatchset

              Jacob Blain Christen (Gerrit)

              unread,
              May 1, 2019, 6:34:55 PM5/1/19
              to Gerrit Bot, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

              adjusted argument order, as suggested, for dialContext()

              View Change

              1 comment:

                • Done

              To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: net
              Gerrit-Branch: master
              Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
              Gerrit-Change-Number: 168921
              Gerrit-PatchSet: 11
              Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
              Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
              Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
              Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
              Gerrit-Comment-Date: Wed, 01 May 2019 22:34:49 +0000

              Brad Fitzpatrick (Gerrit)

              unread,
              May 2, 2019, 11:33:44 AM5/2/19
              to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

              View Change

              1 comment:

                • I don't follow. The forward Dialer is an optional implementation to be used instead of net.Dialer. […]

                  I'm saying we're not using the context on line 25 (the one with the underscore currently).

                  But in the other file in this CL you do the whole trick with the goroutine racing (and the temporary goroutine leak) when the dialer doesn't support ContextDialer, as is the case on this line.

                  So I think we should do the same thing here, so a the SOCKS dialer's DialContext respects the context, even if the underlying forward Dialer doesn't. (even if it means we leak a goroutine for a bit until the connection finally times out by the operating system or whatever)

                  But since you have that code already, I'd put it in an internal package where you can use it from here and from the other location.

              To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: net
              Gerrit-Branch: master
              Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
              Gerrit-Change-Number: 168921
              Gerrit-PatchSet: 11
              Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
              Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
              Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
              Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
              Gerrit-Comment-Date: Thu, 02 May 2019 15:33:41 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              Comment-In-Reply-To: Brad Fitzpatrick <brad...@golang.org>

              Jacob Blain Christen (Gerrit)

              unread,
              May 2, 2019, 1:36:17 PM5/2/19
              to Gerrit Bot, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

              View Change

              1 comment:

                • I'm saying we're not using the context on line 25 (the one with the underscore currently). […]

                  Ah, I see. I do like that idea but it is complicated by the proxy.Dialer interface type in the dialContext helper func signature. This is a mess that I was trying to avoid because it will cause some duplication honoring the context-less Dial receiver.

                  Yes, it all comes back to the proxy.Dialer being an interface type. I'll take a stab at implementing your suggestion.

              To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: net
              Gerrit-Branch: master
              Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
              Gerrit-Change-Number: 168921
              Gerrit-PatchSet: 11
              Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
              Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
              Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
              Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
              Gerrit-Comment-Date: Thu, 02 May 2019 17:36:12 +0000

              Gerrit Bot (Gerrit)

              unread,
              May 2, 2019, 2:14:58 PM5/2/19
              to Jacob Blain Christen, Gobot Gobot, Brad Fitzpatrick, goph...@pubsubhelper.golang.org, Ian Lance Taylor, golang-co...@googlegroups.com

              Gerrit Bot uploaded patch set #12 to this change.

              View Change

              proxy: add Dial (with context)

              The existing API does not allow client code to take advantage of Dialer implementations that implement DialContext receivers. This a familiar API, see net.Dialer.

              Fixes golang/go#27874
              Fixes golang/go#19354
              Fixes golang/go#17759
              Fixes golang/go#13455

              Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
              GitHub-Last-Rev: b0a372707fc4c45772f19b1b886c8823dd613810

              GitHub-Pull-Request: golang/net#38
              ---
              A proxy/dial.go
              A proxy/dial_test.go
              M proxy/direct.go
              M proxy/per_host.go
              M proxy/per_host_test.go
              M proxy/proxy.go
              M proxy/socks5.go
              7 files changed, 254 insertions(+), 18 deletions(-)

              To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: net
              Gerrit-Branch: master
              Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
              Gerrit-Change-Number: 168921
              Gerrit-PatchSet: 12
              Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
              Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
              Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
              Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
              Gerrit-MessageType: newpatchset

              Brad Fitzpatrick (Gerrit)

              unread,
              May 2, 2019, 2:17:26 PM5/2/19
              to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

              Patch set 12:Run-TryBot +1Code-Review +2

              View Change

                To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: net
                Gerrit-Branch: master
                Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
                Gerrit-Change-Number: 168921
                Gerrit-PatchSet: 12
                Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
                Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
                Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
                Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
                Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
                Gerrit-Comment-Date: Thu, 02 May 2019 18:17:23 +0000

                Gobot Gobot (Gerrit)

                unread,
                May 2, 2019, 2:17:29 PM5/2/19
                to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

                TryBots beginning. Status page: https://farmer.golang.org/try?commit=9a1750e0

                View Change

                  To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-Project: net
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
                  Gerrit-Change-Number: 168921
                  Gerrit-PatchSet: 12
                  Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
                  Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
                  Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                  Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
                  Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
                  Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
                  Gerrit-Comment-Date: Thu, 02 May 2019 18:17:26 +0000

                  Jacob Blain Christen (Gerrit)

                  unread,
                  May 2, 2019, 2:20:34 PM5/2/19
                  to Gerrit Bot, goph...@pubsubhelper.golang.org, Gobot Gobot, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

                  View Change

                  1 comment:

                    • Ah, I see. I do like that idea but it is complicated by the proxy. […]

                      Since dialContext was not exported and all uses of it are at the proxy package level I just decided to call it directly. This is a smaller change to the package-private API than pushing it down into an internal package.

                      Also, pushing it down into an internal package screamed for a test for the dialContext helper func which I can see I should probably implement now.

                  To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-Project: net
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
                  Gerrit-Change-Number: 168921
                  Gerrit-PatchSet: 12
                  Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
                  Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
                  Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                  Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
                  Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
                  Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
                  Gerrit-Comment-Date: Thu, 02 May 2019 18:20:30 +0000

                  Gobot Gobot (Gerrit)

                  unread,
                  May 2, 2019, 2:21:02 PM5/2/19
                  to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Ian Lance Taylor, golang-co...@googlegroups.com

                  TryBots are happy.

                  Patch set 12:TryBot-Result +1

                  View Change

                    To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

                    Gerrit-Project: net
                    Gerrit-Branch: master
                    Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
                    Gerrit-Change-Number: 168921
                    Gerrit-PatchSet: 12
                    Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
                    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
                    Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                    Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
                    Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
                    Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
                    Gerrit-Comment-Date: Thu, 02 May 2019 18:20:59 +0000

                    Brad Fitzpatrick (Gerrit)

                    unread,
                    May 2, 2019, 2:39:28 PM5/2/19
                    to Gerrit Bot, Jacob Blain Christen, goph...@pubsubhelper.golang.org, Brad Fitzpatrick, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

                    View Change

                    1 comment:

                      • Since dialContext was not exported and all uses of it are at the proxy package level I just decided […]

                        My mistake. I didn't notice this was in the same package. I forgot we split it off into net/internal/socks earlier.

                    To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

                    Gerrit-Project: net
                    Gerrit-Branch: master
                    Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
                    Gerrit-Change-Number: 168921
                    Gerrit-PatchSet: 12
                    Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
                    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
                    Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                    Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
                    Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
                    Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
                    Gerrit-Comment-Date: Thu, 02 May 2019 18:39:24 +0000

                    Brad Fitzpatrick (Gerrit)

                    unread,
                    May 2, 2019, 2:39:31 PM5/2/19
                    to Gerrit Bot, Brad Fitzpatrick, Jacob Blain Christen, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Gobot Gobot, Ian Lance Taylor, golang-co...@googlegroups.com

                    Brad Fitzpatrick merged this change.

                    View Change

                    Approvals: Brad Fitzpatrick: Looks good to me, approved; Run TryBots Gobot Gobot: TryBots succeeded
                    proxy: add Dial (with context)

                    The existing API does not allow client code to take advantage of Dialer implementations that implement DialContext receivers. This a familiar API, see net.Dialer.

                    Fixes golang/go#27874
                    Fixes golang/go#19354
                    Fixes golang/go#17759
                    Fixes golang/go#13455

                    Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
                    GitHub-Last-Rev: b0a372707fc4c45772f19b1b886c8823dd613810
                    GitHub-Pull-Request: golang/net#38
                    Reviewed-on: https://go-review.googlesource.com/c/net/+/168921
                    Reviewed-by: Brad Fitzpatrick <brad...@golang.org>
                    Run-TryBot: Brad Fitzpatrick <brad...@golang.org>
                    TryBot-Result: Gobot Gobot <go...@golang.org>

                    ---
                    A proxy/dial.go
                    A proxy/dial_test.go
                    M proxy/direct.go
                    M proxy/per_host.go
                    M proxy/per_host_test.go
                    M proxy/proxy.go
                    M proxy/socks5.go
                    7 files changed, 254 insertions(+), 18 deletions(-)

                    diff --git a/proxy/dial.go b/proxy/dial.go
                    new file mode 100644
                    index 0000000..811c2e4
                    --- /dev/null
                    +++ b/proxy/dial.go
                    @@ -0,0 +1,54 @@
                    +// Copyright 2019 The Go Authors. All rights reserved.
                    +// Use of this source code is governed by a BSD-style
                    +// license that can be found in the LICENSE file.
                    +
                    +package proxy
                    +
                    +import (
                    + "context"
                    + "net"
                    +)
                    +
                    +// A ContextDialer dials using a context.
                    +type ContextDialer interface {
                    + DialContext(ctx context.Context, network, address string) (net.Conn, error)
                    +}
                    +
                    +// Dial works like DialContext on net.Dialer but using a dialer returned by FromEnvironment.
                    +//
                    +// The passed ctx is only used for returning the Conn, not the lifetime of the Conn.
                    +//
                    +// Custom dialers (registered via RegisterDialerType) that do not implement ContextDialer
                    +// can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout.
                    +//
                    +// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
                    +func Dial(ctx context.Context, network, address string) (net.Conn, error) {
                    + d := FromEnvironment()
                    + if xd, ok := d.(ContextDialer); ok {
                    + return xd.DialContext(ctx, network, address)
                    + }
                    + return dialContext(ctx, d, network, address)
                    +}
                    +
                    +// WARNING: this can leak a goroutine for as long as the underlying Dialer implementation takes to timeout
                    +// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
                    +func dialContext(ctx context.Context, d Dialer, network, address string) (net.Conn, error) {
                    + var (
                    + conn net.Conn
                    + done = make(chan struct{}, 1)
                    + err error
                    + )
                    + go func() {
                    + conn, err = d.Dial(network, address)
                    + close(done)
                    + if conn != nil && ctx.Err() != nil {
                    + conn.Close()
                    + }
                    + }()
                    + select {
                    + case <-ctx.Done():
                    + err = ctx.Err()
                    + case <-done:
                    + }
                    + return conn, err
                    +}
                    diff --git a/proxy/dial_test.go b/proxy/dial_test.go
                    new file mode 100644
                    index 0000000..3edab49
                    --- /dev/null
                    +++ b/proxy/dial_test.go
                    @@ -0,0 +1,131 @@
                    +// Copyright 2019 The Go Authors. All rights reserved.
                    +// Use of this source code is governed by a BSD-style
                    +// license that can be found in the LICENSE file.
                    +
                    +package proxy
                    +
                    +import (
                    + "context"
                    + "fmt"
                    + "net"
                    + "os"
                    + "testing"
                    + "time"
                    +
                    + "golang.org/x/net/internal/sockstest"
                    +)
                    +
                    +func TestDial(t *testing.T) {
                    + ResetProxyEnv()
                    + t.Run("DirectWithCancel", func(t *testing.T) {
                    + defer ResetProxyEnv()
                    + l, err := net.Listen("tcp", "127.0.0.1:0")
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + defer l.Close()
                    + _, port, err := net.SplitHostPort(l.Addr().String())
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + ctx, cancel := context.WithCancel(context.Background())
                    + defer cancel()
                    + c, err := Dial(ctx, l.Addr().Network(), net.JoinHostPort("", port))
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + c.Close()
                    + })
                    + t.Run("DirectWithTimeout", func(t *testing.T) {
                    + defer ResetProxyEnv()
                    + l, err := net.Listen("tcp", "127.0.0.1:0")
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + defer l.Close()
                    + _, port, err := net.SplitHostPort(l.Addr().String())
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
                    + defer cancel()
                    + c, err := Dial(ctx, l.Addr().Network(), net.JoinHostPort("", port))
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + c.Close()
                    + })
                    + t.Run("DirectWithTimeoutExceeded", func(t *testing.T) {
                    + defer ResetProxyEnv()
                    + l, err := net.Listen("tcp", "127.0.0.1:0")
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + defer l.Close()
                    + _, port, err := net.SplitHostPort(l.Addr().String())
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
                    + time.Sleep(time.Millisecond)
                    + defer cancel()
                    + c, err := Dial(ctx, l.Addr().Network(), net.JoinHostPort("", port))
                    + if err == nil {
                    + defer c.Close()
                    + t.Fatal("failed to timeout")
                    + }
                    + })
                    + t.Run("SOCKS5", func(t *testing.T) {
                    + defer ResetProxyEnv()
                    + s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + defer s.Close()
                    + if err = os.Setenv("ALL_PROXY", fmt.Sprintf("socks5://%s", s.Addr().String())); err != nil {
                    + t.Fatal(err)
                    + }
                    + c, err := Dial(context.Background(), s.TargetAddr().Network(), s.TargetAddr().String())
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + c.Close()
                    + })
                    + t.Run("SOCKS5WithTimeout", func(t *testing.T) {
                    + defer ResetProxyEnv()
                    + s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + defer s.Close()
                    + if err = os.Setenv("ALL_PROXY", fmt.Sprintf("socks5://%s", s.Addr().String())); err != nil {
                    + t.Fatal(err)
                    + }
                    + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
                    + defer cancel()
                    + c, err := Dial(ctx, s.TargetAddr().Network(), s.TargetAddr().String())
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + c.Close()
                    + })
                    + t.Run("SOCKS5WithTimeoutExceeded", func(t *testing.T) {
                    + defer ResetProxyEnv()
                    + s, err := sockstest.NewServer(sockstest.NoAuthRequired, sockstest.NoProxyRequired)
                    + if err != nil {
                    + t.Fatal(err)
                    + }
                    + defer s.Close()
                    + if err = os.Setenv("ALL_PROXY", fmt.Sprintf("socks5://%s", s.Addr().String())); err != nil {
                    + t.Fatal(err)
                    + }
                    + ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
                    + time.Sleep(time.Millisecond)
                    + defer cancel()
                    + c, err := Dial(ctx, s.TargetAddr().Network(), s.TargetAddr().String())
                    + if err == nil {
                    + defer c.Close()
                    + t.Fatal("failed to timeout")
                    + }
                    + })
                    +}
                    diff --git a/proxy/direct.go b/proxy/direct.go
                    index 4c5ad88..26b51c3 100644
                    --- a/proxy/direct.go
                    +++ b/proxy/direct.go
                    @@ -5,6 +5,7 @@
                    package proxy

                    import (
                    + "context"
                    "net"
                    )

                    @@ -13,6 +14,13 @@
                    // Direct is a direct proxy: one that makes network connections directly.
                    var Direct = direct{}

                    +// Dial directly invokes net.Dial with the supplied parameters.
                    func (direct) Dial(network, addr string) (net.Conn, error) {
                    return net.Dial(network, addr)
                    }
                    +
                    +// DialContext instantiates a net.Dialer and invokes its DialContext receiver with the supplied parameters.
                    +func (direct) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
                    + var d net.Dialer
                    + return d.DialContext(ctx, network, addr)
                    +}
                    diff --git a/proxy/per_host.go b/proxy/per_host.go
                    index 0689bb6..573fe79 100644
                    --- a/proxy/per_host.go
                    +++ b/proxy/per_host.go
                    @@ -5,6 +5,7 @@
                    package proxy

                    import (
                    + "context"
                    "net"
                    "strings"
                    )
                    @@ -41,6 +42,20 @@
                    return p.dialerForRequest(host).Dial(network, addr)
                    }

                    +// DialContext connects to the address addr on the given network through either
                    +// defaultDialer or bypass.
                    +func (p *PerHost) DialContext(ctx context.Context, network, addr string) (c net.Conn, err error) {
                    + host, _, err := net.SplitHostPort(addr)
                    + if err != nil {
                    + return nil, err
                    + }
                    + d := p.dialerForRequest(host)
                    + if x, ok := d.(ContextDialer); ok {
                    + return x.DialContext(ctx, network, addr)
                    + }
                    + return dialContext(ctx, d, network, addr)
                    +}
                    +
                    func (p *PerHost) dialerForRequest(host string) Dialer {
                    if ip := net.ParseIP(host); ip != nil {
                    for _, net := range p.bypassNetworks {
                    diff --git a/proxy/per_host_test.go b/proxy/per_host_test.go
                    index a7d8095..0447eb4 100644
                    --- a/proxy/per_host_test.go
                    +++ b/proxy/per_host_test.go
                    @@ -5,6 +5,7 @@
                    package proxy

                    import (
                    + "context"
                    "errors"
                    "net"
                    "reflect"
                    @@ -21,10 +22,6 @@
                    }

                    func TestPerHost(t *testing.T) {
                    - var def, bypass recordingProxy
                    - perHost := NewPerHost(&def, &bypass)
                    - perHost.AddFromString("localhost,*.zone,127.0.0.1,10.0.0.1/8,1000::/16")
                    -
                    expectedDef := []string{
                    "example.com:123",
                    "1.2.3.4:123",
                    @@ -39,17 +36,41 @@
                    "[1000::]:123",
                    }

                    - for _, addr := range expectedDef {
                    - perHost.Dial("tcp", addr)
                    - }
                    - for _, addr := range expectedBypass {
                    - perHost.Dial("tcp", addr)
                    - }
                    + t.Run("Dial", func(t *testing.T) {
                    + var def, bypass recordingProxy
                    + perHost := NewPerHost(&def, &bypass)
                    + perHost.AddFromString("localhost,*.zone,127.0.0.1,10.0.0.1/8,1000::/16")
                    + for _, addr := range expectedDef {
                    + perHost.Dial("tcp", addr)
                    + }
                    + for _, addr := range expectedBypass {
                    + perHost.Dial("tcp", addr)
                    + }

                    - if !reflect.DeepEqual(expectedDef, def.addrs) {
                    - t.Errorf("Hosts which went to the default proxy didn't match. Got %v, want %v", def.addrs, expectedDef)
                    - }
                    - if !reflect.DeepEqual(expectedBypass, bypass.addrs) {
                    - t.Errorf("Hosts which went to the bypass proxy didn't match. Got %v, want %v", bypass.addrs, expectedBypass)
                    - }
                    + if !reflect.DeepEqual(expectedDef, def.addrs) {
                    + t.Errorf("Hosts which went to the default proxy didn't match. Got %v, want %v", def.addrs, expectedDef)
                    + }
                    + if !reflect.DeepEqual(expectedBypass, bypass.addrs) {
                    + t.Errorf("Hosts which went to the bypass proxy didn't match. Got %v, want %v", bypass.addrs, expectedBypass)
                    + }
                    + })
                    +
                    + t.Run("DialContext", func(t *testing.T) {
                    + var def, bypass recordingProxy
                    + perHost := NewPerHost(&def, &bypass)
                    + perHost.AddFromString("localhost,*.zone,127.0.0.1,10.0.0.1/8,1000::/16")
                    + for _, addr := range expectedDef {
                    + perHost.DialContext(context.Background(), "tcp", addr)
                    + }
                    + for _, addr := range expectedBypass {
                    + perHost.DialContext(context.Background(), "tcp", addr)
                    + }
                    +
                    + if !reflect.DeepEqual(expectedDef, def.addrs) {
                    + t.Errorf("Hosts which went to the default proxy didn't match. Got %v, want %v", def.addrs, expectedDef)
                    + }
                    + if !reflect.DeepEqual(expectedBypass, bypass.addrs) {
                    + t.Errorf("Hosts which went to the bypass proxy didn't match. Got %v, want %v", bypass.addrs, expectedBypass)
                    + }
                    + })
                    }
                    diff --git a/proxy/proxy.go b/proxy/proxy.go
                    index f6026b9..37d3cab 100644
                    --- a/proxy/proxy.go
                    +++ b/proxy/proxy.go
                    @@ -15,6 +15,7 @@
                    )

                    // A Dialer is a means to establish a connection.
                    +// Custom dialers should also implement ContextDialer.
                    type Dialer interface {
                    // Dial connects to the given address via the proxy.
                    Dial(network, addr string) (c net.Conn, err error)
                    diff --git a/proxy/socks5.go b/proxy/socks5.go
                    index 56345ec..c91651f 100644
                    --- a/proxy/socks5.go
                    +++ b/proxy/socks5.go
                    @@ -17,8 +17,14 @@
                    func SOCKS5(network, address string, auth *Auth, forward Dialer) (Dialer, error) {
                    d := socks.NewDialer(network, address)
                    if forward != nil {
                    - d.ProxyDial = func(_ context.Context, network string, address string) (net.Conn, error) {
                    - return forward.Dial(network, address)
                    + if f, ok := forward.(ContextDialer); ok {
                    + d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {
                    + return f.DialContext(ctx, network, address)
                    + }
                    + } else {
                    + d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {
                    + return dialContext(ctx, forward, network, address)
                    + }
                    }
                    }
                    if auth != nil {

                    To view, visit change 168921. To unsubscribe, or for help writing mail filters, visit settings.

                    Gerrit-Project: net
                    Gerrit-Branch: master
                    Gerrit-Change-Id: I0f247783d2037da28c9917db99adda51db1647bd
                    Gerrit-Change-Number: 168921
                    Gerrit-PatchSet: 13
                    Gerrit-Owner: Gerrit Bot <letsus...@gmail.com>
                    Gerrit-Reviewer: Brad Fitzpatrick <brad...@golang.org>
                    Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                    Gerrit-Reviewer: Jacob Blain Christen <dweo...@gmail.com>
                    Gerrit-Reviewer: Mikio Hara <mikioh.publi...@gmail.com>
                    Gerrit-CC: Ian Lance Taylor <ia...@golang.org>
                    Gerrit-MessageType: merged
                    Reply all
                    Reply to author
                    Forward
                    0 new messages