198 lines
5.5 KiB
Go
198 lines
5.5 KiB
Go
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
|
||
}
|