/
wing_http.go
executable file
·298 lines (263 loc) · 7.91 KB
/
wing_http.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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
// Copyright (c) 2018-2019 WING All Rights Reserved.
//
// Author : yangping
// Email : youhei_yp@163.com
//
// Prismy.No | Date | Modified by. | Description
// -------------------------------------------------------------------
// 00001 2019/05/22 yangping New version
// -------------------------------------------------------------------
package comm
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"github.com/youhei-yp/wing/invar"
"github.com/youhei-yp/wing/logger"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
const (
// ContentTypeJson json content type
ContentTypeJson = "application/json;charset=UTF-8"
// ContentTypeForm form content type
ContentTypeForm = "application/x-www-form-urlencoded"
)
// EncodeUrl encode url params
func EncodeUrl(rawurl string) string {
enurl, err := url.Parse(rawurl)
if err != nil {
logger.E("Encode urlm err:", err)
return rawurl
}
enurl.RawQuery = enurl.Query().Encode()
return enurl.String()
}
// HttpGet handle http get method
func HttpGet(tagurl string, params ...interface{}) ([]byte, error) {
if len(params) > 0 {
tagurl = fmt.Sprintf(tagurl, params...)
}
rawurl := EncodeUrl(tagurl)
logger.D("HttpGet:", rawurl)
resp, err := http.Get(rawurl)
if err != nil {
logger.E("Handle http get err:", err)
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
logger.E("Read get response err:", err)
return nil, err
}
logger.D("HttpGet: body:", string(body))
return body, nil
}
// HttpPost handle http post method, you can set content type as
// comm.ContentTypeJson or comm.ContentTypeForm, or other you need set.
// [CODE:]
// // set post data as json string
// data := struct {"key": "Value", "id": "123"}
// resp, err := comm.HttpPost(tagurl, data)
//
// // set post data as form string
// data := "key=Value&id=123"
// resp, err := comm.HttpPost(tagurl, data, comm.ContentTypeForm)
// [CODE]
func HttpPost(tagurl string, postdata interface{}, contentType ...string) ([]byte, error) {
ct := ContentTypeJson
if len(contentType) > 0 {
ct = contentType[0]
}
logger.D("HttpPost:", tagurl, "past data:", postdata, "contentType:", ct)
switch ct {
case ContentTypeJson:
return httpPostJson(tagurl, postdata)
case ContentTypeForm:
return httpPostForm(tagurl, postdata.(url.Values))
}
logger.E("HttpPost: invalid contentType:", ct)
return nil, invar.ErrInvalidParams
}
// HttpGetString call HttpGet and trim " char both begin and end
func HttpGetString(tagurl string, params ...interface{}) (string, error) {
resp, err := HttpGet(tagurl, params...)
if err != nil {
return "", err
}
return strings.Trim(string(resp), "\""), nil
}
// HttpPostString call HttpPost and trim " char both begin and end.
func HttpPostString(tagurl string, postdata interface{}, contentType ...string) (string, error) {
resp, err := HttpPost(tagurl, postdata, contentType...)
if err != nil {
return "", err
}
return strings.Trim(string(resp), "\""), nil
}
// HttpGetStruct handle http get method and unmarshal data to struct object
func HttpGetStruct(tagurl string, out interface{}, params ...interface{}) error {
body, err := HttpGet(tagurl, params...)
if err != nil {
return err
}
if err := json.Unmarshal(body, out); err != nil {
logger.E("Unmarshal bady to struct err:", err)
return err
}
logger.D("HttpGetStruct:", out)
return nil
}
// HttpPostStruct handle http post method and unmarshal data to struct object
func HttpPostStruct(tagurl string, postdata, out interface{}, contentType ...string) error {
body, err := HttpPost(tagurl, postdata, contentType...)
if err != nil {
return err
}
if err := json.Unmarshal(body, out); err != nil {
logger.E("Unmarshal bady to struct err:", err)
return err
}
logger.D("HttpPostStruct:", out)
return nil
}
// HttpClientGet handle get by http.Client, you can set useTLS to enable TLS or not
func HttpClientGet(tagurl string, useTLS bool, params ...interface{}) ([]byte, error) {
if len(params) > 0 {
tagurl = fmt.Sprintf(tagurl, params...)
}
rawurl := EncodeUrl(tagurl)
req, err := http.NewRequest("GET", rawurl, http.NoBody)
if err != nil {
logger.E("Create http request err:", err)
return nil, err
}
return httpClientDo(req, useTLS)
}
// HttpClientGet handle post by http.Client, you can set useTLS to enable TLS or not
func HttpClientPost(tagurl string, useTLS bool, postdata ...interface{}) ([]byte, error) {
var body io.Reader
if len(postdata) > 0 {
params, err := json.Marshal(postdata)
if err != nil {
logger.E("Marshal post data err:", err)
return nil, err
}
body = bytes.NewReader(params)
} else {
body = http.NoBody
}
req, err := http.NewRequest("POST", tagurl, body)
if err != nil {
logger.E("Create http request err:", err)
return nil, err
}
req.Header.Set("Content-Type", ContentTypeJson)
return httpClientDo(req, useTLS)
}
// HttpClientGetStruct handle http get method and unmarshal data to struct object
func HttpClientGetStruct(tagurl string, useTLS bool, out interface{}, params ...interface{}) error {
body, err := HttpClientGet(tagurl, useTLS, params...)
if err != nil {
return err
}
if err := json.Unmarshal(body, out); err != nil {
logger.E("Unmarshal bady to struct err:", err)
return err
}
logger.D("HttpClientGetStruct:", out)
return nil
}
// HttpClientPostStruct handle http post method and unmarshal data to struct object
func HttpClientPostStruct(tagurl string, useTLS bool, out interface{}, postdata ...interface{}) error {
body, err := HttpClientPost(tagurl, useTLS, postdata...)
if err != nil {
return err
}
if err := json.Unmarshal(body, out); err != nil {
logger.E("Unmarshal bady to struct err:", err)
return err
}
logger.D("HttpClientPostStruct:", out)
return nil
}
// httpPostJson http post method, you can set post data as json struct.
func httpPostJson(tagurl string, postdata interface{}) ([]byte, error) {
params, err := json.Marshal(postdata)
if err != nil {
logger.E("Marshal post data err:", err)
return nil, err
}
resp, err := http.Post(tagurl, ContentTypeJson, bytes.NewReader(params))
if err != nil {
logger.E("Http post json err:", err)
return nil, err
}
defer resp.Body.Close()
// check response status
if resp.StatusCode != http.StatusOK {
logger.E("Failed http post, status:", resp.StatusCode)
return nil, invar.ErrInvalidState
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
logger.E("Read post response err:", err)
return nil, err
}
logger.D("HttpPostJson:", tagurl, "data:", postdata, "body:", string(body))
return body, nil
}
// httpPostForm http post method, you can set post data as url.Values.
func httpPostForm(tagurl string, postdata url.Values) ([]byte, error) {
resp, err := http.PostForm(tagurl, postdata)
if err != nil {
logger.E("Http post form err:", err)
return nil, err
}
defer resp.Body.Close()
// check response status
if resp.StatusCode != http.StatusOK {
logger.E("Failed http post, status:", resp.StatusCode)
return nil, invar.ErrInvalidState
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
logger.E("Read post response err:", err)
return nil, err
}
logger.D("HttpPostForm:", tagurl, "data:", postdata, "body:", string(body))
return body, nil
}
// httpClientDo handle http client DO method, and return response.
func httpClientDo(req *http.Request, useTLS bool) ([]byte, error) {
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: !useTLS,
},
},
}
resp, err := client.Do(req)
if err != nil {
logger.E("Execute client DO err:", err)
return nil, err
}
defer resp.Body.Close()
// check response status
if resp.StatusCode != http.StatusOK {
logger.E("Failed http client, status:", resp.StatusCode)
return nil, invar.ErrInvalidState
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
logger.E("Read client response err:", err)
return nil, err
}
logger.D("HttpClientDo: body:", string(body))
return body, nil
}