blob: 8ae4e69cf00f1783913a64bf79749d2c5c75d1d5 [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 Cheng62fdaa32019-01-11 10:12:41 +080021 "gopkg.in/resty.v1"
Tang Chengea3f5372019-09-29 14:40:22 +080022 log "github.com/sirupsen/logrus"
23 "github.com/franela/goreq"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080024)
Tang Cheng32e32562015-07-08 17:08:03 +080025
Tang Cheng51242e22016-07-14 14:52:07 +080026var (
27 // ErrBadCAPEM 错误的 CA 文件
28 ErrBadCAPEM = errors.New("不正确的PEM文件")
29)
30
Tang Chengcb9f8782019-01-08 16:00:37 +080031var connectionTimeout = time.Duration(500) * time.Millisecond
32
Tang Chenge29065c2016-07-14 12:29:42 +080033// WebSession web session object
Tang Cheng32e32562015-07-08 17:08:03 +080034type WebSession struct {
Tang Chenge29065c2016-07-14 12:29:42 +080035 // AppId app id
36 AppID string
37 // TermId term id
38 TermID string
39 // Appsecret secret
40 AppSecret string
41 // BaseUrl base url
42 BaseURL string
43 // DefaultTimeout default time
Tang Cheng78513ea2015-10-28 14:32:02 +080044 DefaultTimeout int
Tang Chenge29065c2016-07-14 12:29:42 +080045 sessionKey string
guangcheng.qinfb12d0d2019-08-08 17:06:36 +080046 jwt string
47 expiredAt int64
Tang Chenge29065c2016-07-14 12:29:42 +080048 sslVerify bool
guangcheng.qinfb12d0d2019-08-08 17:06:36 +080049 startTime int64
Tang Cheng78513ea2015-10-28 14:32:02 +080050 httpConnectionPool sync.Pool
Tang Cheng32e32562015-07-08 17:08:03 +080051}
52
Tang Chenge29065c2016-07-14 12:29:42 +080053func safeGetJSONInt(value interface{}) int {
Tang Chengf16121a2015-07-27 13:46:14 +080054 if value == nil {
55 return 0
56 }
57 s := fmt.Sprintf("%v", value)
Tang Chenge29065c2016-07-14 12:29:42 +080058 i, err := strconv.Atoi(s)
59 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +080060 return 0
Tang Chengf16121a2015-07-27 13:46:14 +080061 }
Tang Chenge29065c2016-07-14 12:29:42 +080062 return i
Tang Chengf16121a2015-07-27 13:46:14 +080063}
64
Tang Chenge29065c2016-07-14 12:29:42 +080065// ServiceResponse service response object
Tang Chengf16121a2015-07-27 13:46:14 +080066type ServiceResponse struct {
Tang Chenge29065c2016-07-14 12:29:42 +080067 // RetCode return code
Tang Chengf16121a2015-07-27 13:46:14 +080068 RetCode int
Tang Chenge29065c2016-07-14 12:29:42 +080069 // RetMsg return message
70 RetMsg string
71 // Result return data
72 Result map[string]interface{}
Tang Chengf16121a2015-07-27 13:46:14 +080073}
74
Tang Chenge29065c2016-07-14 12:29:42 +080075// NewServiceResponseFromJSON parse json response data
76func NewServiceResponseFromJSON(jsonData interface{}) *ServiceResponse {
77 if jsonData == nil {
Tang Chengf16121a2015-07-27 13:46:14 +080078 return nil
79 }
80 res := &ServiceResponse{}
Tang Chenge29065c2016-07-14 12:29:42 +080081 res.Result = jsonData.(map[string]interface{})
82 res.RetCode = safeGetJSONInt(res.Result["retcode"])
Tang Chengf16121a2015-07-27 13:46:14 +080083 res.RetMsg = res.GetStrValue("retmsg")
84 return res
85}
Tang Chenge29065c2016-07-14 12:29:42 +080086
87// GetIntValue get int value
Tang Chengf16121a2015-07-27 13:46:14 +080088func (r *ServiceResponse) GetIntValue(name string) int {
Tang Chenge29065c2016-07-14 12:29:42 +080089 return safeGetJSONInt(r.Result[name])
Tang Chengf16121a2015-07-27 13:46:14 +080090}
91
Tang Chenge29065c2016-07-14 12:29:42 +080092// GetStrValue get string value
Tang Chengf16121a2015-07-27 13:46:14 +080093func (r *ServiceResponse) GetStrValue(name string) string {
Tang Chenge29065c2016-07-14 12:29:42 +080094 s, ok := r.Result[name]
95 if ok {
Tang Chengf16121a2015-07-27 13:46:14 +080096 return fmt.Sprintf("%v", s)
Tang Chengf16121a2015-07-27 13:46:14 +080097 }
Tang Chenge29065c2016-07-14 12:29:42 +080098 return ""
Tang Chengf16121a2015-07-27 13:46:14 +080099}
100
Tang Chenge29065c2016-07-14 12:29:42 +0800101// GetInterfaceValue get value as interface
zongqiang.zhang134f4182016-06-14 15:23:22 +0800102func (r *ServiceResponse) GetInterfaceValue(name string) interface{} {
Tang Chenge29065c2016-07-14 12:29:42 +0800103 s, ok := r.Result[name]
104 if ok {
zongqiang.zhang134f4182016-06-14 15:23:22 +0800105 return s
zongqiang.zhang134f4182016-06-14 15:23:22 +0800106 }
Tang Chenge29065c2016-07-14 12:29:42 +0800107 return nil
zongqiang.zhang134f4182016-06-14 15:23:22 +0800108}
Tang Chenge29065c2016-07-14 12:29:42 +0800109
110// GetFloatValue get float value
Tang Chengf16121a2015-07-27 13:46:14 +0800111func (r *ServiceResponse) GetFloatValue(name string) float64 {
112 if s, ok := r.Result[name]; ok {
113 t := fmt.Sprintf("%v", s)
Tang Chenge29065c2016-07-14 12:29:42 +0800114 f, err := strconv.ParseFloat(t, 64)
115 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +0800116 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800117 }
Tang Chenge29065c2016-07-14 12:29:42 +0800118 return f
Tang Chengf16121a2015-07-27 13:46:14 +0800119 }
Tang Chenge29065c2016-07-14 12:29:42 +0800120 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800121}
122
Tang Cheng62fdaa32019-01-11 10:12:41 +0800123// doGet send GET request
124func (w *WebSession) doGet(uri string, params map[string]string,
125 timeout int) (*resty.Response, error) {
Tang Cheng32e32562015-07-08 17:08:03 +0800126
Tang Chenge29065c2016-07-14 12:29:42 +0800127 fullURL := w.BaseURL + uri
Tang Cheng62fdaa32019-01-11 10:12:41 +0800128 resty.SetTimeout(time.Duration(timeout) * time.Second)
129 resp, err := resty.R().
130 SetQueryParams(params).
131 Get(fullURL)
132 return resp, err
Tang Cheng32e32562015-07-08 17:08:03 +0800133}
134
Tang Chenge29065c2016-07-14 12:29:42 +0800135// GetTimestamp get time stamp format 20160103133455
Tang Cheng32e32562015-07-08 17:08:03 +0800136func (w *WebSession) GetTimestamp() string {
137 t := time.Now()
138 return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(),
139 t.Hour(), t.Minute(), t.Second())
140}
141
Tang Chenge29065c2016-07-14 12:29:42 +0800142// SignWithKey sign with key
Tang Chengf16121a2015-07-27 13:46:14 +0800143func (w *WebSession) SignWithKey(key, message string) string {
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800144 mac := hmac.New(sha256.New, []byte(key))
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800145 mac.Write([]byte(message))
146 res := mac.Sum(nil)
Tang Cheng26b91152015-07-22 12:26:52 +0800147 return hex.EncodeToString(res)
Tang Cheng32e32562015-07-08 17:08:03 +0800148}
Tang Chenge29065c2016-07-14 12:29:42 +0800149
150// Sign sign data
Tang Chengf16121a2015-07-27 13:46:14 +0800151func (w *WebSession) Sign(message string) string {
Tang Chenge29065c2016-07-14 12:29:42 +0800152 return w.SignWithKey(w.AppSecret, message)
Tang Chengf16121a2015-07-27 13:46:14 +0800153}
Tang Cheng32e32562015-07-08 17:08:03 +0800154
Tang Chenge29065c2016-07-14 12:29:42 +0800155func newTransport(baseurl string, sslVerify bool) *http.Transport {
Tang Chengf8716aa2015-08-19 10:20:40 +0800156 var transport http.Transport
Tang Cheng78513ea2015-10-28 14:32:02 +0800157 if strings.HasPrefix(baseurl, "https://") {
Tang Cheng0b9abf12015-08-20 09:55:32 +0800158 var b bool
Tang Chenge29065c2016-07-14 12:29:42 +0800159 if sslVerify {
Tang Cheng0b9abf12015-08-20 09:55:32 +0800160 b = false
161 } else {
162 b = true
163 }
Tang Cheng78513ea2015-10-28 14:32:02 +0800164 transport = http.Transport{MaxIdleConnsPerHost: 0,
Tang Cheng91665852015-08-29 22:17:20 +0800165 TLSClientConfig: &tls.Config{InsecureSkipVerify: b},
Tang Cheng78513ea2015-10-28 14:32:02 +0800166 TLSHandshakeTimeout: time.Duration(1) * time.Second,
Tang Cheng91665852015-08-29 22:17:20 +0800167 Dial: func(network, addr string) (net.Conn, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800168 defaultTimeout := time.Duration(1) * time.Second
169 return net.DialTimeout(network, addr, defaultTimeout)
Tang Cheng91665852015-08-29 22:17:20 +0800170 }}
Tang Cheng78513ea2015-10-28 14:32:02 +0800171 } else if strings.HasPrefix(baseurl, "http://") {
172 transport = http.Transport{MaxIdleConnsPerHost: 0,
Tang Cheng91665852015-08-29 22:17:20 +0800173 Dial: func(network, addr string) (net.Conn, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800174 defaultTimeout := time.Duration(1) * time.Second
175 return net.DialTimeout(network, addr, defaultTimeout)
Tang Cheng91665852015-08-29 22:17:20 +0800176 }}
Tang Chengf8716aa2015-08-19 10:20:40 +0800177 }
Tang Cheng78513ea2015-10-28 14:32:02 +0800178 log.Debugf("创建新连接")
179 return &transport
Tang Chengf16121a2015-07-27 13:46:14 +0800180}
Tang Chengf8716aa2015-08-19 10:20:40 +0800181
Tang Cheng62fdaa32019-01-11 10:12:41 +0800182// doPost send POST request
183func (w *WebSession) doPost(uri string, param map[string]string) (*resty.Response, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800184 param["app_id"] = w.AppID
185 param["term_id"] = w.TermID
Tang Cheng26b91152015-07-22 12:26:52 +0800186 param["sign_method"] = "HMAC"
Tang Chenge29065c2016-07-14 12:29:42 +0800187 param["session_key"] = w.sessionKey
Tang Cheng32e32562015-07-08 17:08:03 +0800188 ts := w.GetTimestamp()
Tang Cheng26b91152015-07-22 12:26:52 +0800189 param["timestamp"] = ts
Tang Chenge29065c2016-07-14 12:29:42 +0800190 param["sign"] = w.Sign(w.AppID + w.TermID + w.sessionKey + ts)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800191
Tang Chenge29065c2016-07-14 12:29:42 +0800192 fullURL := w.BaseURL + uri
Tang Cheng62fdaa32019-01-11 10:12:41 +0800193 r, err := resty.R().
194 SetHeader("Content-Type", "application/json").
195 SetBody(param).
196 Post(fullURL)
197 if err != nil || r.StatusCode() != 200 {
198 log.Errorf("Status=%v, err=%v", r.StatusCode(), err)
Tang Cheng32e32562015-07-08 17:08:03 +0800199 }
200 return r, err
201}
202
Tang Chenge29065c2016-07-14 12:29:42 +0800203// Auth authorization
Tang Cheng32e32562015-07-08 17:08:03 +0800204func (w *WebSession) Auth() error {
qiaoweica037fa2015-07-10 18:31:53 +0800205 token, err := w.getAuthToken()
206 if err != nil {
207 return err
208 }
209 err = w.getAppAccessKey(token)
210 if err != nil {
211 return err
212 }
Tang Cheng32e32562015-07-08 17:08:03 +0800213 return nil
214}
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800215
guangcheng.qine2cae6e2019-08-19 10:03:06 +0800216func (w *WebSession) updateAuth() {
217 for {
218 log.Debugf("设备: %v 正在尝试重新连接登录验证!", w.AppID)
219 err := w.Auth()
220 if err == nil {
221 return
222 }
223 time.Sleep(time.Second * 10)
224 }
225}
226
Tang Chenge29065c2016-07-14 12:29:42 +0800227// NewSession new session object
Tang Cheng0b9abf12015-08-20 09:55:32 +0800228func NewSession(appid, appsecret, termid, baseurl string, timeout int, sslVerify bool) *WebSession {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800229 return &WebSession{
Tang Chenge29065c2016-07-14 12:29:42 +0800230 AppID: appid,
231 AppSecret: appsecret,
232 TermID: termid,
233 BaseURL: baseurl,
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800234 DefaultTimeout: timeout,
Tang Chenge29065c2016-07-14 12:29:42 +0800235 sslVerify: sslVerify,
Tang Cheng62fdaa32019-01-11 10:12:41 +0800236 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800237}
238
Tang Cheng51242e22016-07-14 14:52:07 +0800239// NewSessionWithCA new session ca
240func NewSessionWithCA(appID, appSecret, termID, baseURL string,
241 timeout int, ca []byte) (*WebSession, error) {
242 certs := x509.NewCertPool()
243 if !certs.AppendCertsFromPEM(ca) {
244 return nil, ErrBadCAPEM
245 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800246 resty.SetTLSClientConfig(&tls.Config{
247 InsecureSkipVerify: true,
248 RootCAs: certs,
249 })
Tang Cheng51242e22016-07-14 14:52:07 +0800250
Tang Cheng84839422016-07-14 14:57:19 +0800251 return &WebSession{
252 AppID: appID,
253 AppSecret: appSecret,
254 TermID: termID,
255 BaseURL: baseURL,
256 DefaultTimeout: timeout,
257 sslVerify: true,
258 }, nil
Tang Cheng51242e22016-07-14 14:52:07 +0800259}
260
qiaoweica037fa2015-07-10 18:31:53 +0800261func (w *WebSession) getAuthToken() (string, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800262 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800263 AppID string `json:"app_id"`
264 TermID string `json:"term_id"`
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800265 AccessToken string `json:"token"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800266 }
267
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800268 uri := "/auth/gettoken"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800269
270 params := make(map[string]string)
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800271 params["appid"] = w.AppID
272 r, err := w.doGet(uri, params, 10)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800273
Tang Chengf8716aa2015-08-19 10:20:40 +0800274 if err != nil {
Tang Chengf8716aa2015-08-19 10:20:40 +0800275 return "", err
276 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800277 if r.StatusCode() != 200 {
qiaoweica037fa2015-07-10 18:31:53 +0800278 return "", errors.New("请求失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800279 }
280
Tang Cheng62fdaa32019-01-11 10:12:41 +0800281 body := r.Body()
Tang Cheng51242e22016-07-14 14:52:07 +0800282 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800283 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800284 if err != nil {
285 log.Errorf("json unmarshal err %v", err)
qiaoweica037fa2015-07-10 18:31:53 +0800286 return "", errors.New("解析失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800287 }
qiaoweica037fa2015-07-10 18:31:53 +0800288 return s.AccessToken, nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800289}
Tang Chenge29065c2016-07-14 12:29:42 +0800290
qiaoweica037fa2015-07-10 18:31:53 +0800291func (w *WebSession) getAppAccessKey(token string) error {
Tang Cheng51242e22016-07-14 14:52:07 +0800292 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800293 AppID string `json:"app_id"`
294 TermID string `json:"term_id"`
qiaoweica037fa2015-07-10 18:31:53 +0800295 SessionKey string `json:"session_key"`
296 CardKey string `json:"card_key"`
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800297 Jwt string `json:"jwt"`
298 ExpiredAt string `json:"expiredAt"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800299 }
300
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800301 uri := "/auth/authentication"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800302
303 params := make(map[string]string)
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800304 params["appid"] = w.AppID
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800305 params["timestamp"] = w.GetTimestamp()
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800306 params["sign"] = w.Sign(token)
307 params["sign_method"] = "HMAC-SHA256"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800308
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800309 r, err := w.doGet(uri, params, 10)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800310 if err != nil {
311 log.Errorf("err = %v\n", err)
qiaoweica037fa2015-07-10 18:31:53 +0800312 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800313 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800314
315 if r.StatusCode() != 200 {
316 log.Errorf(" errcode = %v\n", r.StatusCode())
317 return fmt.Errorf("code %v", r.StatusCode())
zongqiang.zhang134f4182016-06-14 15:23:22 +0800318 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800319
Tang Cheng62fdaa32019-01-11 10:12:41 +0800320 body := r.Body()
qiaoweica037fa2015-07-10 18:31:53 +0800321
Tang Cheng51242e22016-07-14 14:52:07 +0800322 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800323 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800324 if err != nil {
325 log.Errorf("json unmarshal err %v", err)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800326 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800327 }
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800328 w.jwt = s.Jwt
329 //JWT is valid for 20 minutes
330 w.expiredAt = 20 * 60
331 w.startTime = time.Now().Unix()
332 return nil
333}
334
335func (w *WebSession) updateJwt() error {
336 type FormJSON struct {
337 AppID string `json:"app_id"`
338 Jwt string `json:"jwt"`
339 }
340 nowTime := time.Now().Unix()
341 if nowTime-w.startTime >= w.expiredAt {
342 uri := "/auth/refresh"
343
344 params := make(map[string]string)
345 params["appid"] = w.AppID
346
347 fullURL := w.BaseURL + uri
348 log.Debugf("CallService: %v", fullURL)
349 r, err := resty.R().
350 SetHeader("Authorization", "Bearer "+w.jwt).
351 Get(fullURL)
352 if err != nil || r.StatusCode() != 200 {
353 log.Errorf("Status=%v, err=%v", r.StatusCode(), err)
354 return err
355 }
356
357 body := r.Body()
358
359 s := &FormJSON{}
360 err = json.Unmarshal(body, &s)
361 if err != nil {
362 log.Errorf("json unmarshal err %v", err)
363 return err
364 }
365 w.jwt = s.Jwt
366 w.startTime = nowTime
367 }
qiaoweica037fa2015-07-10 18:31:53 +0800368 return nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800369}
Tang Cheng26b91152015-07-22 12:26:52 +0800370
Tang Chenge29065c2016-07-14 12:29:42 +0800371// CallYKTApi call ykt api function
Tang Cheng26b91152015-07-22 12:26:52 +0800372func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800373 callData := request.Serialize()
Tang Cheng26b91152015-07-22 12:26:52 +0800374 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800375 params["funcdata"] = callData
Tang Cheng26b91152015-07-22 12:26:52 +0800376
Tang Cheng62fdaa32019-01-11 10:12:41 +0800377 r, err := w.doPost("/ecardservice/ecardapi", params)
Tang Chengf16121a2015-07-27 13:46:14 +0800378 if err != nil {
Tang Cheng26b91152015-07-22 12:26:52 +0800379 log.Errorf(" err = %v\n", err)
380 return nil, err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800381 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800382
Tang Cheng62fdaa32019-01-11 10:12:41 +0800383 if r.StatusCode() != 200 {
384 return nil, fmt.Errorf("Request StatusCode:%v", r.StatusCode())
Tang Chengf16121a2015-07-27 13:46:14 +0800385 }
386
Tang Cheng62fdaa32019-01-11 10:12:41 +0800387 return NewMessageReader(r.Body()), nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800388}
Tang Chengf16121a2015-07-27 13:46:14 +0800389
Tang Chenge29065c2016-07-14 12:29:42 +0800390// CallService call epay service
Tang Chengf16121a2015-07-27 13:46:14 +0800391func (w *WebSession) CallService(path string, params map[string]interface{},
Tang Chenge29065c2016-07-14 12:29:42 +0800392 signField []string, timeout int) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800393
Tang Chenge29065c2016-07-14 12:29:42 +0800394 return w.CallService2(path, params, timeout, signField...)
Tang Chengf16121a2015-07-27 13:46:14 +0800395}
396
Tang Chengcb9f8782019-01-08 16:00:37 +0800397// SetConnectionTimeout set global connection timeout
398func SetConnectionTimeout(ms int) {
399 connectionTimeout = time.Duration(ms) * time.Millisecond
Tang Cheng62fdaa32019-01-11 10:12:41 +0800400 resty.SetTimeout(connectionTimeout)
Tang Chengcb9f8782019-01-08 16:00:37 +0800401}
402
Tang Chenge29065c2016-07-14 12:29:42 +0800403// CallService2 call epay service
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800404func (w *WebSession) CallService2(path string, params map[string]interface{},
405 timeout int, signField ...string) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800406 err = nil
Tang Chengf16121a2015-07-27 13:46:14 +0800407
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800408 if err = w.updateJwt(); err != nil {
409 log.Errorf("updateJwt err = %v", err)
410 return
411 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800412 formData := make(map[string]string)
Tang Cheng72bc9002019-01-11 11:29:59 +0800413 if params != nil {
414 for k, v := range params {
415 formData[k] = fmt.Sprintf("%v", v)
416 }
Tang Chengf16121a2015-07-27 13:46:14 +0800417 }
Tang Cheng72bc9002019-01-11 11:29:59 +0800418 formData["app_id"] = w.AppID
419 formData["term_id"] = w.TermID
420 ts := w.GetTimestamp()
421 formData["timestamp"] = ts
Tang Chengf16121a2015-07-27 13:46:14 +0800422
Tang Cheng51242e22016-07-14 14:52:07 +0800423 fullURL := w.BaseURL + path
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800424 log.Debugf("CallService: %v", fullURL)
Tang Cheng62fdaa32019-01-11 10:12:41 +0800425 r, err := resty.R().
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800426 SetHeader("Authorization", "Bearer "+w.jwt).
Tang Cheng62fdaa32019-01-11 10:12:41 +0800427 SetHeader("Accept", "application/json").
428 SetFormData(formData).
429 Post(fullURL)
Tang Chengf16121a2015-07-27 13:46:14 +0800430 if err != nil {
431 log.Errorf("Status=%v, err=%v", r, err)
432 return
433 }
Tang Chengfb7ab582016-08-13 22:25:30 +0800434
guangcheng.qine2cae6e2019-08-19 10:03:06 +0800435 if r.StatusCode() == 403 || r.StatusCode() == 401 {
436 w.updateAuth()
437 }
438
Tang Cheng62fdaa32019-01-11 10:12:41 +0800439 if r.StatusCode() != 200 {
guangcheng.qinfb12d0d2019-08-08 17:06:36 +0800440 log.Errorf("Request Error %v", r.StatusCode())
Tang Cheng62fdaa32019-01-11 10:12:41 +0800441 err = fmt.Errorf("Request Error, StatusCode : %v", r.StatusCode())
Tang Chengf16121a2015-07-27 13:46:14 +0800442 return
443 }
Tang Chengfb7ab582016-08-13 22:25:30 +0800444
Tang Chengf16121a2015-07-27 13:46:14 +0800445 var s interface{}
Tang Chengc3ba6442019-02-28 09:55:31 +0800446 decoder := json.NewDecoder(bytes.NewBuffer(r.Body()))
447 decoder.UseNumber() // 此处能够保证bigint的精度
448 err = decoder.Decode(&s)
449 // err = json.Unmarshal(r.Body(), &s)
Tang Chengf16121a2015-07-27 13:46:14 +0800450 if err != nil {
451 log.Errorf("json unmarshal err %v", err)
452 return
453 }
Tang Chenge29065c2016-07-14 12:29:42 +0800454 response = NewServiceResponseFromJSON(s)
Tang Chengf16121a2015-07-27 13:46:14 +0800455 return
456}