package proxy import ( "context" "crypto/tls" "fmt" "net" "net/http" "net/url" "strings" "github.com/gorilla/websocket" "golang.org/x/net/proxy" ) // GetDialer 获取代理拨号器 func GetDialer(proxyType, proxyAddress string) (*websocket.Dialer, error) { if proxyAddress == "" { return &websocket.Dialer{}, nil } if !strings.HasPrefix(proxyAddress, "http://") && !strings.HasPrefix(proxyAddress, "https://") && !strings.HasPrefix(proxyAddress, "socks5://") { proxyAddress = proxyType + "://" + proxyAddress } proxyURL, err := url.Parse(proxyAddress) if err != nil { return nil, fmt.Errorf("failed to parse proxy URL: %v", err) } transport := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: false}, } switch proxyURL.Scheme { case "socks5": return createSocks5Dialer(proxyURL) case "http", "https": transport.Proxy = http.ProxyURL(proxyURL) return &websocket.Dialer{Proxy: transport.Proxy, TLSClientConfig: transport.TLSClientConfig}, nil default: return nil, fmt.Errorf("unsupported proxy scheme: %s", proxyURL.Scheme) } } func createSocks5Dialer(proxyURL *url.URL) (*websocket.Dialer, error) { auth := &proxy.Auth{} if proxyURL.User != nil { auth.User = proxyURL.User.Username() auth.Password, _ = proxyURL.User.Password() } socksDialer, err := proxy.SOCKS5("tcp", proxyURL.Host, auth, proxy.Direct) if err != nil { return nil, fmt.Errorf("failed to create SOCKS5 proxy dialer: %v", err) } return &websocket.Dialer{ NetDialContext: func(ctx context.Context, network, address string) (net.Conn, error) { return socksDialer.Dial(network, address) }, }, nil }