NewProxyHttpClient 创建支持代理的 HTTP 客户端
(proxyURL string)
| 30 | |
| 31 | // NewProxyHttpClient 创建支持代理的 HTTP 客户端 |
| 32 | func NewProxyHttpClient(proxyURL string) (*http.Client, error) { |
| 33 | if proxyURL == "" { |
| 34 | return http.DefaultClient, nil |
| 35 | } |
| 36 | |
| 37 | parsedURL, err := url.Parse(proxyURL) |
| 38 | if err != nil { |
| 39 | return nil, err |
| 40 | } |
| 41 | |
| 42 | switch parsedURL.Scheme { |
| 43 | case "http", "https": |
| 44 | return &http.Client{ |
| 45 | Transport: &http.Transport{ |
| 46 | Proxy: http.ProxyURL(parsedURL), |
| 47 | }, |
| 48 | }, nil |
| 49 | |
| 50 | case "socks5", "socks5h": |
| 51 | // 获取认证信息 |
| 52 | var auth *proxy.Auth |
| 53 | if parsedURL.User != nil { |
| 54 | auth = &proxy.Auth{ |
| 55 | User: parsedURL.User.Username(), |
| 56 | Password: "", |
| 57 | } |
| 58 | if password, ok := parsedURL.User.Password(); ok { |
| 59 | auth.Password = password |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | // 创建 SOCKS5 代理拨号器 |
| 64 | // proxy.SOCKS5 使用 tcp 参数,所有 TCP 连接包括 DNS 查询都将通过代理进行。行为与 socks5h 相同 |
| 65 | dialer, err := proxy.SOCKS5("tcp", parsedURL.Host, auth, proxy.Direct) |
| 66 | if err != nil { |
| 67 | return nil, err |
| 68 | } |
| 69 | |
| 70 | return &http.Client{ |
| 71 | Transport: &http.Transport{ |
| 72 | DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { |
| 73 | return dialer.Dial(network, addr) |
| 74 | }, |
| 75 | }, |
| 76 | }, nil |
| 77 | |
| 78 | default: |
| 79 | return nil, fmt.Errorf("unsupported proxy scheme: %s", parsedURL.Scheme) |
| 80 | } |
| 81 | } |
no outgoing calls
no test coverage detected