client: add content-type and csrf headers
required for UnifiOS controllers (UDM, UDM Pro) Ref paultyng/terraform-provider-unifi#55
This commit is contained in:
committed by
Paul Tyng
parent
8f15aa6dff
commit
b2581f5eb3
@@ -12,6 +12,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -38,11 +39,20 @@ func (err *APIError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
|
// single thread client calls for CSRF, etc.
|
||||||
|
sync.Mutex
|
||||||
|
|
||||||
c *http.Client
|
c *http.Client
|
||||||
baseURL *url.URL
|
baseURL *url.URL
|
||||||
|
|
||||||
apiPath string
|
apiPath string
|
||||||
loginPath string
|
loginPath string
|
||||||
|
|
||||||
|
csrf string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) CSRFToken() string {
|
||||||
|
return c.csrf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) SetBaseURL(base string) error {
|
func (c *Client) SetBaseURL(base string) error {
|
||||||
@@ -133,6 +143,10 @@ func (c *Client) Login(ctx context.Context, user, pass string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) do(ctx context.Context, method, relativeURL string, reqBody interface{}, respBody interface{}) error {
|
func (c *Client) do(ctx context.Context, method, relativeURL string, reqBody interface{}, respBody interface{}) error {
|
||||||
|
// single threading requests, this is mostly to assist in CSRF token propagation
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
reqReader io.Reader
|
reqReader io.Reader
|
||||||
err error
|
err error
|
||||||
@@ -161,6 +175,11 @@ func (c *Client) do(ctx context.Context, method, relativeURL string, reqBody int
|
|||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("User-Agent", "terraform-provider-unifi/0.1")
|
req.Header.Set("User-Agent", "terraform-provider-unifi/0.1")
|
||||||
|
req.Header.Add("Content-Type", "application/json; charset=utf-8")
|
||||||
|
|
||||||
|
if c.csrf != "" {
|
||||||
|
req.Header.Set("X-CSRF-Token", c.csrf)
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := c.c.Do(req)
|
resp, err := c.c.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -172,6 +191,10 @@ func (c *Client) do(ctx context.Context, method, relativeURL string, reqBody int
|
|||||||
return &NotFoundError{}
|
return &NotFoundError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if csrf := resp.Header.Get("x-csrf-token"); csrf != "" {
|
||||||
|
c.csrf = resp.Header.Get("x-csrf-token")
|
||||||
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
fmt.Printf("Request Body:\n%s\n", string(reqBytes))
|
fmt.Printf("Request Body:\n%s\n", string(reqBytes))
|
||||||
errBody := struct {
|
errBody := struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user