368 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			368 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package httputils
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// http request 工具函数
							 | 
						|||
| 
								 | 
							
								import (
							 | 
						|||
| 
								 | 
							
									"crypto/tls"
							 | 
						|||
| 
								 | 
							
									"errors"
							 | 
						|||
| 
								 | 
							
									"fmt"
							 | 
						|||
| 
								 | 
							
									"io/ioutil"
							 | 
						|||
| 
								 | 
							
									"log"
							 | 
						|||
| 
								 | 
							
									"net"
							 | 
						|||
| 
								 | 
							
									"net/http"
							 | 
						|||
| 
								 | 
							
									"net/url"
							 | 
						|||
| 
								 | 
							
									"strings"
							 | 
						|||
| 
								 | 
							
									"time"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									"github.com/bytedance/sonic"
							 | 
						|||
| 
								 | 
							
									"github.com/valyala/fasthttp"
							 | 
						|||
| 
								 | 
							
									"golang.org/x/net/proxy"
							 | 
						|||
| 
								 | 
							
								)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								var (
							 | 
						|||
| 
								 | 
							
									fastHttpClient = &fasthttp.Client{
							 | 
						|||
| 
								 | 
							
										Name:                "http",
							 | 
						|||
| 
								 | 
							
										MaxConnsPerHost:     10000,
							 | 
						|||
| 
								 | 
							
										MaxIdleConnDuration: 30 * time.Second,
							 | 
						|||
| 
								 | 
							
										ReadTimeout:         50 * time.Second,
							 | 
						|||
| 
								 | 
							
										WriteTimeout:        50 * time.Second,
							 | 
						|||
| 
								 | 
							
										TLSConfig:           &tls.Config{InsecureSkipVerify: true}, // 跳过证书验证
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									clientHuoBi   *http.Client // 火币交易所 HTTP 客户端
							 | 
						|||
| 
								 | 
							
									clientBinance *http.Client // 币安交易所 HTTP 客户端
							 | 
						|||
| 
								 | 
							
								)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func init() {
							 | 
						|||
| 
								 | 
							
									// 克隆默认的 HTTP 传输配置
							 | 
						|||
| 
								 | 
							
									t := http.DefaultTransport.(*http.Transport).Clone()
							 | 
						|||
| 
								 | 
							
									t.MaxIdleConns = 100
							 | 
						|||
| 
								 | 
							
									t.MaxConnsPerHost = 10000
							 | 
						|||
| 
								 | 
							
									t.MaxIdleConnsPerHost = 100
							 | 
						|||
| 
								 | 
							
									t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} // 跳过证书验证
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// 初始化火币交易所 HTTP 客户端
							 | 
						|||
| 
								 | 
							
									clientHuoBi = &http.Client{
							 | 
						|||
| 
								 | 
							
										Timeout:   50 * time.Second, // 请求超时时间
							 | 
						|||
| 
								 | 
							
										Transport: t,
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// 初始化币安交易所 HTTP 客户端
							 | 
						|||
| 
								 | 
							
									clientBinance = &http.Client{
							 | 
						|||
| 
								 | 
							
										Timeout:   50 * time.Second, // 请求超时时间
							 | 
						|||
| 
								 | 
							
										Transport: t,
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/*
							 | 
						|||
| 
								 | 
							
								初始化请求代理
							 | 
						|||
| 
								 | 
							
								- @proxy 代理地址(http) ip:port
							 | 
						|||
| 
								 | 
							
								*/
							 | 
						|||
| 
								 | 
							
								func InitProxy(proxy string) {
							 | 
						|||
| 
								 | 
							
									if proxy != "" {
							 | 
						|||
| 
								 | 
							
										fastHttpClient.Dial = createHTTPProxyDialer(proxy) // 设置代理拨号器
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// net http 请求(币安)
							 | 
						|||
| 
								 | 
							
								func NewHttpRequestBinance(reqMethod, reqUrl, postData string, reqHeaders map[string]string) ([]byte, error) {
							 | 
						|||
| 
								 | 
							
									req, _ := http.NewRequest(reqMethod, reqUrl, strings.NewReader(postData)) // 创建新的 HTTP 请求
							 | 
						|||
| 
								 | 
							
									if req.Header.Get("User-Agent") == "" {
							 | 
						|||
| 
								 | 
							
										req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36") // 设置用户代理
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									if reqHeaders != nil {
							 | 
						|||
| 
								 | 
							
										for k, v := range reqHeaders {
							 | 
						|||
| 
								 | 
							
											req.Header.Add(k, v) // 添加请求头
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									resp, err := clientBinance.Do(req) // 发送请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									defer resp.Body.Close() // 确保关闭响应体
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									bodyData, err := ioutil.ReadAll(resp.Body) // 读取响应体
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									arr := make([]byte, len(bodyData))
							 | 
						|||
| 
								 | 
							
									copy(arr, bodyData)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									if resp.StatusCode != 200 { // 检查响应状态码
							 | 
						|||
| 
								 | 
							
										return nil, errors.New(string(arr))
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return arr, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// fast http 执行请求
							 | 
						|||
| 
								 | 
							
								func NewHttpRequestWithFasthttp(reqMethod, reqUrl, postData string, headers map[string]string) ([]byte, error) {
							 | 
						|||
| 
								 | 
							
									req := fasthttp.AcquireRequest()   // 从 fasthttp 获取请求
							 | 
						|||
| 
								 | 
							
									resp := fasthttp.AcquireResponse() // 从 fasthttp 获取响应
							 | 
						|||
| 
								 | 
							
									defer func() {
							 | 
						|||
| 
								 | 
							
										fasthttp.ReleaseRequest(req)   // 释放请求
							 | 
						|||
| 
								 | 
							
										fasthttp.ReleaseResponse(resp) // 释放响应
							 | 
						|||
| 
								 | 
							
									}()
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									for k, v := range headers {
							 | 
						|||
| 
								 | 
							
										req.Header.Set(k, v) // 设置请求头
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									req.Header.SetMethod(reqMethod) // 设置请求方法
							 | 
						|||
| 
								 | 
							
									req.SetRequestURI(reqUrl)       // 设置请求 URL
							 | 
						|||
| 
								 | 
							
									req.SetBodyString(postData)     // 设置请求体
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									err := fastHttpClient.Do(req, resp) // 执行请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									recbody := resp.Body() // 获取响应体
							 | 
						|||
| 
								 | 
							
									arr := make([]byte, len(recbody))
							 | 
						|||
| 
								 | 
							
									copy(arr, recbody)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									if resp.StatusCode() != 200 { // 检查响应状态码
							 | 
						|||
| 
								 | 
							
										return nil, errors.New(fmt.Sprintf("HttpStatusCode:%d ,Desc:%s", resp.StatusCode(), string(recbody)))
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return recbody, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP GET 请求,返回 map
							 | 
						|||
| 
								 | 
							
								func HttpGet(reqUrl string) (map[string]interface{}, error) {
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", nil) // 发送 GET 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									var bodyDataMap map[string]interface{}
							 | 
						|||
| 
								 | 
							
									err = sonic.Unmarshal(respData, &bodyDataMap) // 解析 JSON 响应
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Println(string(respData)) // 打印响应数据
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									return bodyDataMap, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP GET 请求,带请求头
							 | 
						|||
| 
								 | 
							
								func HttpGet2(reqUrl string, headers map[string]string) (map[string]interface{}, error) {
							 | 
						|||
| 
								 | 
							
									if headers == nil {
							 | 
						|||
| 
								 | 
							
										headers = map[string]string{}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									headers["Content-Type"] = "application/x-www-form-urlencoded"           // 设置内容类型
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", headers) // 发送 GET 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									var bodyDataMap map[string]interface{}
							 | 
						|||
| 
								 | 
							
									err = sonic.Unmarshal(respData, &bodyDataMap) // 解析 JSON 响应
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Println("respData", string(respData)) // 打印响应数据
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									return bodyDataMap, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP GET 请求,返回接口切片
							 | 
						|||
| 
								 | 
							
								func HttpGet3(reqUrl string, headers map[string]string) ([]interface{}, error) {
							 | 
						|||
| 
								 | 
							
									if headers == nil {
							 | 
						|||
| 
								 | 
							
										headers = map[string]string{}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									headers["Content-Type"] = "application/x-www-form-urlencoded"           // 设置内容类型
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", headers) // 发送 GET 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									var bodyDataMap []interface{}
							 | 
						|||
| 
								 | 
							
									err = sonic.Unmarshal(respData, &bodyDataMap) // 解析 JSON 响应
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Println("respData", string(respData)) // 打印响应数据
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									return bodyDataMap, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP GET 请求,结果存储在 result 中
							 | 
						|||
| 
								 | 
							
								func HttpGet4(reqUrl string, headers map[string]string, result interface{}) error {
							 | 
						|||
| 
								 | 
							
									if headers == nil {
							 | 
						|||
| 
								 | 
							
										headers = map[string]string{}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									headers["Content-Type"] = "application/x-www-form-urlencoded"           // 设置内容类型
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", headers) // 发送 GET 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									err = sonic.Unmarshal(respData, result) // 解析 JSON 响应
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Printf("HttpGet4 - json.Unmarshal failed : %v, resp %s", err, string(respData))
							 | 
						|||
| 
								 | 
							
										return err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP GET 请求,返回原始字节
							 | 
						|||
| 
								 | 
							
								func HttpGet5(reqUrl string, headers map[string]string) ([]byte, error) {
							 | 
						|||
| 
								 | 
							
									if headers == nil {
							 | 
						|||
| 
								 | 
							
										headers = map[string]string{}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									headers["Content-Type"] = "application/x-www-form-urlencoded"           // 设置内容类型
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", headers) // 发送 GET 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return respData, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP POST 请求,表单数据
							 | 
						|||
| 
								 | 
							
								func HttpPostForm(reqUrl string, postData url.Values) ([]byte, error) {
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("POST", reqUrl, postData.Encode(), nil) // 发送 POST 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return respData, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP POST 请求,返回 map
							 | 
						|||
| 
								 | 
							
								func HttpPost(reqUrl string, postData string) (map[string]interface{}, error) {
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("POST", reqUrl, postData, nil) // 发送 POST 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									var bodyDataMap map[string]interface{}
							 | 
						|||
| 
								 | 
							
									err = sonic.Unmarshal(respData, &bodyDataMap) // 解析 JSON 响应
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Println(string(respData)) // 打印响应数据
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									return bodyDataMap, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP POST 请求,返回原始字节
							 | 
						|||
| 
								 | 
							
								func HttpPost2(reqUrl string, postData string) ([]byte, error) {
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("POST", reqUrl, postData, nil) // 发送 POST 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return respData, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP POST 请求,返回接口切片
							 | 
						|||
| 
								 | 
							
								func HttpPost3(reqUrl string, postData string) ([]interface{}, error) {
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("POST", reqUrl, postData, nil) // 发送 POST 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									var bodyDataMap []interface{}
							 | 
						|||
| 
								 | 
							
									err = sonic.Unmarshal(respData, &bodyDataMap) // 解析 JSON 响应
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Println(string(respData)) // 打印响应数据
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									return bodyDataMap, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP POST 请求,结果存储在 result 中
							 | 
						|||
| 
								 | 
							
								func HttpPost4(reqUrl string, postData string, result interface{}) error {
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("POST", reqUrl, postData, nil) // 发送 POST 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									err = sonic.Unmarshal(respData, result) // 解析 JSON 响应
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Printf("HttpPost4 - json.Unmarshal failed : %v, resp %s", err, string(respData))
							 | 
						|||
| 
								 | 
							
										return err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP POST 请求,返回原始字节
							 | 
						|||
| 
								 | 
							
								func HttpPost5(reqUrl string, postData string) ([]byte, error) {
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("POST", reqUrl, postData, nil) // 发送 POST 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return respData, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// HTTP POST 请求,表单数据,带请求头
							 | 
						|||
| 
								 | 
							
								func HttpPostForm2(reqUrl string, postData url.Values, headers map[string]string) ([]byte, error) {
							 | 
						|||
| 
								 | 
							
									respData, err := NewHttpRequestWithFasthttp("POST", reqUrl, postData.Encode(), headers) // 发送 POST 请求
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									return respData, nil
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 创建 HTTP 代理拨号器
							 | 
						|||
| 
								 | 
							
								func createHTTPProxyDialer(proxy string) fasthttp.DialFunc {
							 | 
						|||
| 
								 | 
							
									// 解析代理 URL
							 | 
						|||
| 
								 | 
							
									proxyURL, err := url.Parse(proxy)
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										log.Fatal(err)
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// 返回拨号器函数
							 | 
						|||
| 
								 | 
							
									return func(addr string) (net.Conn, error) {
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										// 选择代理协议
							 | 
						|||
| 
								 | 
							
										switch proxyURL.Scheme {
							 | 
						|||
| 
								 | 
							
										case "http", "https":
							 | 
						|||
| 
								 | 
							
											proxyConn, err := net.Dial("tcp", proxyURL.Host)
							 | 
						|||
| 
								 | 
							
											if err != nil {
							 | 
						|||
| 
								 | 
							
												return nil, err
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											// Send the HTTP CONNECT request to the proxy
							 | 
						|||
| 
								 | 
							
											_, err = proxyConn.Write([]byte("CONNECT " + addr + " HTTP/1.1\r\nHost: " + addr + "\r\n\r\n"))
							 | 
						|||
| 
								 | 
							
											if err != nil {
							 | 
						|||
| 
								 | 
							
												return nil, err
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											// Read the response from the proxy
							 | 
						|||
| 
								 | 
							
											buf := make([]byte, 4096)
							 | 
						|||
| 
								 | 
							
											n, err := proxyConn.Read(buf)
							 | 
						|||
| 
								 | 
							
											if err != nil {
							 | 
						|||
| 
								 | 
							
												return nil, err
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
											// Check for a successful response (HTTP 200)
							 | 
						|||
| 
								 | 
							
											if !isConnectSuccess(buf[:n]) {
							 | 
						|||
| 
								 | 
							
												return nil, err
							 | 
						|||
| 
								 | 
							
											}
							 | 
						|||
| 
								 | 
							
											return proxyConn, nil
							 | 
						|||
| 
								 | 
							
										case "socks5":
							 | 
						|||
| 
								 | 
							
											return socks5Dial(proxyURL.Host)
							 | 
						|||
| 
								 | 
							
										default:
							 | 
						|||
| 
								 | 
							
											return nil, fmt.Errorf("不支持的代理协议: %s", proxyURL.Scheme)
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								func isConnectSuccess(response []byte) bool {
							 | 
						|||
| 
								 | 
							
									return len(response) > 0 && strings.HasPrefix(string(response), "HTTP/1.1 200")
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// socks5Dial 使用 SOCKS5 代理拨号
							 | 
						|||
| 
								 | 
							
								func socks5Dial(proxyAddr string) (net.Conn, error) {
							 | 
						|||
| 
								 | 
							
									// 创建 SOCKS5 代理拨号器
							 | 
						|||
| 
								 | 
							
									dialer, err := proxy.SOCKS5("tcp", proxyAddr, nil, proxy.Direct)
							 | 
						|||
| 
								 | 
							
									if err != nil {
							 | 
						|||
| 
								 | 
							
										return nil, err
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// 使用代理拨号
							 | 
						|||
| 
								 | 
							
									return dialer.Dial("tcp", "destination_address:port") // 替换为目标地址和端口
							 | 
						|||
| 
								 | 
							
								}
							 |