Files
pansou/util/http_util.go
fish2018 5004e4f99f update
2025-07-12 19:53:44 +08:00

126 lines
2.9 KiB
Go

package util
import (
"context"
"crypto/tls"
"io"
"net"
"net/http"
"net/url"
"time"
"golang.org/x/net/proxy"
"pansou/config"
)
// 全局HTTP客户端
var httpClient *http.Client
// InitHTTPClient 初始化HTTP客户端
func InitHTTPClient() {
// 创建传输配置
transport := &http.Transport{
// 启用HTTP/2
ForceAttemptHTTP2: true,
// TLS配置
TLSClientConfig: &tls.Config{
InsecureSkipVerify: false, // 生产环境应设为false
},
// 连接池优化
MaxIdleConns: 100,
MaxIdleConnsPerHost: 20,
MaxConnsPerHost: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
// TCP连接优化
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
}
// 如果配置了代理,设置代理
if config.AppConfig.UseProxy {
proxyURL, err := url.Parse(config.AppConfig.ProxyURL)
if err == nil {
// 根据代理类型设置不同的处理方式
if proxyURL.Scheme == "socks5" {
// 创建SOCKS5代理拨号器
dialer, err := proxy.FromURL(proxyURL, proxy.Direct)
if err == nil {
transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.Dial(network, addr)
}
}
} else {
// HTTP/HTTPS代理
transport.Proxy = http.ProxyURL(proxyURL)
}
}
}
// 创建客户端
httpClient = &http.Client{
Transport: transport,
Timeout: time.Duration(60) * time.Second,
}
}
// GetHTTPClient 获取HTTP客户端
func GetHTTPClient() *http.Client {
if httpClient == nil {
InitHTTPClient()
}
return httpClient
}
// FetchHTML 获取HTML内容
func FetchHTML(targetURL string) (string, error) {
// 使用优化后的HTTP客户端
client := GetHTTPClient()
// 创建请求
req, err := http.NewRequest("GET", targetURL, nil)
if err != nil {
return "", err
}
// 设置请求头
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Upgrade-Insecure-Requests", "1")
// 发送请求
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
// 读取响应体
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
// BuildSearchURL 构建搜索URL
func BuildSearchURL(channel string, keyword string, nextPageParam string) string {
baseURL := "https://t.me/s/" + channel
if keyword != "" {
baseURL += "?q=" + url.QueryEscape(keyword)
if nextPageParam != "" {
baseURL += "&" + nextPageParam
}
}
return baseURL
}