blob: 91b320930eda35213437252b87950e587429662e [file] [log] [blame]
Tang Cheng26b91152015-07-22 12:26:52 +08001package swservice
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +08002
3import (
Tang Chengc3ba6442019-02-28 09:55:31 +08004 "bytes"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +08005 "crypto/hmac"
guangcheng.qinfb12d0d2019-08-08 17:06:36 +08006 "crypto/sha256"
Tang Chengf8716aa2015-08-19 10:20:40 +08007 "crypto/tls"
Tang Cheng26b91152015-07-22 12:26:52 +08008 "encoding/hex"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +08009 "encoding/json"
qiaoweica037fa2015-07-10 18:31:53 +080010 "errors"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080011 "fmt"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080012 "net"
13 "net/http"
Tang Chengf16121a2015-07-27 13:46:14 +080014 "strconv"
Tang Chengf8716aa2015-08-19 10:20:40 +080015 "strings"
Tang Cheng78513ea2015-10-28 14:32:02 +080016 "sync"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080017 "time"
Tang Chenga412d202016-01-27 09:24:53 +080018
Tang Cheng51242e22016-07-14 14:52:07 +080019 "crypto/x509"
20
Tang Chenga412d202016-01-27 09:24:53 +080021 log "github.com/Sirupsen/logrus"
Tang Cheng62fdaa32019-01-11 10:12:41 +080022 "gopkg.in/resty.v1"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080023)
Tang Cheng32e32562015-07-08 17:08:03 +080024
Tang Cheng51242e22016-07-14 14:52:07 +080025var (
26 // ErrBadCAPEM 错误的 CA 文件
27 ErrBadCAPEM = errors.New("不正确的PEM文件")
28)
29
Tang Chengcb9f8782019-01-08 16:00:37 +080030var connectionTimeout = time.Duration(500) * time.Millisecond
31
Tang Chenge29065c2016-07-14 12:29:42 +080032// WebSession web session object
Tang Cheng32e32562015-07-08 17:08:03 +080033type WebSession struct {
Tang Chenge29065c2016-07-14 12:29:42 +080034 // AppId app id
35 AppID string
36 // TermId term id
37 TermID string
38 // Appsecret secret
39 AppSecret string
40 // BaseUrl base url
41 BaseURL string
42 // DefaultTimeout default time
Tang Cheng78513ea2015-10-28 14:32:02 +080043 DefaultTimeout int
Tang Chenge29065c2016-07-14 12:29:42 +080044 sessionKey string
guangcheng.qinfb12d0d2019-08-08 17:06:36 +080045 jwt string
46 expiredAt int64
Tang Chenge29065c2016-07-14 12:29:42 +080047 sslVerify bool
guangcheng.qinfb12d0d2019-08-08 17:06:36 +080048 startTime int64
Tang Cheng78513ea2015-10-28 14:32:02 +080049 httpConnectionPool sync.Pool
Tang Cheng32e32562015-07-08 17:08:03 +080050}
51
Tang Chenge29065c2016-07-14 12:29:42 +080052func safeGetJSONInt(value interface{}) int {
Tang Chengf16121a2015-07-27 13:46:14 +080053 if value == nil {
54 return 0
55 }
56 s := fmt.Sprintf("%v", value)
Tang Chenge29065c2016-07-14 12:29:42 +080057 i, err := strconv.Atoi(s)
58 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +080059 return 0
Tang Chengf16121a2015-07-27 13:46:14 +080060 }
Tang Chenge29065c2016-07-14 12:29:42 +080061 return i
Tang Chengf16121a2015-07-27 13:46:14 +080062}
63
Tang Chenge29065c2016-07-14 12:29:42 +080064// ServiceResponse service response object
Tang Chengf16121a2015-07-27 13:46:14 +080065type ServiceResponse struct {
Tang Chenge29065c2016-07-14 12:29:42 +080066 // RetCode return code
Tang Chengf16121a2015-07-27 13:46:14 +080067 RetCode int
Tang Chenge29065c2016-07-14 12:29:42 +080068 // RetMsg return message
69 RetMsg string
70 // Result return data
71 Result map[string]interface{}
Tang Chengf16121a2015-07-27 13:46:14 +080072}
73
Tang Chenge29065c2016-07-14 12:29:42 +080074// NewServiceResponseFromJSON parse json response data
75func NewServiceResponseFromJSON(jsonData interface{}) *ServiceResponse {
76 if jsonData == nil {
Tang Chengf16121a2015-07-27 13:46:14 +080077 return nil
78 }
79 res := &ServiceResponse{}
Tang Chenge29065c2016-07-14 12:29:42 +080080 res.Result = jsonData.(map[string]interface{})
81 res.RetCode = safeGetJSONInt(res.Result["retcode"])
Tang Chengf16121a2015-07-27 13:46:14 +080082 res.RetMsg = res.GetStrValue("retmsg")
83 return res
84}
Tang Chenge29065c2016-07-14 12:29:42 +080085
86// GetIntValue get int value
Tang Chengf16121a2015-07-27 13:46:14 +080087func (r *ServiceResponse) GetIntValue(name string) int {
Tang Chenge29065c2016-07-14 12:29:42 +080088 return safeGetJSONInt(r.Result[name])
Tang Chengf16121a2015-07-27 13:46:14 +080089}
90
Tang Chenge29065c2016-07-14 12:29:42 +080091// GetStrValue get string value
Tang Chengf16121a2015-07-27 13:46:14 +080092func (r *ServiceResponse) GetStrValue(name string) string {
Tang Chenge29065c2016-07-14 12:29:42 +080093 s, ok := r.Result[name]
94 if ok {
Tang Chengf16121a2015-07-27 13:46:14 +080095 return fmt.Sprintf("%v", s)
Tang Chengf16121a2015-07-27 13:46:14 +080096 }
Tang Chenge29065c2016-07-14 12:29:42 +080097 return ""
Tang Chengf16121a2015-07-27 13:46:14 +080098}
99
Tang Chenge29065c2016-07-14 12:29:42 +0800100// GetInterfaceValue get value as interface
zongqiang.zhang134f4182016-06-14 15:23:22 +0800101func (r *ServiceResponse) GetInterfaceValue(name string) interface{} {
Tang Chenge29065c2016-07-14 12:29:42 +0800102 s, ok := r.Result[name]
103 if ok {
zongqiang.zhang134f4182016-06-14 15:23:22 +0800104 return s
zongqiang.zhang134f4182016-06-14 15:23:22 +0800105 }
Tang Chenge29065c2016-07-14 12:29:42 +0800106 return nil
zongqiang.zhang134f4182016-06-14 15:23:22 +0800107}
Tang Chenge29065c2016-07-14 12:29:42 +0800108
109// GetFloatValue get float value
Tang Chengf16121a2015-07-27 13:46:14 +0800110func (r *ServiceResponse) GetFloatValue(name string) float64 {
111 if s, ok := r.Result[name]; ok {
112 t := fmt.Sprintf("%v", s)
Tang Chenge29065c2016-07-14 12:29:42 +0800113 f, err := strconv.ParseFloat(t, 64)
114 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +0800115 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800116 }
Tang Chenge29065c2016-07-14 12:29:42 +0800117 return f
Tang Chengf16121a2015-07-27 13:46:14 +0800118 }
Tang Chenge29065c2016-07-14 12:29:42 +0800119 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800120}
121
Tang Cheng62fdaa32019-01-11 10:12:41 +0800122// doGet send GET request
123func (w *WebSession) doGet(uri string, params map[string]string,
124 timeout int) (*resty.Response, error) {
Tang Cheng32e32562015-07-08 17:08:03 +0800125
Tang Chenge29065c2016-07-14 12:29:42 +0800126 fullURL := w.BaseURL + uri
Tang Cheng62fdaa32019-01-11 10:12:41 +0800127 resty.SetTimeout(time.Duration(timeout) * time.Second)
128 resp, err := resty.R().
129 SetQueryParams(params).
130 Get(fullURL)
131 return resp, err
Tang Cheng32e32562015-07-08 17:08:03 +0800132}
133
Tang Chenge29065c2016-07-14 12:29:42 +0800134// GetTimestamp get time stamp format 20160103133455
Tang Cheng32e32562015-07-08 17:08:03 +0800135func (w *WebSession) GetTimestamp() string {
136 t := time.Now()
137 return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(),
138 t.Hour(), t.Minute(), t.Second())
139}
140
Tang Chenge29065c2016-07-14 12:29:42 +0800141// SignWithKey sign with key
Tang Chengf16121a2015-07-27 13:46:14 +0800142func (w *WebSession) SignWithKey(key, message string) string {
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800143 mac := hmac.New(sha256.New, []byte(key))
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800144 mac.Write([]byte(message))
145 res := mac.Sum(nil)
Tang Cheng26b91152015-07-22 12:26:52 +0800146 return hex.EncodeToString(res)
Tang Cheng32e32562015-07-08 17:08:03 +0800147}
Tang Chenge29065c2016-07-14 12:29:42 +0800148
149// Sign sign data
Tang Chengf16121a2015-07-27 13:46:14 +0800150func (w *WebSession) Sign(message string) string {
Tang Chenge29065c2016-07-14 12:29:42 +0800151 return w.SignWithKey(w.AppSecret, message)
Tang Chengf16121a2015-07-27 13:46:14 +0800152}
Tang Cheng32e32562015-07-08 17:08:03 +0800153
Tang Chenge29065c2016-07-14 12:29:42 +0800154func newTransport(baseurl string, sslVerify bool) *http.Transport {
Tang Chengf8716aa2015-08-19 10:20:40 +0800155 var transport http.Transport
Tang Cheng78513ea2015-10-28 14:32:02 +0800156 if strings.HasPrefix(baseurl, "https://") {
Tang Cheng0b9abf12015-08-20 09:55:32 +0800157 var b bool
Tang Chenge29065c2016-07-14 12:29:42 +0800158 if sslVerify {
Tang Cheng0b9abf12015-08-20 09:55:32 +0800159 b = false
160 } else {
161 b = true
162 }
Tang Cheng78513ea2015-10-28 14:32:02 +0800163 transport = http.Transport{MaxIdleConnsPerHost: 0,
Tang Cheng91665852015-08-29 22:17:20 +0800164 TLSClientConfig: &tls.Config{InsecureSkipVerify: b},
Tang Cheng78513ea2015-10-28 14:32:02 +0800165 TLSHandshakeTimeout: time.Duration(1) * time.Second,
Tang Cheng91665852015-08-29 22:17:20 +0800166 Dial: func(network, addr string) (net.Conn, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800167 defaultTimeout := time.Duration(1) * time.Second
168 return net.DialTimeout(network, addr, defaultTimeout)
Tang Cheng91665852015-08-29 22:17:20 +0800169 }}
Tang Cheng78513ea2015-10-28 14:32:02 +0800170 } else if strings.HasPrefix(baseurl, "http://") {
171 transport = http.Transport{MaxIdleConnsPerHost: 0,
Tang Cheng91665852015-08-29 22:17:20 +0800172 Dial: func(network, addr string) (net.Conn, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800173 defaultTimeout := time.Duration(1) * time.Second
174 return net.DialTimeout(network, addr, defaultTimeout)
Tang Cheng91665852015-08-29 22:17:20 +0800175 }}
Tang Chengf8716aa2015-08-19 10:20:40 +0800176 }
Tang Cheng78513ea2015-10-28 14:32:02 +0800177 log.Debugf("创建新连接")
178 return &transport
Tang Chengf16121a2015-07-27 13:46:14 +0800179}
Tang Chengf8716aa2015-08-19 10:20:40 +0800180
Tang Cheng62fdaa32019-01-11 10:12:41 +0800181// doPost send POST request
182func (w *WebSession) doPost(uri string, param map[string]string) (*resty.Response, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800183 param["app_id"] = w.AppID
184 param["term_id"] = w.TermID
Tang Cheng26b91152015-07-22 12:26:52 +0800185 param["sign_method"] = "HMAC"
Tang Chenge29065c2016-07-14 12:29:42 +0800186 param["session_key"] = w.sessionKey
Tang Cheng32e32562015-07-08 17:08:03 +0800187 ts := w.GetTimestamp()
Tang Cheng26b91152015-07-22 12:26:52 +0800188 param["timestamp"] = ts
Tang Chenge29065c2016-07-14 12:29:42 +0800189 param["sign"] = w.Sign(w.AppID + w.TermID + w.sessionKey + ts)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800190
Tang Chenge29065c2016-07-14 12:29:42 +0800191 fullURL := w.BaseURL + uri
Tang Cheng62fdaa32019-01-11 10:12:41 +0800192 r, err := resty.R().
193 SetHeader("Content-Type", "application/json").
194 SetBody(param).
195 Post(fullURL)
196 if err != nil || r.StatusCode() != 200 {
197 log.Errorf("Status=%v, err=%v", r.StatusCode(), err)
Tang Cheng32e32562015-07-08 17:08:03 +0800198 }
199 return r, err
200}
201
Tang Chenge29065c2016-07-14 12:29:42 +0800202// Auth authorization
Tang Cheng32e32562015-07-08 17:08:03 +0800203func (w *WebSession) Auth() error {
qiaoweica037fa2015-07-10 18:31:53 +0800204 token, err := w.getAuthToken()
205 if err != nil {
206 return err
207 }
208 err = w.getAppAccessKey(token)
209 if err != nil {
210 return err
211 }
Tang Cheng32e32562015-07-08 17:08:03 +0800212 return nil
213}
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800214
Tang Chenge29065c2016-07-14 12:29:42 +0800215// NewSession new session object
Tang Cheng0b9abf12015-08-20 09:55:32 +0800216func NewSession(appid, appsecret, termid, baseurl string, timeout int, sslVerify bool) *WebSession {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800217 return &WebSession{
Tang Chenge29065c2016-07-14 12:29:42 +0800218 AppID: appid,
219 AppSecret: appsecret,
220 TermID: termid,
221 BaseURL: baseurl,
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800222 DefaultTimeout: timeout,
Tang Chenge29065c2016-07-14 12:29:42 +0800223 sslVerify: sslVerify,
Tang Cheng62fdaa32019-01-11 10:12:41 +0800224 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800225}
226
Tang Cheng51242e22016-07-14 14:52:07 +0800227// NewSessionWithCA new session ca
228func NewSessionWithCA(appID, appSecret, termID, baseURL string,
229 timeout int, ca []byte) (*WebSession, error) {
230 certs := x509.NewCertPool()
231 if !certs.AppendCertsFromPEM(ca) {
232 return nil, ErrBadCAPEM
233 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800234 resty.SetTLSClientConfig(&tls.Config{
235 InsecureSkipVerify: true,
236 RootCAs: certs,
237 })
Tang Cheng51242e22016-07-14 14:52:07 +0800238
Tang Cheng84839422016-07-14 14:57:19 +0800239 return &WebSession{
240 AppID: appID,
241 AppSecret: appSecret,
242 TermID: termID,
243 BaseURL: baseURL,
244 DefaultTimeout: timeout,
245 sslVerify: true,
246 }, nil
Tang Cheng51242e22016-07-14 14:52:07 +0800247}
248
qiaoweica037fa2015-07-10 18:31:53 +0800249func (w *WebSession) getAuthToken() (string, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800250 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800251 AppID string `json:"app_id"`
252 TermID string `json:"term_id"`
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800253 AccessToken string `json:"token"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800254 }
255
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800256 uri := "/auth/gettoken"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800257
258 params := make(map[string]string)
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800259 params["appid"] = w.AppID
260 r, err := w.doGet(uri, params, 10)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800261
Tang Chengf8716aa2015-08-19 10:20:40 +0800262 if err != nil {
Tang Chengf8716aa2015-08-19 10:20:40 +0800263 return "", err
264 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800265 if r.StatusCode() != 200 {
qiaoweica037fa2015-07-10 18:31:53 +0800266 return "", errors.New("请求失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800267 }
268
Tang Cheng62fdaa32019-01-11 10:12:41 +0800269 body := r.Body()
Tang Cheng51242e22016-07-14 14:52:07 +0800270 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800271 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800272 if err != nil {
273 log.Errorf("json unmarshal err %v", err)
qiaoweica037fa2015-07-10 18:31:53 +0800274 return "", errors.New("解析失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800275 }
qiaoweica037fa2015-07-10 18:31:53 +0800276 return s.AccessToken, nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800277}
Tang Chenge29065c2016-07-14 12:29:42 +0800278
qiaoweica037fa2015-07-10 18:31:53 +0800279func (w *WebSession) getAppAccessKey(token string) error {
Tang Cheng51242e22016-07-14 14:52:07 +0800280 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800281 AppID string `json:"app_id"`
282 TermID string `json:"term_id"`
qiaoweica037fa2015-07-10 18:31:53 +0800283 SessionKey string `json:"session_key"`
284 CardKey string `json:"card_key"`
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800285 Jwt string `json:"jwt"`
286 ExpiredAt string `json:"expiredAt"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800287 }
288
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800289 uri := "/auth/authentication"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800290
291 params := make(map[string]string)
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800292 params["appid"] = w.AppID
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800293 params["timestamp"] = w.GetTimestamp()
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800294 params["sign"] = w.Sign(token)
295 params["sign_method"] = "HMAC-SHA256"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800296
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800297 r, err := w.doGet(uri, params, 10)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800298 if err != nil {
299 log.Errorf("err = %v\n", err)
qiaoweica037fa2015-07-10 18:31:53 +0800300 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800301 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800302
303 if r.StatusCode() != 200 {
304 log.Errorf(" errcode = %v\n", r.StatusCode())
305 return fmt.Errorf("code %v", r.StatusCode())
zongqiang.zhang134f4182016-06-14 15:23:22 +0800306 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800307
Tang Cheng62fdaa32019-01-11 10:12:41 +0800308 body := r.Body()
qiaoweica037fa2015-07-10 18:31:53 +0800309
Tang Cheng51242e22016-07-14 14:52:07 +0800310 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800311 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800312 if err != nil {
313 log.Errorf("json unmarshal err %v", err)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800314 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800315 }
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800316 w.jwt = s.Jwt
317 //JWT is valid for 20 minutes
318 w.expiredAt = 20 * 60
319 w.startTime = time.Now().Unix()
320 return nil
321}
322
323func (w *WebSession) updateJwt() error {
324 type FormJSON struct {
325 AppID string `json:"app_id"`
326 Jwt string `json:"jwt"`
327 }
328 nowTime := time.Now().Unix()
329 if nowTime-w.startTime >= w.expiredAt {
330 uri := "/auth/refresh"
331
332 params := make(map[string]string)
333 params["appid"] = w.AppID
334
335 fullURL := w.BaseURL + uri
336 log.Debugf("CallService: %v", fullURL)
337 r, err := resty.R().
338 SetHeader("Authorization", "Bearer "+w.jwt).
339 Get(fullURL)
340 if err != nil || r.StatusCode() != 200 {
341 log.Errorf("Status=%v, err=%v", r.StatusCode(), err)
342 return err
343 }
344
345 body := r.Body()
346
347 s := &FormJSON{}
348 err = json.Unmarshal(body, &s)
349 if err != nil {
350 log.Errorf("json unmarshal err %v", err)
351 return err
352 }
353 w.jwt = s.Jwt
354 w.startTime = nowTime
355 }
qiaoweica037fa2015-07-10 18:31:53 +0800356 return nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800357}
Tang Cheng26b91152015-07-22 12:26:52 +0800358
Tang Chenge29065c2016-07-14 12:29:42 +0800359// CallYKTApi call ykt api function
Tang Cheng26b91152015-07-22 12:26:52 +0800360func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800361 callData := request.Serialize()
Tang Cheng26b91152015-07-22 12:26:52 +0800362 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800363 params["funcdata"] = callData
Tang Cheng26b91152015-07-22 12:26:52 +0800364
Tang Cheng62fdaa32019-01-11 10:12:41 +0800365 r, err := w.doPost("/ecardservice/ecardapi", params)
Tang Chengf16121a2015-07-27 13:46:14 +0800366 if err != nil {
Tang Cheng26b91152015-07-22 12:26:52 +0800367 log.Errorf(" err = %v\n", err)
368 return nil, err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800369 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800370
Tang Cheng62fdaa32019-01-11 10:12:41 +0800371 if r.StatusCode() != 200 {
372 return nil, fmt.Errorf("Request StatusCode:%v", r.StatusCode())
Tang Chengf16121a2015-07-27 13:46:14 +0800373 }
374
Tang Cheng62fdaa32019-01-11 10:12:41 +0800375 return NewMessageReader(r.Body()), nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800376}
Tang Chengf16121a2015-07-27 13:46:14 +0800377
Tang Chenge29065c2016-07-14 12:29:42 +0800378// CallService call epay service
Tang Chengf16121a2015-07-27 13:46:14 +0800379func (w *WebSession) CallService(path string, params map[string]interface{},
Tang Chenge29065c2016-07-14 12:29:42 +0800380 signField []string, timeout int) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800381
Tang Chenge29065c2016-07-14 12:29:42 +0800382 return w.CallService2(path, params, timeout, signField...)
Tang Chengf16121a2015-07-27 13:46:14 +0800383}
384
Tang Chengcb9f8782019-01-08 16:00:37 +0800385// SetConnectionTimeout set global connection timeout
386func SetConnectionTimeout(ms int) {
387 connectionTimeout = time.Duration(ms) * time.Millisecond
Tang Cheng62fdaa32019-01-11 10:12:41 +0800388 resty.SetTimeout(connectionTimeout)
Tang Chengcb9f8782019-01-08 16:00:37 +0800389}
390
Tang Chenge29065c2016-07-14 12:29:42 +0800391// CallService2 call epay service
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800392func (w *WebSession) CallService2(path string, params map[string]interface{},
393 timeout int, signField ...string) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800394 err = nil
Tang Chengf16121a2015-07-27 13:46:14 +0800395
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800396 if err = w.updateJwt(); err != nil {
397 log.Errorf("updateJwt err = %v", err)
398 return
399 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800400 formData := make(map[string]string)
Tang Cheng72bc9002019-01-11 11:29:59 +0800401 if params != nil {
402 for k, v := range params {
403 formData[k] = fmt.Sprintf("%v", v)
404 }
Tang Chengf16121a2015-07-27 13:46:14 +0800405 }
Tang Cheng72bc9002019-01-11 11:29:59 +0800406 formData["app_id"] = w.AppID
407 formData["term_id"] = w.TermID
408 ts := w.GetTimestamp()
409 formData["timestamp"] = ts
Tang Chengf16121a2015-07-27 13:46:14 +0800410
Tang Cheng51242e22016-07-14 14:52:07 +0800411 fullURL := w.BaseURL + path
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800412 log.Debugf("CallService: %v", fullURL)
Tang Cheng62fdaa32019-01-11 10:12:41 +0800413 r, err := resty.R().
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800414 SetHeader("Authorization", "Bearer "+w.jwt).
Tang Cheng62fdaa32019-01-11 10:12:41 +0800415 SetHeader("Accept", "application/json").
416 SetFormData(formData).
417 Post(fullURL)
Tang Chengf16121a2015-07-27 13:46:14 +0800418 if err != nil {
419 log.Errorf("Status=%v, err=%v", r, err)
420 return
421 }
Tang Chengfb7ab582016-08-13 22:25:30 +0800422
Tang Cheng62fdaa32019-01-11 10:12:41 +0800423 if r.StatusCode() != 200 {
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800424 log.Errorf("Request Error %v", r.StatusCode())
Tang Cheng62fdaa32019-01-11 10:12:41 +0800425 err = fmt.Errorf("Request Error, StatusCode : %v", r.StatusCode())
Tang Chengf16121a2015-07-27 13:46:14 +0800426 return
427 }
Tang Chengfb7ab582016-08-13 22:25:30 +0800428
Tang Chengf16121a2015-07-27 13:46:14 +0800429 var s interface{}
Tang Chengc3ba6442019-02-28 09:55:31 +0800430 decoder := json.NewDecoder(bytes.NewBuffer(r.Body()))
431 decoder.UseNumber() // 此处能够保证bigint的精度
432 err = decoder.Decode(&s)
433 // err = json.Unmarshal(r.Body(), &s)
Tang Chengf16121a2015-07-27 13:46:14 +0800434 if err != nil {
435 log.Errorf("json unmarshal err %v", err)
436 return
437 }
Tang Chenge29065c2016-07-14 12:29:42 +0800438 response = NewServiceResponseFromJSON(s)
Tang Chengf16121a2015-07-27 13:46:14 +0800439 return
440}