mirror of
https://github.com/sky22333/hubproxy.git
synced 2026-08-30 12:37:04 +08:00
113 lines
2.9 KiB
Go
113 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
|
|
"golang.org/x/net/proxy"
|
|
)
|
|
|
|
var (
|
|
// 全局HTTP客户端 - 用于代理请求(长超时)
|
|
globalHTTPClient *http.Client
|
|
// 搜索HTTP客户端 - 用于API请求(短超时)
|
|
searchHTTPClient *http.Client
|
|
)
|
|
|
|
// initHTTPClients 初始化HTTP客户端
|
|
func initHTTPClients() {
|
|
cfg := GetConfig()
|
|
|
|
// 创建DialContext函数,支持SOCKS5代理
|
|
createDialContext := func(timeout time.Duration) func(ctx context.Context, network, addr string) (net.Conn, error) {
|
|
if cfg.Proxy.Socks5 == "" {
|
|
// 没有配置代理,使用直连
|
|
dialer := &net.Dialer{
|
|
Timeout: timeout,
|
|
KeepAlive: 30 * time.Second,
|
|
}
|
|
return dialer.DialContext
|
|
}
|
|
|
|
// 解析SOCKS5代理URL
|
|
proxyURL, err := url.Parse(cfg.Proxy.Socks5)
|
|
if err != nil {
|
|
log.Printf("SOCKS5代理配置错误,使用直连: %v", err)
|
|
dialer := &net.Dialer{
|
|
Timeout: timeout,
|
|
KeepAlive: 30 * time.Second,
|
|
}
|
|
return dialer.DialContext
|
|
}
|
|
|
|
// 创建基础dialer
|
|
baseDialer := &net.Dialer{
|
|
Timeout: timeout,
|
|
KeepAlive: 30 * time.Second,
|
|
}
|
|
|
|
// 创建SOCKS5代理dialer
|
|
var auth *proxy.Auth
|
|
if proxyURL.User != nil {
|
|
if password, ok := proxyURL.User.Password(); ok {
|
|
auth = &proxy.Auth{
|
|
User: proxyURL.User.Username(),
|
|
Password: password,
|
|
}
|
|
}
|
|
}
|
|
|
|
socks5Dialer, err := proxy.SOCKS5("tcp", proxyURL.Host, auth, baseDialer)
|
|
if err != nil {
|
|
log.Printf("创建SOCKS5代理失败,使用直连: %v", err)
|
|
return baseDialer.DialContext
|
|
}
|
|
|
|
log.Printf("使用SOCKS5代理: %s", proxyURL.Host)
|
|
|
|
// 返回带上下文的dial函数
|
|
return func(ctx context.Context, network, addr string) (net.Conn, error) {
|
|
return socks5Dialer.Dial(network, addr)
|
|
}
|
|
}
|
|
|
|
// 代理客户端配置 - 适用于大文件传输
|
|
globalHTTPClient = &http.Client{
|
|
Transport: &http.Transport{
|
|
DialContext: createDialContext(30 * time.Second),
|
|
MaxIdleConns: 1000,
|
|
MaxIdleConnsPerHost: 1000,
|
|
IdleConnTimeout: 90 * time.Second,
|
|
TLSHandshakeTimeout: 10 * time.Second,
|
|
ExpectContinueTimeout: 1 * time.Second,
|
|
ResponseHeaderTimeout: 300 * time.Second,
|
|
},
|
|
}
|
|
|
|
// 搜索客户端配置 - 适用于API调用
|
|
searchHTTPClient = &http.Client{
|
|
Timeout: 10 * time.Second,
|
|
Transport: &http.Transport{
|
|
DialContext: createDialContext(5 * time.Second),
|
|
MaxIdleConns: 100,
|
|
MaxIdleConnsPerHost: 10,
|
|
IdleConnTimeout: 90 * time.Second,
|
|
TLSHandshakeTimeout: 5 * time.Second,
|
|
DisableCompression: false,
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetGlobalHTTPClient 获取全局HTTP客户端(用于代理)
|
|
func GetGlobalHTTPClient() *http.Client {
|
|
return globalHTTPClient
|
|
}
|
|
|
|
// GetSearchHTTPClient 获取搜索HTTP客户端(用于API调用)
|
|
func GetSearchHTTPClient() *http.Client {
|
|
return searchHTTPClient
|
|
} |