-
Notifications
You must be signed in to change notification settings - Fork 68
Expand file tree
/
Copy pathproxy.go
More file actions
57 lines (53 loc) · 1.62 KB
/
proxy.go
File metadata and controls
57 lines (53 loc) · 1.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package api
import (
"context"
"crypto/tls"
"net"
"net/http"
"net/url"
)
// withProxyTransport modifies the given transport to handle proxying of unix, socks5 and http connections.
//
// Note: baseTransport is considered to be a clone created with transport.Clone()
//
// - If proxyPath is not empty, a unix socket proxy is created.
// - Otherwise, proxyURL is used to determine if we should proxy socks5 / http connections
func withProxyTransport(baseTransport *http.Transport, proxyURL *url.URL, proxyPath string) *http.Transport {
handshakeTLS := func(ctx context.Context, conn net.Conn, addr string) (net.Conn, error) {
// Extract the hostname (without the port) for TLS SNI
host, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
cfg := baseTransport.TLSClientConfig.Clone()
if cfg.ServerName == "" {
cfg.ServerName = host
}
tlsConn := tls.Client(conn, cfg)
if err := tlsConn.HandshakeContext(ctx); err != nil {
tlsConn.Close()
return nil, err
}
return tlsConn, nil
}
if proxyPath != "" {
dial := func(ctx context.Context, _, _ string) (net.Conn, error) {
d := net.Dialer{}
return d.DialContext(ctx, "unix", proxyPath)
}
dialTLS := func(ctx context.Context, network, addr string) (net.Conn, error) {
conn, err := dial(ctx, network, addr)
if err != nil {
return nil, err
}
return handshakeTLS(ctx, conn, addr)
}
baseTransport.DialContext = dial
baseTransport.DialTLSContext = dialTLS
// clear out any system proxy settings
baseTransport.Proxy = nil
} else if proxyURL != nil {
baseTransport.Proxy = http.ProxyURL(proxyURL)
}
return baseTransport
}