package api import ( "context" "fmt" "io" "log" "net/http" "net/http/httputil" ) // Client is the API client for tesla. type Client struct { baseUrl string debug bool HTTPClient *http.Client } // NewClient allow to instantiate an API Client for Tesla. func NewClient() (*Client, error) { client := Client{ baseUrl: baseUrl, HTTPClient: http.DefaultClient, } return &client, nil } // SetDebug will enable or disable debug. func (c *Client) SetDebug(debug bool) { c.debug = debug } func (c *Client) get(ctx context.Context, path string) (*http.Response, error) { return c.do(ctx, http.MethodGet, path, nil) } func (c *Client) customizeRequest(req *http.Request) *http.Request { // Content-Type expected by the API req.Header.Set("Content-Type", contentTypeHeader) // add user-agent header req.Header.Set("User-Agent", userAgentHeader) return req } func (c *Client) do(ctx context.Context, method string, url string, body io.Reader) (*http.Response, error) { req, err := http.NewRequestWithContext( ctx, method, fmt.Sprintf("%s%s", c.baseUrl, url), body, ) if err != nil { return nil, fmt.Errorf("failed to build request: %w", err) } req = c.customizeRequest(req) if c.debug { dump, err := httputil.DumpRequestOut(req, true) if err != nil { return nil, err } log.Printf("\n----------- Request Debug -----------\n%s\n-------------------------------------\n", string(dump)) } resp, err := c.HTTPClient.Do(req) if err != nil { return resp, fmt.Errorf("an error occurred while calling the API: %w", err) } if c.debug { dump, err := httputil.DumpResponse(resp, true) if err != nil { return resp, err } log.Printf("\n----------- Response Debug ----------\n%s\n------------------------------------\n", string(dump)) } if resp.StatusCode < 200 || resp.StatusCode >= 300 { return resp, Error{ HTTPCode: resp.StatusCode, HTTPMessage: resp.Status, } } return resp, nil }