package utils import ( "bytes" "context" "encoding/json" "fmt" "io/ioutil" "net/http" "time" ) // HTTPClient HTTP客户端工具 type HTTPClient struct { client *http.Client } // NewHTTPClient 创建HTTP客户端实例 func NewHTTPClient(timeout int) *HTTPClient { return &HTTPClient{ client: &http.Client{ Timeout: time.Duration(timeout) * time.Second, }, } } // Get 发送GET请求 func (h *HTTPClient) Get(url string, headers map[string]string) ([]byte, error) { req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } // 添加请求头 for key, value := range headers { req.Header.Set(key, value) } return h.doRequest(req) } // Post 发送POST请求 func (h *HTTPClient) Post(url string, data interface{}, headers map[string]string) ([]byte, error) { // 序列化数据 jsonData, err := json.Marshal(data) if err != nil { return nil, err } // 创建请求 req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { return nil, err } // 设置Content-Type req.Header.Set("Content-Type", "application/json") // 添加其他请求头 for key, value := range headers { req.Header.Set(key, value) } return h.doRequest(req) } // Put 发送PUT请求 func (h *HTTPClient) Put(url string, data interface{}, headers map[string]string) ([]byte, error) { // 序列化数据 jsonData, err := json.Marshal(data) if err != nil { return nil, err } // 创建请求 req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData)) if err != nil { return nil, err } // 设置Content-Type req.Header.Set("Content-Type", "application/json") // 添加其他请求头 for key, value := range headers { req.Header.Set(key, value) } return h.doRequest(req) } // Delete 发送DELETE请求 func (h *HTTPClient) Delete(url string, headers map[string]string) ([]byte, error) { req, err := http.NewRequest("DELETE", url, nil) if err != nil { return nil, err } // 添加请求头 for key, value := range headers { req.Header.Set(key, value) } return h.doRequest(req) } // doRequest 执行HTTP请求 func (h *HTTPClient) doRequest(req *http.Request) ([]byte, error) { // 创建带超时的上下文 ctx, cancel := context.WithTimeout(context.Background(), h.client.Timeout) defer cancel() req = req.WithContext(ctx) // 发送请求 resp, err := h.client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() // 读取响应 body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } // 检查响应状态码 if resp.StatusCode < 200 || resp.StatusCode >= 300 { return nil, fmt.Errorf("HTTP请求失败,状态码: %d,响应内容: %s", resp.StatusCode, string(body)) } return body, nil }