Files

81 lines
1.8 KiB
Go
Raw Permalink Normal View History

2026-08-12 14:04:30 +03:00
package rudder
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
)
type transport struct {
baseURL string
apiKey string
httpClient *http.Client
}
func (t *transport) do(ctx context.Context, method, path string, query url.Values, body any, out any) error {
endpoint := strings.TrimSuffix(t.baseURL, "/") + "/game/v1" + path
2026-08-12 14:04:30 +03:00
if len(query) > 0 {
endpoint += "?" + query.Encode()
}
var reader io.Reader
if body != nil {
data, err := json.Marshal(body)
if err != nil {
return fmt.Errorf("rudder: encode request body: %w", err)
}
reader = bytes.NewReader(data)
}
req, err := http.NewRequestWithContext(ctx, method, endpoint, reader)
if err != nil {
return fmt.Errorf("rudder: build request: %w", err)
}
req.Header.Set("X-API-Key", t.apiKey)
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
resp, err := t.httpClient.Do(req)
if err != nil {
return fmt.Errorf("rudder: %s %s: %w", method, path, err)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("rudder: read response body: %w", err)
}
if resp.StatusCode >= 400 {
apiErr := &APIError{Status: resp.StatusCode}
var payload struct {
Error string `json:"error"`
Code string `json:"code"`
RequestID string `json:"requestId"`
}
if json.Unmarshal(data, &payload) == nil {
apiErr.Code = payload.Code
apiErr.Message = payload.Error
apiErr.RequestID = payload.RequestID
}
if apiErr.Message == "" {
apiErr.Message = http.StatusText(resp.StatusCode)
}
return apiErr
}
if out == nil || len(data) == 0 {
return nil
}
if err := json.Unmarshal(data, out); err != nil {
return fmt.Errorf("rudder: decode response: %w", err)
}
return nil
}