This repository was archived by the owner on Feb 2, 2019. It is now read-only.
forked from edeckers/auroradnsclient
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.go
144 lines (114 loc) · 2.77 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package auroradns
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
)
const defaultBaseURL = "https://api.auroradns.eu"
const (
contentTypeHeader = "Content-Type"
contentTypeJSON = "application/json"
)
// ErrorResponse A representation of an API error message.
type ErrorResponse struct {
ErrorCode string `json:"error"`
Message string `json:"errormsg"`
}
func (e *ErrorResponse) Error() string {
return fmt.Sprintf("%s - %s", e.ErrorCode, e.Message)
}
// Option Type of a client option
type Option func(*Client) error
// Client The API client
type Client struct {
baseURL *url.URL
UserAgent string
httpClient *http.Client
}
// NewClient Creates a new client
func NewClient(httpClient *http.Client, opts ...Option) (*Client, error) {
if httpClient == nil {
httpClient = http.DefaultClient
}
baseURL, _ := url.Parse(defaultBaseURL)
client := &Client{
baseURL: baseURL,
httpClient: httpClient,
}
for _, opt := range opts {
err := opt(client)
if err != nil {
return nil, err
}
}
return client, nil
}
func (c *Client) newRequest(method, resource string, body io.Reader) (*http.Request, error) {
u, err := c.baseURL.Parse(resource)
if err != nil {
return nil, err
}
req, err := http.NewRequest(method, u.String(), body)
if err != nil {
return nil, err
}
req.Header.Set(contentTypeHeader, contentTypeJSON)
if c.UserAgent != "" {
req.Header.Set("User-Agent", c.UserAgent)
}
return req, nil
}
func (c *Client) do(req *http.Request, v interface{}) (*http.Response, error) {
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer func() { _ = resp.Body.Close() }()
if err = checkResponse(resp); err != nil {
return resp, err
}
if v == nil {
return resp, nil
}
raw, err := ioutil.ReadAll(resp.Body)
if err != nil {
return resp, fmt.Errorf("failed to read body: %v", err)
}
if err = json.Unmarshal(raw, v); err != nil {
return resp, fmt.Errorf("unmarshaling %T error: %v: %s", err, v, string(raw))
}
return resp, nil
}
func checkResponse(resp *http.Response) error {
if c := resp.StatusCode; 200 <= c && c <= 299 {
return nil
}
data, err := ioutil.ReadAll(resp.Body)
if err == nil && data != nil {
errorResponse := new(ErrorResponse)
err = json.Unmarshal(data, errorResponse)
if err != nil {
return fmt.Errorf("unmarshaling ErrorResponse error: %v: %s", err.Error(), string(data))
}
return errorResponse
}
defer func() { _ = resp.Body.Close() }()
return nil
}
// WithBaseURL Allows to define a custom base URL
func WithBaseURL(rawBaseURL string) func(*Client) error {
return func(client *Client) error {
if len(rawBaseURL) == 0 {
return nil
}
baseURL, err := url.Parse(rawBaseURL)
if err != nil {
return err
}
client.baseURL = baseURL
return nil
}
}