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") // 替换为目标地址和端口 }