diff --git a/README.md b/README.md index 229da37..fa56138 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,10 @@ enabled = false # 是否开启速率限制 rateMethod = "total" # "ip" or "total" 速率限制方式 ratePerMinute = 180 # 每分钟限制请求数量 burst = 5 # 突发请求数量 + +[proxy] +enabled = false # 是否使用代理连接 +url = "socks5://127.0.0.1:1080" # "http://127.0.0.1:7890" 支持HTTP代理和SOCKS5代理 支持多级SOCKS5代理 ``` ### 黑名单配置 diff --git a/config/config.go b/config/config.go index de72a4b..32b64ce 100644 --- a/config/config.go +++ b/config/config.go @@ -13,6 +13,7 @@ type Config struct { Blacklist BlacklistConfig Whitelist WhitelistConfig RateLimit RateLimitConfig + Proxy ProxyConfig } type ServerConfig struct { @@ -62,6 +63,11 @@ type RateLimitConfig struct { Burst int `toml:"burst"` } +type ProxyConfig struct { + Enabled bool `toml:"enabled"` + Url string `toml:"url"` +} + // LoadConfig 从 TOML 配置文件加载配置 func LoadConfig(filePath string) (*Config, error) { var config Config diff --git a/config/config.toml b/config/config.toml index d981545..b720432 100644 --- a/config/config.toml +++ b/config/config.toml @@ -36,3 +36,7 @@ enabled = false rateMethod = "total" # "ip" or "total" ratePerMinute = 180 burst = 5 + +[proxy] +enabled = false +url = "socks5://127.0.0.1:1080" # "http://127.0.0.1:7890" \ No newline at end of file diff --git a/go.mod b/go.mod index 6d5d294..526095a 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/BurntSushi/toml v1.4.0 github.com/WJQSERVER-STUDIO/go-utils/logger v1.3.0 github.com/gin-gonic/gin v1.10.0 + golang.org/x/net v0.34.0 golang.org/x/time v0.10.0 ) @@ -31,7 +32,6 @@ require ( github.com/ugorji/go/codec v1.2.12 // indirect golang.org/x/arch v0.14.0 // indirect golang.org/x/crypto v0.33.0 // indirect - golang.org/x/net v0.34.0 // indirect golang.org/x/sys v0.30.0 // indirect golang.org/x/text v0.22.0 // indirect google.golang.org/protobuf v1.36.5 // indirect diff --git a/main.go b/main.go index 9bd6faa..88606f7 100644 --- a/main.go +++ b/main.go @@ -100,8 +100,8 @@ func setupRateLimit(cfg *config.Config) { } } -func InitReq() { - proxy.InitReq() +func InitReq(cfg *config.Config) { + proxy.InitReq(cfg) } func init() { @@ -109,7 +109,7 @@ func init() { flag.Parse() loadConfig() setupLogger(cfg) - InitReq() + InitReq(cfg) loadlist(cfg) setupRateLimit(cfg) diff --git a/proxy/chunkreq.go b/proxy/chunkreq.go index 893b524..dc8c555 100644 --- a/proxy/chunkreq.go +++ b/proxy/chunkreq.go @@ -22,9 +22,9 @@ var ( BufferPool *sync.Pool ) -func InitReq() { - initChunkedHTTPClient() - initGitHTTPClient() +func InitReq(cfg *config.Config) { + initChunkedHTTPClient(cfg) + initGitHTTPClient(cfg) // 初始化固定大小的缓存池 BufferPool = &sync.Pool{ @@ -34,7 +34,7 @@ func InitReq() { } } -func initChunkedHTTPClient() { +func initChunkedHTTPClient(cfg *config.Config) { ctr = &http.Transport{ MaxIdleConns: 100, MaxConnsPerHost: 60, @@ -47,6 +47,7 @@ func initChunkedHTTPClient() { KeepAlive: 30 * time.Second, }).DialContext, } + initTransport(cfg, ctr) cclient = &http.Client{ Transport: ctr, } diff --git a/proxy/dial.go b/proxy/dial.go new file mode 100644 index 0000000..69d35ab --- /dev/null +++ b/proxy/dial.go @@ -0,0 +1,61 @@ +package proxy + +import ( + "ghproxy/config" + "net/http" + "net/url" + "strings" + + "golang.org/x/net/proxy" +) + +func newProxyDial(proxyUrls string) proxy.Dialer { + var proxyDialer proxy.Dialer = proxy.Direct + for _, proxyUrl := range strings.Split(proxyUrls, ",") { + urlInfo, err := url.Parse(proxyUrl) + if err != nil { + continue + } + if urlInfo.Scheme != "socks5" { + continue + } + var auth *proxy.Auth = nil + if urlInfo.User != nil { + pwd, ok := urlInfo.User.Password() + if !ok { + continue + } + auth = &proxy.Auth{ + User: urlInfo.User.Username(), + Password: pwd, + } + } + + dialer, err := proxy.SOCKS5("tcp", urlInfo.Host, auth, proxyDialer) + if err == nil { + proxyDialer = dialer + } + } + return proxyDialer +} + +func initTransport(cfg *config.Config, transport *http.Transport) { + if !cfg.Proxy.Enabled { + return + } + if cfg.Proxy.Url == "" { + transport.Proxy = http.ProxyFromEnvironment + return + } + + proxyInfo, err := url.Parse(cfg.Proxy.Url) + if err == nil { + if strings.HasPrefix(cfg.Proxy.Url, "http") { + transport.Proxy = http.ProxyURL(proxyInfo) + } else { + proxyDialer := newProxyDial(cfg.Proxy.Url) + transport.Dial = proxyDialer.Dial + transport.DialContext = proxyDialer.(proxy.ContextDialer).DialContext + } + } +} diff --git a/proxy/gitreq.go b/proxy/gitreq.go index 568a1ac..a03cd09 100644 --- a/proxy/gitreq.go +++ b/proxy/gitreq.go @@ -17,12 +17,13 @@ var ( gtr *http.Transport ) -func initGitHTTPClient() { +func initGitHTTPClient(cfg *config.Config) { gtr = &http.Transport{ MaxIdleConns: 30, MaxConnsPerHost: 30, IdleConnTimeout: 30 * time.Second, } + initTransport(cfg, gtr) gclient = &http.Client{ Transport: gtr, }