mirror of https://github.com/gorilla/websocket.git
Add optional method ProxyTLSConnection (closes #779)
Removed the call to NetDialTLSContext from the HTTP proxy CONNECT step and replaced it with a regular net.Dial in order to prevent connection issues. Custom TLS connections can now be made via the new optional ProxyTLSConnection method, after the proxy connection has been successfully established.
This commit is contained in:
parent
78cf1bc733
commit
502bd65db8
45
client.go
45
client.go
|
@ -65,6 +65,12 @@ type Dialer struct {
|
||||||
// TLSClientConfig is ignored.
|
// TLSClientConfig is ignored.
|
||||||
NetDialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
|
NetDialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||||
|
|
||||||
|
// ProxyTLSConnection specifies the dial function for creating TLS connections through a Proxy. If
|
||||||
|
// ProxyTLSConnection is nil, NetDialTLSContext is used.
|
||||||
|
// If ProxyTLSConnection is set, Dial assumes the TLS handshake is done there and
|
||||||
|
// TLSClientConfig is ignored.
|
||||||
|
ProxyTLSConnection func(ctx context.Context, proxyConn net.Conn) (net.Conn, error)
|
||||||
|
|
||||||
// Proxy specifies a function to return a proxy for a given
|
// Proxy specifies a function to return a proxy for a given
|
||||||
// Request. If the function returns a non-nil error, the
|
// Request. If the function returns a non-nil error, the
|
||||||
// request is aborted with the provided error.
|
// request is aborted with the provided error.
|
||||||
|
@ -333,26 +339,31 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if u.Scheme == "https" && d.NetDialTLSContext == nil {
|
if u.Scheme == "https" {
|
||||||
// If NetDialTLSContext is set, assume that the TLS handshake has already been done
|
if d.ProxyTLSConnection != nil && d.Proxy != nil {
|
||||||
|
// If we are connected to a proxy, perform the TLS handshake through the existing tunnel
|
||||||
|
netConn, err = d.ProxyTLSConnection(ctx, netConn)
|
||||||
|
} else if d.NetDialTLSContext == nil {
|
||||||
|
// If NetDialTLSContext is set, assume that the TLS handshake has already been done
|
||||||
|
|
||||||
cfg := cloneTLSConfig(d.TLSClientConfig)
|
cfg := cloneTLSConfig(d.TLSClientConfig)
|
||||||
if cfg.ServerName == "" {
|
if cfg.ServerName == "" {
|
||||||
cfg.ServerName = hostNoPort
|
cfg.ServerName = hostNoPort
|
||||||
}
|
}
|
||||||
tlsConn := tls.Client(netConn, cfg)
|
tlsConn := tls.Client(netConn, cfg)
|
||||||
netConn = tlsConn
|
netConn = tlsConn
|
||||||
|
|
||||||
if trace != nil && trace.TLSHandshakeStart != nil {
|
if trace != nil && trace.TLSHandshakeStart != nil {
|
||||||
trace.TLSHandshakeStart()
|
trace.TLSHandshakeStart()
|
||||||
}
|
}
|
||||||
err := doHandshake(ctx, tlsConn, cfg)
|
err := doHandshake(ctx, tlsConn, cfg)
|
||||||
if trace != nil && trace.TLSHandshakeDone != nil {
|
if trace != nil && trace.TLSHandshakeDone != nil {
|
||||||
trace.TLSHandshakeDone(tlsConn.ConnectionState(), err)
|
trace.TLSHandshakeDone(tlsConn.ConnectionState(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
proxy.go
2
proxy.go
|
@ -33,7 +33,7 @@ type httpProxyDialer struct {
|
||||||
|
|
||||||
func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
|
func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
|
||||||
hostPort, _ := hostPortNoPort(hpd.proxyURL)
|
hostPort, _ := hostPortNoPort(hpd.proxyURL)
|
||||||
conn, err := hpd.forwardDial(network, hostPort)
|
conn, err := net.Dial(network, hostPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue