Files
exchange_go/common/helper/proxy.go
2025-02-06 11:14:33 +08:00

80 lines
2.0 KiB
Go

package helper
import (
"context"
"errors"
"fmt"
"net"
"net/http"
"net/url"
"strings"
"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{}
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
}