-
Notifications
You must be signed in to change notification settings - Fork 0
/
httpclient.go
97 lines (84 loc) · 2.1 KB
/
httpclient.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
package graphiteapi
import (
"context"
"io"
"io/ioutil"
"net"
"net/http"
"sync"
"time"
)
// httpClient is used everywhere internally, here we initialize a default http client,
// library users can call graphiteapi.UseHTTPClient() to set a customized http client.
var httpClient *http.Client = &http.Client{
Timeout: 5 * time.Second,
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: 1 * time.Second,
}).Dial,
MaxIdleConnsPerHost: 5,
},
}
var (
userAgent string = "graphite-api-client/0.1"
customHeaders map[string][]string = make(map[string][]string)
chl sync.RWMutex
)
// SetHTTPClient sets the http client used to make requests
func SetHTTPClient(client *http.Client) {
httpClient = client
}
// AddCustomHeader adds a custom header on all requests
func AddCustomHeader(key, value string) {
if key == "User-Agent" {
SetUserAgent(value)
return
}
chl.Lock()
defer chl.Unlock()
if values, ok := customHeaders[key]; ok {
values = append(values, value)
customHeaders[key] = values
} else {
values = []string{value}
customHeaders[key] = values
}
}
// SetUserAgent sets a custom user agent
func SetUserAgent(ua string) {
userAgent = ua
}
// httpNewRequest wraps http.NewRequest(), and set custom headers
func httpNewRequest(method string, url string, body io.Reader) (*http.Request, error) {
if req, err := http.NewRequest(method, url, body); err != nil {
return req, err
} else {
req.Header.Set("User-Agent", userAgent)
chl.Lock()
defer chl.Unlock()
for key := range customHeaders {
values := customHeaders[key]
for _, value := range values {
req.Header.Add(key, value)
}
}
return req, nil
}
}
// httpDo wraps http.Client.Do(), fetches response and unmarshals into r
func httpDo(ctx context.Context, req *http.Request, r Response) error {
req = req.WithContext(ctx)
var resp *http.Response
var body []byte
var err error
if resp, err = httpClient.Do(req); err != nil {
return err
}
if body, err = ioutil.ReadAll(resp.Body); err != nil {
return err
}
if err = r.Unmarshal(body); err != nil {
return err
}
return nil
}