/
client.go
219 lines (188 loc) · 4.24 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
package dhttp
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
D "github.com/NeoJRotary/describe-go"
)
// TypeClient http function collections struct
type TypeClient struct {
err error
Request *http.Request
Method string
URL string
ContentType string
Body []byte
BodyReader io.Reader
Header map[string]string
Query map[string]string
Timeout time.Duration
}
// Response inheritance of http.Response
type Response struct {
*http.Response
}
// Client get new Client, can be inited by TypeClient
func Client(input ...TypeClient) *TypeClient {
c := TypeClient{
Request: &http.Request{
Method: "GET",
URL: nil,
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
Header: make(http.Header),
Body: nil,
Host: "",
},
}
if len(input) > 0 {
init := input[0]
c.Request.Method = init.Method
c.SetURL(init.URL)
c.SetContentType(init.ContentType)
if init.Body != nil {
c.SetBody(init.Body)
}
if init.BodyReader != nil {
c.SetBodyReader(init.BodyReader)
}
for k, v := range init.Header {
c.SetHeader(k, v)
}
for k, v := range init.Query {
c.SetQuery(k, v)
}
}
return &c
}
// GET set method to GET
func (c *TypeClient) GET() *TypeClient {
c.Request.Method = http.MethodGet
return c
}
// POST set method to POST
func (c *TypeClient) POST() *TypeClient {
c.Request.Method = http.MethodPost
return c
}
// PUT set method to PUT
func (c *TypeClient) PUT() *TypeClient {
c.Request.Method = http.MethodPut
return c
}
// PATCH set method to PATCH
func (c *TypeClient) PATCH() *TypeClient {
c.Request.Method = http.MethodPatch
return c
}
// DELETE set method to DELETE
func (c *TypeClient) DELETE() *TypeClient {
c.Request.Method = http.MethodDelete
return c
}
// OPTIONS set method to OPTIONS
func (c *TypeClient) OPTIONS() *TypeClient {
c.Request.Method = http.MethodOptions
return c
}
// CONNECT set method to CONNECT
func (c *TypeClient) CONNECT() *TypeClient {
c.Request.Method = http.MethodConnect
return c
}
// HEAD set method to HEAD
func (c *TypeClient) HEAD() *TypeClient {
c.Request.Method = http.MethodHead
return c
}
// TRACE set method to TRACE
func (c *TypeClient) TRACE() *TypeClient {
c.Request.Method = http.MethodTrace
return c
}
// SetContentType set content-type header
func (c *TypeClient) SetContentType(contentType string) *TypeClient {
c.Request.Header.Set("Content-Type", contentType)
return c
}
// SetURL set URL
func (c *TypeClient) SetURL(urlString string) *TypeClient {
u, err := url.Parse(urlString)
if D.IsErr(err) {
c.err = err
return c
}
c.Request.URL = u
c.Request.Host = D.String(u.Host).TrimSuffix(":").Get()
return c
}
// SetBody set http body by []byte
func (c *TypeClient) SetBody(buf []byte) *TypeClient {
return c.SetBodyReader(bytes.NewBuffer(buf))
}
// SetBodyReader set http body by io.Reader
func (c *TypeClient) SetBodyReader(reader io.Reader) *TypeClient {
rc, ok := reader.(io.ReadCloser)
if !ok && reader != nil {
rc = ioutil.NopCloser(reader)
}
c.Request.Body = rc
if reader != nil {
switch v := reader.(type) {
case *bytes.Buffer:
c.Request.ContentLength = int64(v.Len())
case *bytes.Reader:
c.Request.ContentLength = int64(v.Len())
case *strings.Reader:
c.Request.ContentLength = int64(v.Len())
default:
}
if c.Request.ContentLength == 0 {
c.Request.Body = http.NoBody
}
}
return c
}
// SetHeader set one header key
func (c *TypeClient) SetHeader(key, value string) *TypeClient {
c.Request.Header.Set(key, value)
return c
}
// SetQuery set one query key
func (c *TypeClient) SetQuery(key, value string) *TypeClient {
c.Request.URL.Query().Set(key, value)
return c
}
// SetTimeout set timeout
func (c *TypeClient) SetTimeout(dur time.Duration) *TypeClient {
c.Timeout = dur
return c
}
// Do do http request
func (c *TypeClient) Do() (*Response, error) {
if D.IsErr(c.err) {
return nil, c.err
}
client := &http.Client{
Timeout: c.Timeout,
}
res, err := client.Do(c.Request)
if D.IsErr(err) {
return nil, err
}
return &Response{res}, nil
}
// ReadAllBody read all response body
func (r *Response) ReadAllBody() []byte {
defer r.Body.Close()
b, err := ioutil.ReadAll(r.Body)
if D.IsErr(err) {
return nil
}
return b
}