-
Notifications
You must be signed in to change notification settings - Fork 0
/
httpclient.go
137 lines (111 loc) · 3.04 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
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
package httpclient
import (
"bytes"
"errors"
"net"
"strconv"
"time"
"io/ioutil"
"net/http"
)
// HTTPClient is an interface for initializing the http client library.
type HTTPClient struct {
Client *http.Client
Data *bytes.Buffer
Headers map[string]string
Username string
Password string
}
// DefaultClient is a function for defining a basic HTTP client with standard timeouts.
func DefaultClient() *HTTPClient {
return &HTTPClient{
Client: &http.Client{
Timeout: 60 * time.Second,
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: 5 * time.Second,
}).Dial,
TLSHandshakeTimeout: 5 * time.Second,
IdleConnTimeout: 300 * time.Second,
},
},
}
}
// NewClient Create an HTTPClient with a user-provided net/http.Client
func NewClient(httpClient *http.Client) *HTTPClient {
return &HTTPClient{Client: httpClient}
}
// SetBasicAuth is a chaining function to set the username and password for basic
// authentication
func (c *HTTPClient) SetBasicAuth(username, password string) *HTTPClient {
c.Username = username
c.Password = password
return c
}
// SetPostData is a chaining function to set POST/PUT/PATCH data
func (c *HTTPClient) SetPostData(data string) *HTTPClient {
c.Data = bytes.NewBufferString(data)
return c
}
// SetHeader is a chaining function to set arbitrary HTTP Headers
func (c *HTTPClient) SetHeader(label string, value string) *HTTPClient {
if c.Headers == nil {
c.Headers = map[string]string{}
}
c.Headers[label] = value
return c
}
// Get calls the net.http GET operation
func (c *HTTPClient) Get(url string) ([]byte, error) {
return c.do(url, http.MethodGet)
}
// Patch calls the net.http PATCH operation
func (c *HTTPClient) Patch(url string) ([]byte, error) {
return c.do(url, http.MethodPatch)
}
// Post calls the net.http POST operation
func (c *HTTPClient) Post(url string) ([]byte, error) {
return c.do(url, http.MethodPost)
}
// Put calls the net.http PUT operation
func (c *HTTPClient) Put(url string) ([]byte, error) {
return c.do(url, http.MethodPut)
}
func (c *HTTPClient) do(url string, method string) ([]byte, error) {
var (
req *http.Request
res *http.Response
output []byte
err error
)
// NewRequest knows that c.data is typed *bytes.Buffer and will SEGFAULT
// if c.data is nil. So we create a request using nil when c.data is nil
if c.Data != nil {
req, err = http.NewRequest(method, url, c.Data)
} else {
req, err = http.NewRequest(method, url, nil)
}
if err != nil {
return nil, err
}
if (len(c.Username) > 0) && (len(c.Password) > 0) {
req.SetBasicAuth(c.Username, c.Password)
}
if c.Headers != nil {
for label, value := range c.Headers {
req.Header.Set(label, value)
}
}
if res, err = c.Client.Do(req); err != nil {
return nil, err
}
defer res.Body.Close()
if output, err = ioutil.ReadAll(res.Body); err != nil {
return nil, err
}
// check status
if res.StatusCode < 200 || res.StatusCode >= 300 {
return nil, errors.New("non-successful status code received [" + strconv.Itoa(res.StatusCode) + "]")
}
return output, nil
}