blob: 5d0c7500e039224eb8922e24b9d92d0b77d1c227 [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"
6 "crypto/sha1"
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
45 sslVerify bool
Tang Cheng78513ea2015-10-28 14:32:02 +080046 httpConnectionPool sync.Pool
Tang Cheng32e32562015-07-08 17:08:03 +080047}
48
Tang Chenge29065c2016-07-14 12:29:42 +080049func safeGetJSONInt(value interface{}) int {
Tang Chengf16121a2015-07-27 13:46:14 +080050 if value == nil {
51 return 0
52 }
53 s := fmt.Sprintf("%v", value)
Tang Chenge29065c2016-07-14 12:29:42 +080054 i, err := strconv.Atoi(s)
55 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +080056 return 0
Tang Chengf16121a2015-07-27 13:46:14 +080057 }
Tang Chenge29065c2016-07-14 12:29:42 +080058 return i
Tang Chengf16121a2015-07-27 13:46:14 +080059}
60
Tang Chenge29065c2016-07-14 12:29:42 +080061// ServiceResponse service response object
Tang Chengf16121a2015-07-27 13:46:14 +080062type ServiceResponse struct {
Tang Chenge29065c2016-07-14 12:29:42 +080063 // RetCode return code
Tang Chengf16121a2015-07-27 13:46:14 +080064 RetCode int
Tang Chenge29065c2016-07-14 12:29:42 +080065 // RetMsg return message
66 RetMsg string
67 // Result return data
68 Result map[string]interface{}
Tang Chengf16121a2015-07-27 13:46:14 +080069}
70
Tang Chenge29065c2016-07-14 12:29:42 +080071// NewServiceResponseFromJSON parse json response data
72func NewServiceResponseFromJSON(jsonData interface{}) *ServiceResponse {
73 if jsonData == nil {
Tang Chengf16121a2015-07-27 13:46:14 +080074 return nil
75 }
76 res := &ServiceResponse{}
Tang Chenge29065c2016-07-14 12:29:42 +080077 res.Result = jsonData.(map[string]interface{})
78 res.RetCode = safeGetJSONInt(res.Result["retcode"])
Tang Chengf16121a2015-07-27 13:46:14 +080079 res.RetMsg = res.GetStrValue("retmsg")
80 return res
81}
Tang Chenge29065c2016-07-14 12:29:42 +080082
83// GetIntValue get int value
Tang Chengf16121a2015-07-27 13:46:14 +080084func (r *ServiceResponse) GetIntValue(name string) int {
Tang Chenge29065c2016-07-14 12:29:42 +080085 return safeGetJSONInt(r.Result[name])
Tang Chengf16121a2015-07-27 13:46:14 +080086}
87
Tang Chenge29065c2016-07-14 12:29:42 +080088// GetStrValue get string value
Tang Chengf16121a2015-07-27 13:46:14 +080089func (r *ServiceResponse) GetStrValue(name string) string {
Tang Chenge29065c2016-07-14 12:29:42 +080090 s, ok := r.Result[name]
91 if ok {
Tang Chengf16121a2015-07-27 13:46:14 +080092 return fmt.Sprintf("%v", s)
Tang Chengf16121a2015-07-27 13:46:14 +080093 }
Tang Chenge29065c2016-07-14 12:29:42 +080094 return ""
Tang Chengf16121a2015-07-27 13:46:14 +080095}
96
Tang Chenge29065c2016-07-14 12:29:42 +080097// GetInterfaceValue get value as interface
zongqiang.zhang134f4182016-06-14 15:23:22 +080098func (r *ServiceResponse) GetInterfaceValue(name string) interface{} {
Tang Chenge29065c2016-07-14 12:29:42 +080099 s, ok := r.Result[name]
100 if ok {
zongqiang.zhang134f4182016-06-14 15:23:22 +0800101 return s
zongqiang.zhang134f4182016-06-14 15:23:22 +0800102 }
Tang Chenge29065c2016-07-14 12:29:42 +0800103 return nil
zongqiang.zhang134f4182016-06-14 15:23:22 +0800104}
Tang Chenge29065c2016-07-14 12:29:42 +0800105
106// GetFloatValue get float value
Tang Chengf16121a2015-07-27 13:46:14 +0800107func (r *ServiceResponse) GetFloatValue(name string) float64 {
108 if s, ok := r.Result[name]; ok {
109 t := fmt.Sprintf("%v", s)
Tang Chenge29065c2016-07-14 12:29:42 +0800110 f, err := strconv.ParseFloat(t, 64)
111 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +0800112 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800113 }
Tang Chenge29065c2016-07-14 12:29:42 +0800114 return f
Tang Chengf16121a2015-07-27 13:46:14 +0800115 }
Tang Chenge29065c2016-07-14 12:29:42 +0800116 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800117}
118
Tang Cheng62fdaa32019-01-11 10:12:41 +0800119// doGet send GET request
120func (w *WebSession) doGet(uri string, params map[string]string,
121 timeout int) (*resty.Response, error) {
Tang Cheng32e32562015-07-08 17:08:03 +0800122
Tang Chenge29065c2016-07-14 12:29:42 +0800123 fullURL := w.BaseURL + uri
Tang Cheng32e32562015-07-08 17:08:03 +0800124
Tang Cheng62fdaa32019-01-11 10:12:41 +0800125 resty.SetTimeout(time.Duration(timeout) * time.Second)
126 resp, err := resty.R().
127 SetQueryParams(params).
128 Get(fullURL)
129 return resp, err
Tang Cheng32e32562015-07-08 17:08:03 +0800130}
131
Tang Chenge29065c2016-07-14 12:29:42 +0800132// GetTimestamp get time stamp format 20160103133455
Tang Cheng32e32562015-07-08 17:08:03 +0800133func (w *WebSession) GetTimestamp() string {
134 t := time.Now()
135 return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(),
136 t.Hour(), t.Minute(), t.Second())
137}
138
Tang Chenge29065c2016-07-14 12:29:42 +0800139// SignWithKey sign with key
Tang Chengf16121a2015-07-27 13:46:14 +0800140func (w *WebSession) SignWithKey(key, message string) string {
141 mac := hmac.New(sha1.New, []byte(key))
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800142 mac.Write([]byte(message))
143 res := mac.Sum(nil)
Tang Cheng26b91152015-07-22 12:26:52 +0800144 return hex.EncodeToString(res)
Tang Cheng32e32562015-07-08 17:08:03 +0800145}
Tang Chenge29065c2016-07-14 12:29:42 +0800146
147// Sign sign data
Tang Chengf16121a2015-07-27 13:46:14 +0800148func (w *WebSession) Sign(message string) string {
Tang Chenge29065c2016-07-14 12:29:42 +0800149 return w.SignWithKey(w.AppSecret, message)
Tang Chengf16121a2015-07-27 13:46:14 +0800150}
Tang Cheng32e32562015-07-08 17:08:03 +0800151
Tang Chenge29065c2016-07-14 12:29:42 +0800152func newTransport(baseurl string, sslVerify bool) *http.Transport {
Tang Chengf8716aa2015-08-19 10:20:40 +0800153 var transport http.Transport
Tang Cheng78513ea2015-10-28 14:32:02 +0800154 if strings.HasPrefix(baseurl, "https://") {
Tang Cheng0b9abf12015-08-20 09:55:32 +0800155 var b bool
Tang Chenge29065c2016-07-14 12:29:42 +0800156 if sslVerify {
Tang Cheng0b9abf12015-08-20 09:55:32 +0800157 b = false
158 } else {
159 b = true
160 }
Tang Cheng78513ea2015-10-28 14:32:02 +0800161 transport = http.Transport{MaxIdleConnsPerHost: 0,
Tang Cheng91665852015-08-29 22:17:20 +0800162 TLSClientConfig: &tls.Config{InsecureSkipVerify: b},
Tang Cheng78513ea2015-10-28 14:32:02 +0800163 TLSHandshakeTimeout: time.Duration(1) * time.Second,
Tang Cheng91665852015-08-29 22:17:20 +0800164 Dial: func(network, addr string) (net.Conn, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800165 defaultTimeout := time.Duration(1) * time.Second
166 return net.DialTimeout(network, addr, defaultTimeout)
Tang Cheng91665852015-08-29 22:17:20 +0800167 }}
Tang Cheng78513ea2015-10-28 14:32:02 +0800168 } else if strings.HasPrefix(baseurl, "http://") {
169 transport = http.Transport{MaxIdleConnsPerHost: 0,
Tang Cheng91665852015-08-29 22:17:20 +0800170 Dial: func(network, addr string) (net.Conn, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800171 defaultTimeout := time.Duration(1) * time.Second
172 return net.DialTimeout(network, addr, defaultTimeout)
Tang Cheng91665852015-08-29 22:17:20 +0800173 }}
Tang Chengf8716aa2015-08-19 10:20:40 +0800174 }
Tang Cheng78513ea2015-10-28 14:32:02 +0800175 log.Debugf("创建新连接")
176 return &transport
Tang Chengf16121a2015-07-27 13:46:14 +0800177}
Tang Chengf8716aa2015-08-19 10:20:40 +0800178
Tang Cheng62fdaa32019-01-11 10:12:41 +0800179// doPost send POST request
180func (w *WebSession) doPost(uri string, param map[string]string) (*resty.Response, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800181 param["app_id"] = w.AppID
182 param["term_id"] = w.TermID
Tang Cheng26b91152015-07-22 12:26:52 +0800183 param["sign_method"] = "HMAC"
Tang Chenge29065c2016-07-14 12:29:42 +0800184 param["session_key"] = w.sessionKey
Tang Cheng32e32562015-07-08 17:08:03 +0800185 ts := w.GetTimestamp()
Tang Cheng26b91152015-07-22 12:26:52 +0800186 param["timestamp"] = ts
Tang Chenge29065c2016-07-14 12:29:42 +0800187 param["sign"] = w.Sign(w.AppID + w.TermID + w.sessionKey + ts)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800188
Tang Chenge29065c2016-07-14 12:29:42 +0800189 fullURL := w.BaseURL + uri
Tang Cheng62fdaa32019-01-11 10:12:41 +0800190
191 r, err := resty.R().
192 SetHeader("Content-Type", "application/json").
193 SetBody(param).
194 Post(fullURL)
195 if err != nil || r.StatusCode() != 200 {
196 log.Errorf("Status=%v, err=%v", r.StatusCode(), err)
Tang Cheng32e32562015-07-08 17:08:03 +0800197 }
198 return r, err
199}
200
Tang Chenge29065c2016-07-14 12:29:42 +0800201// Auth authorization
Tang Cheng32e32562015-07-08 17:08:03 +0800202func (w *WebSession) Auth() error {
qiaoweica037fa2015-07-10 18:31:53 +0800203 token, err := w.getAuthToken()
204 if err != nil {
205 return err
206 }
207 err = w.getAppAccessKey(token)
208 if err != nil {
209 return err
210 }
Tang Cheng32e32562015-07-08 17:08:03 +0800211 return nil
212}
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800213
Tang Chenge29065c2016-07-14 12:29:42 +0800214// NewSession new session object
Tang Cheng0b9abf12015-08-20 09:55:32 +0800215func NewSession(appid, appsecret, termid, baseurl string, timeout int, sslVerify bool) *WebSession {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800216 return &WebSession{
Tang Chenge29065c2016-07-14 12:29:42 +0800217 AppID: appid,
218 AppSecret: appsecret,
219 TermID: termid,
220 BaseURL: baseurl,
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800221 DefaultTimeout: timeout,
Tang Chenge29065c2016-07-14 12:29:42 +0800222 sslVerify: sslVerify,
Tang Cheng62fdaa32019-01-11 10:12:41 +0800223 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800224}
225
Tang Cheng51242e22016-07-14 14:52:07 +0800226// NewSessionWithCA new session ca
227func NewSessionWithCA(appID, appSecret, termID, baseURL string,
228 timeout int, ca []byte) (*WebSession, error) {
229 certs := x509.NewCertPool()
230 if !certs.AppendCertsFromPEM(ca) {
231 return nil, ErrBadCAPEM
232 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800233
234 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"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800253 AccessToken string `json:"access_token"`
254 }
255
Tang Chenge29065c2016-07-14 12:29:42 +0800256 uri := fmt.Sprintf("/authservice/getauth/%v/getaccesstoken", w.AppID)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800257
258 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800259 params["term_id"] = w.TermID
Tang Cheng62fdaa32019-01-11 10:12:41 +0800260 r, err := w.doGet(uri, params, 5)
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()
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800270
Tang Cheng51242e22016-07-14 14:52:07 +0800271 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800272 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800273 if err != nil {
274 log.Errorf("json unmarshal err %v", err)
qiaoweica037fa2015-07-10 18:31:53 +0800275 return "", errors.New("解析失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800276 }
qiaoweica037fa2015-07-10 18:31:53 +0800277 return s.AccessToken, nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800278}
Tang Chenge29065c2016-07-14 12:29:42 +0800279
qiaoweica037fa2015-07-10 18:31:53 +0800280func (w *WebSession) getAppAccessKey(token string) error {
Tang Cheng51242e22016-07-14 14:52:07 +0800281 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800282 AppID string `json:"app_id"`
283 TermID string `json:"term_id"`
qiaoweica037fa2015-07-10 18:31:53 +0800284 SessionKey string `json:"session_key"`
285 CardKey string `json:"card_key"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800286 }
287
Tang Chenge29065c2016-07-14 12:29:42 +0800288 uri := fmt.Sprintf("/authservice/getauth/%v", w.AppID)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800289
290 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800291 params["term_id"] = w.TermID
qiaoweica037fa2015-07-10 18:31:53 +0800292 params["access_token"] = token
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800293 params["timestamp"] = w.GetTimestamp()
294 params["v"] = "1"
qiaoweica037fa2015-07-10 18:31:53 +0800295 params["sign"] = w.Sign(token + params["timestamp"])
296 params["sign_method"] = "HMAC"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800297
Tang Cheng62fdaa32019-01-11 10:12:41 +0800298 r, err := w.doGet(uri, params, 5)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800299 if err != nil {
300 log.Errorf("err = %v\n", err)
qiaoweica037fa2015-07-10 18:31:53 +0800301 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800302 }
Tang Cheng62fdaa32019-01-11 10:12:41 +0800303
304 if r.StatusCode() != 200 {
305 log.Errorf(" errcode = %v\n", r.StatusCode())
306 return fmt.Errorf("code %v", r.StatusCode())
zongqiang.zhang134f4182016-06-14 15:23:22 +0800307 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800308
Tang Cheng62fdaa32019-01-11 10:12:41 +0800309 body := r.Body()
qiaoweica037fa2015-07-10 18:31:53 +0800310
Tang Cheng51242e22016-07-14 14:52:07 +0800311 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800312 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800313 if err != nil {
314 log.Errorf("json unmarshal err %v", err)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800315 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800316 }
Tang Chenge29065c2016-07-14 12:29:42 +0800317 w.sessionKey = s.SessionKey
qiaoweica037fa2015-07-10 18:31:53 +0800318 return nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800319}
Tang Cheng26b91152015-07-22 12:26:52 +0800320
Tang Chenge29065c2016-07-14 12:29:42 +0800321// CallYKTApi call ykt api function
Tang Cheng26b91152015-07-22 12:26:52 +0800322func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800323 callData := request.Serialize()
Tang Cheng26b91152015-07-22 12:26:52 +0800324 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800325 params["funcdata"] = callData
Tang Cheng26b91152015-07-22 12:26:52 +0800326
Tang Cheng62fdaa32019-01-11 10:12:41 +0800327 r, err := w.doPost("/ecardservice/ecardapi", params)
Tang Chengf16121a2015-07-27 13:46:14 +0800328 if err != nil {
Tang Cheng26b91152015-07-22 12:26:52 +0800329 log.Errorf(" err = %v\n", err)
330 return nil, err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800331 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800332
Tang Cheng62fdaa32019-01-11 10:12:41 +0800333 if r.StatusCode() != 200 {
334 return nil, fmt.Errorf("Request StatusCode:%v", r.StatusCode())
Tang Chengf16121a2015-07-27 13:46:14 +0800335 }
336
Tang Cheng62fdaa32019-01-11 10:12:41 +0800337 return NewMessageReader(r.Body()), nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800338}
Tang Chengf16121a2015-07-27 13:46:14 +0800339
Tang Chenge29065c2016-07-14 12:29:42 +0800340// CallService call epay service
Tang Chengf16121a2015-07-27 13:46:14 +0800341func (w *WebSession) CallService(path string, params map[string]interface{},
Tang Chenge29065c2016-07-14 12:29:42 +0800342 signField []string, timeout int) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800343
Tang Chenge29065c2016-07-14 12:29:42 +0800344 return w.CallService2(path, params, timeout, signField...)
Tang Chengf16121a2015-07-27 13:46:14 +0800345}
346
Tang Chengcb9f8782019-01-08 16:00:37 +0800347// SetConnectionTimeout set global connection timeout
348func SetConnectionTimeout(ms int) {
349 connectionTimeout = time.Duration(ms) * time.Millisecond
Tang Cheng62fdaa32019-01-11 10:12:41 +0800350 resty.SetTimeout(connectionTimeout)
Tang Chengcb9f8782019-01-08 16:00:37 +0800351}
352
Tang Chenge29065c2016-07-14 12:29:42 +0800353// CallService2 call epay service
Tang Chengf16121a2015-07-27 13:46:14 +0800354func (w *WebSession) CallService2(path string, params map[string]interface{}, timeout int,
Tang Chenge29065c2016-07-14 12:29:42 +0800355 signField ...string) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800356 err = nil
Tang Chengf16121a2015-07-27 13:46:14 +0800357
Tang Cheng62fdaa32019-01-11 10:12:41 +0800358 formData := make(map[string]string)
Tang Cheng72bc9002019-01-11 11:29:59 +0800359 if params != nil {
360 for k, v := range params {
361 formData[k] = fmt.Sprintf("%v", v)
362 }
Tang Chengf16121a2015-07-27 13:46:14 +0800363 }
Tang Cheng72bc9002019-01-11 11:29:59 +0800364 formData["app_id"] = w.AppID
365 formData["term_id"] = w.TermID
366 ts := w.GetTimestamp()
367 formData["timestamp"] = ts
Tang Chengf16121a2015-07-27 13:46:14 +0800368
Tang Cheng51242e22016-07-14 14:52:07 +0800369 signData := ""
Tang Chenge29065c2016-07-14 12:29:42 +0800370 for _, k := range signField {
Tang Cheng72bc9002019-01-11 11:29:59 +0800371 if v, ok := formData[k]; ok {
372 signData += v
Tang Chengf16121a2015-07-27 13:46:14 +0800373 }
374 }
Tang Cheng51242e22016-07-14 14:52:07 +0800375 signData += ts + w.sessionKey
Tang Cheng51242e22016-07-14 14:52:07 +0800376 log.Debugf("Sign: key[%v] data[%v]\n", w.sessionKey, signData)
Tang Cheng62fdaa32019-01-11 10:12:41 +0800377 formData["sign_method"] = "HMAC"
378 formData["sign"] = w.SignWithKey(w.AppSecret, signData)
Tang Chengf16121a2015-07-27 13:46:14 +0800379
Tang Cheng51242e22016-07-14 14:52:07 +0800380 fullURL := w.BaseURL + path
381 log.Debugf("CallService: %v\n", fullURL)
Tang Cheng62fdaa32019-01-11 10:12:41 +0800382 r, err := resty.R().
383 SetHeader("Accept", "application/json").
384 SetFormData(formData).
385 Post(fullURL)
Tang Chengf16121a2015-07-27 13:46:14 +0800386 if err != nil {
387 log.Errorf("Status=%v, err=%v", r, err)
388 return
389 }
Tang Chengfb7ab582016-08-13 22:25:30 +0800390
Tang Cheng62fdaa32019-01-11 10:12:41 +0800391 if r.StatusCode() != 200 {
392 log.Errorf("Request Error %v\n", r.StatusCode())
393 err = fmt.Errorf("Request Error, StatusCode : %v", r.StatusCode())
Tang Chengf16121a2015-07-27 13:46:14 +0800394 return
395 }
Tang Chengfb7ab582016-08-13 22:25:30 +0800396
Tang Chengf16121a2015-07-27 13:46:14 +0800397 var s interface{}
Tang Chengc3ba6442019-02-28 09:55:31 +0800398 decoder := json.NewDecoder(bytes.NewBuffer(r.Body()))
399 decoder.UseNumber() // 此处能够保证bigint的精度
400 err = decoder.Decode(&s)
401 // err = json.Unmarshal(r.Body(), &s)
Tang Chengf16121a2015-07-27 13:46:14 +0800402 if err != nil {
403 log.Errorf("json unmarshal err %v", err)
404 return
405 }
Tang Chenge29065c2016-07-14 12:29:42 +0800406 response = NewServiceResponseFromJSON(s)
Tang Chengf16121a2015-07-27 13:46:14 +0800407 return
408}