Files
ai-code-review/services/platforms/client.go

198 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}