package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "os" ) // Client wraps the HTTP client with authentication support type Client struct { baseURL string authKey string username string password string client *http.Client } // NewClient creates a new authenticated HTTP client func NewClient(cfg *CLIConfig) *Client { return &Client{ baseURL: cfg.ServerURL, authKey: cfg.AuthKey, username: cfg.Username, password: cfg.Password, client: &http.Client{}, } } // addAuth adds authentication headers to the request func (c *Client) addAuth(req *http.Request) { // Priority 1: API Key (as Bearer token or x-api-key header) if c.authKey != "" { req.Header.Set("Authorization", "Bearer "+c.authKey) req.Header.Set("x-api-key", c.authKey) return } // Priority 2: Basic Auth (username/password) if c.username != "" && c.password != "" { req.SetBasicAuth(c.username, c.password) } } // Get performs an authenticated GET request func (c *Client) Get(path string) (*http.Response, error) { req, err := http.NewRequest("GET", c.baseURL+path, nil) if err != nil { return nil, err } c.addAuth(req) resp, err := c.client.Do(req) if err != nil { return nil, err } // Check for HTTP error status codes if resp.StatusCode >= 400 { defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body)) } return resp, nil } // Post performs an authenticated POST request with JSON data func (c *Client) Post(path string, data interface{}) (*http.Response, error) { jsonData, err := json.Marshal(data) if err != nil { return nil, err } req, err := http.NewRequest("POST", c.baseURL+path, bytes.NewReader(jsonData)) if err != nil { return nil, err } req.Header.Set("Content-Type", "application/json") c.addAuth(req) resp, err := c.client.Do(req) if err != nil { return nil, err } // Check for HTTP error status codes if resp.StatusCode >= 400 { defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body)) } return resp, nil } // decodeJSON decodes JSON response into target func decodeJSON(resp *http.Response, target interface{}) error { defer resp.Body.Close() return json.NewDecoder(resp.Body).Decode(target) } // checkError prints error and exits if error is not nil func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } }