package helper import ( "context" "errors" "fmt" "net" "net/http" "net/url" "strings" "time" "golang.org/x/net/proxy" ) /* 创建代理 - @proxyType 代理类别 http\https\socks5 - @proxyAddr 代理地址 userName:password@endpoint:port */ func CreateHtppProxy(proxyType, proxyAddr string, client *http.Client) error { // Set up proxy based on type (HTTP, HTTPS, SOCKS5) transport := &http.Transport{ TLSHandshakeTimeout: 10 * time.Second, } if proxyAddr != "" { if !strings.HasPrefix(proxyAddr, "http://") && !strings.HasPrefix(proxyAddr, "https://") && !strings.HasPrefix(proxyAddr, "socks5://") { proxyAddr = proxyType + "://" + proxyAddr } if proxyType == "" { proxyType = strings.Split(proxyAddr, "://")[0] } switch proxyType { case "http", "https": proxyURL, err := url.Parse(proxyAddr) if err != nil { return errors.New(fmt.Sprintf("invalid proxy URL: %w", err)) } // Check if proxy URL contains credentials if proxyURL.User != nil { username := proxyURL.User.Username() password, _ := proxyURL.User.Password() transport.Proxy = func(req *http.Request) (*url.URL, error) { req.SetBasicAuth(username, password) // Set basic auth headers return proxyURL, nil } } else { transport.Proxy = http.ProxyURL(proxyURL) } case "socks5": proxyURL, err := url.Parse(proxyAddr) if err != nil { return errors.New(fmt.Sprintf("invalid proxy URL: %w", err)) } var auth *proxy.Auth if proxyURL.User != nil { auth = &proxy.Auth{ User: proxyURL.User.Username(), Password: getProxyPassword(proxyURL), } } dialer, err := proxy.SOCKS5("tcp", proxyURL.Host, auth, proxy.Direct) if err != nil { return errors.New(fmt.Sprintf("failed to set up SOCKS5 proxy: %w", err)) } transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { return dialer.Dial(network, addr) } default: return errors.New(fmt.Sprintf("unsupported proxy type: %s", proxyType)) } client.Transport = transport } return nil }