diff options
| author | davy <davy.wybiral@gmail.com> | 2019-07-03 16:55:03 -0500 |
|---|---|---|
| committer | davy <davy.wybiral@gmail.com> | 2019-07-03 16:55:03 -0500 |
| commit | 442e3c6dcf35cc1ca508e617f94198637e761bc8 (patch) | |
| tree | 8d6b6210ce98385180766fa14984e2c47f779050 /vendor/golang.org/x/net/proxy/dial.go | |
| parent | 53bc0c19fadcfb7ae9a608ed1f9f6268d1670368 (diff) | |
dep ensurev0.1.0
Diffstat (limited to 'vendor/golang.org/x/net/proxy/dial.go')
| -rw-r--r-- | vendor/golang.org/x/net/proxy/dial.go | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/proxy/dial.go b/vendor/golang.org/x/net/proxy/dial.go new file mode 100644 index 0000000..811c2e4 --- /dev/null +++ b/vendor/golang.org/x/net/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 +} |
