Compare commits

...

6 Commits

Author SHA1 Message Date
Sleeyax 88041c35e2
Merge ea5afd45e1 into 9ec25ca502 2024-06-13 13:05:56 +00:00
Corey Daley ea5afd45e1
Merge branch 'main' into http-proxy-tls-fix 2023-08-17 15:10:23 -04:00
Corey Daley fe5bdd86f3
Merge branch 'main' into http-proxy-tls-fix 2023-07-30 14:23:03 -04:00
Sleeyax 36867e9319 Include hostPort in function signature 2022-10-26 19:04:40 +02:00
Sleeyax adb13885c2 Check error 2022-05-14 15:47:30 +02:00
Sleeyax 502bd65db8 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.
2022-05-12 18:06:13 +02:00
2 changed files with 32 additions and 18 deletions

View File

@ -67,6 +67,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, hostPort string, 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.
@ -335,26 +341,34 @@ 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, hostPort, netConn)
if err != nil {
return nil, nil, err
}
} 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
}
} }
} }

View File

@ -35,7 +35,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
} }