package platforms import ( "bytes" "encoding/json" "fmt" "io" "log" "net/http" ) type AuthConfig struct { Token string Username string Password string SudoUser string TOTP string UseBasicAuth bool UseSudoHeader bool UseSudoParam bool UseTOTPHeader bool } type httpClient struct { url string auth *AuthConfig client *http.Client } func newHTTPClient(baseURL string, authConfig *AuthConfig) *httpClient { return &httpClient{ url: baseURL, auth: authConfig, client: &http.Client{}, } } func (c *httpClient) setAuthHeaders(req *http.Request) { if c.auth == nil { return } // 设置 Token 认证 if c.auth.Token != "" { req.Header.Set("Authorization", "token "+c.auth.Token) } } func (c *httpClient) get(path string, result interface{}) error { url := fmt.Sprintf("%s%s", c.url, path) log.Printf("发送 GET 请求: url=%s", url) req, err := http.NewRequest("GET", url, nil) if err != nil { log.Printf("创建 GET 请求失败: url=%s, error=%v", url, err) return fmt.Errorf("创建请求失败: %w", err) } req.Header.Set("Content-Type", "application/json") c.setAuthHeaders(req) resp, err := c.client.Do(req) if err != nil { log.Printf("发送 GET 请求失败: url=%s, error=%v", url, err) return fmt.Errorf("发送请求失败: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) log.Printf("GET 请求返回错误状态码: url=%s, status=%d, response=%s", url, resp.StatusCode, string(body)) return fmt.Errorf("请求失败,状态码: %d,响应: %s", resp.StatusCode, string(body)) } if err := json.NewDecoder(resp.Body).Decode(result); err != nil { log.Printf("解析 GET 响应失败: url=%s, error=%v", url, err) return fmt.Errorf("解析响应失败: %w", err) } log.Printf("GET 请求成功: url=%s", url) return nil } func (c *httpClient) post(path string, data interface{}) error { url := fmt.Sprintf("%s%s", c.url, path) log.Printf("发送 POST 请求: url=%s", url) jsonData, err := json.Marshal(data) if err != nil { log.Printf("序列化 POST 数据失败: url=%s, error=%v", url, err) return fmt.Errorf("序列化请求数据失败: %w", err) } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { log.Printf("创建 POST 请求失败: url=%s, error=%v", url, err) return fmt.Errorf("创建请求失败: %w", err) } req.Header.Set("Content-Type", "application/json") c.setAuthHeaders(req) resp, err := c.client.Do(req) if err != nil { log.Printf("发送 POST 请求失败: url=%s, error=%v", url, err) return fmt.Errorf("发送请求失败: %w", err) } defer resp.Body.Close() if resp.StatusCode < 200 || resp.StatusCode >= 300 { body, _ := io.ReadAll(resp.Body) log.Printf("POST 请求返回错误状态码: url=%s, status=%d, response=%s", url, resp.StatusCode, string(body)) return fmt.Errorf("请求失败,状态码: %d,响应: %s", resp.StatusCode, string(body)) } log.Printf("POST 请求成功: url=%s", url) return nil } func (c *httpClient) getWithHeaders(path string, result interface{}, headers map[string]string) error { url := fmt.Sprintf("%s%s", c.url, path) log.Printf("发送 GET 请求: url=%s", url) req, err := http.NewRequest("GET", url, nil) if err != nil { log.Printf("创建 GET 请求失败: url=%s, error=%v", url, err) return fmt.Errorf("创建请求失败: %w", err) } req.Header.Set("Content-Type", "application/json") for key, value := range headers { req.Header.Set(key, value) } c.setAuthHeaders(req) resp, err := c.client.Do(req) if err != nil { log.Printf("发送 GET 请求失败: url=%s, error=%v", url, err) return fmt.Errorf("发送请求失败: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) log.Printf("GET 请求返回错误状态码: url=%s, status=%d, response=%s", url, resp.StatusCode, string(body)) return fmt.Errorf("请求失败,状态码: %d,响应: %s", resp.StatusCode, string(body)) } if err := json.NewDecoder(resp.Body).Decode(result); err != nil { log.Printf("解析 GET 响应失败: url=%s, error=%v", url, err) return fmt.Errorf("解析响应失败: %w", err) } log.Printf("GET 请求成功: url=%s", url) return nil } func (c *httpClient) postWithHeaders(path string, data interface{}, headers map[string]string) error { url := fmt.Sprintf("%s%s", c.url, path) log.Printf("发送 POST 请求: url=%s", url) jsonData, err := json.Marshal(data) if err != nil { log.Printf("序列化 POST 数据失败: url=%s, error=%v", url, err) return fmt.Errorf("序列化请求数据失败: %w", err) } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { log.Printf("创建 POST 请求失败: url=%s, error=%v", url, err) return fmt.Errorf("创建请求失败: %w", err) } req.Header.Set("Content-Type", "application/json") for key, value := range headers { req.Header.Set(key, value) } c.setAuthHeaders(req) resp, err := c.client.Do(req) if err != nil { log.Printf("发送 POST 请求失败: url=%s, error=%v", url, err) return fmt.Errorf("发送请求失败: %w", err) } defer resp.Body.Close() if resp.StatusCode < 200 || resp.StatusCode >= 300 { body, _ := io.ReadAll(resp.Body) log.Printf("POST 请求返回错误状态码: url=%s, status=%d, response=%s", url, resp.StatusCode, string(body)) return fmt.Errorf("请求失败,状态码: %d,响应: %s", resp.StatusCode, string(body)) } log.Printf("POST 请求成功: url=%s", url) return nil } func (c *httpClient) getRaw(path string) (string, error) { url := fmt.Sprintf("%s%s", c.url, path) log.Printf("发送 GET 请求: url=%s", url) req, err := http.NewRequest("GET", url, nil) if err != nil { log.Printf("创建 GET 请求失败: url=%s, error=%v", url, err) return "", fmt.Errorf("创建请求失败: %w", err) } c.setAuthHeaders(req) resp, err := c.client.Do(req) if err != nil { log.Printf("发送 GET 请求失败: url=%s, error=%v", url, err) return "", fmt.Errorf("发送请求失败: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) log.Printf("GET 请求返回错误状态码: url=%s, status=%d, response=%s", url, resp.StatusCode, string(body)) return "", fmt.Errorf("请求失败,状态码: %d,响应: %s", resp.StatusCode, string(body)) } body, err := io.ReadAll(resp.Body) if err != nil { log.Printf("读取响应失败: url=%s, error=%v", url, err) return "", fmt.Errorf("读取响应失败: %w", err) } log.Printf("GET 请求成功: url=%s", url) return string(body), nil }