blob: e2819bfff1f08693fabb8eef5169931a3acb754c [file] [log] [blame]
Tang Cheng26b91152015-07-22 12:26:52 +08001package swservice
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +08002
3import (
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +08004 "crypto/hmac"
5 "crypto/sha1"
Tang Chengf8716aa2015-08-19 10:20:40 +08006 "crypto/tls"
Tang Cheng26b91152015-07-22 12:26:52 +08007 "encoding/hex"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +08008 "encoding/json"
qiaoweica037fa2015-07-10 18:31:53 +08009 "errors"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080010 "fmt"
qiaoweica037fa2015-07-10 18:31:53 +080011 "io/ioutil"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080012 "net"
13 "net/http"
14 "net/url"
Tang Chengf16121a2015-07-27 13:46:14 +080015 "strconv"
Tang Chengf8716aa2015-08-19 10:20:40 +080016 "strings"
Tang Cheng78513ea2015-10-28 14:32:02 +080017 "sync"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080018 "time"
Tang Chenga412d202016-01-27 09:24:53 +080019
Tang Cheng51242e22016-07-14 14:52:07 +080020 "crypto/x509"
21
Tang Chenga412d202016-01-27 09:24:53 +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
46 sslVerify bool
Tang Cheng78513ea2015-10-28 14:32:02 +080047 httpConnectionPool sync.Pool
Tang Cheng32e32562015-07-08 17:08:03 +080048}
49
Tang Chenge29065c2016-07-14 12:29:42 +080050func safeGetJSONInt(value interface{}) int {
Tang Chengf16121a2015-07-27 13:46:14 +080051 if value == nil {
52 return 0
53 }
54 s := fmt.Sprintf("%v", value)
Tang Chenge29065c2016-07-14 12:29:42 +080055 i, err := strconv.Atoi(s)
56 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +080057 return 0
Tang Chengf16121a2015-07-27 13:46:14 +080058 }
Tang Chenge29065c2016-07-14 12:29:42 +080059 return i
Tang Chengf16121a2015-07-27 13:46:14 +080060}
61
Tang Chenge29065c2016-07-14 12:29:42 +080062// ServiceResponse service response object
Tang Chengf16121a2015-07-27 13:46:14 +080063type ServiceResponse struct {
Tang Chenge29065c2016-07-14 12:29:42 +080064 // RetCode return code
Tang Chengf16121a2015-07-27 13:46:14 +080065 RetCode int
Tang Chenge29065c2016-07-14 12:29:42 +080066 // RetMsg return message
67 RetMsg string
68 // Result return data
69 Result map[string]interface{}
Tang Chengf16121a2015-07-27 13:46:14 +080070}
71
Tang Chenge29065c2016-07-14 12:29:42 +080072// NewServiceResponseFromJSON parse json response data
73func NewServiceResponseFromJSON(jsonData interface{}) *ServiceResponse {
74 if jsonData == nil {
Tang Chengf16121a2015-07-27 13:46:14 +080075 return nil
76 }
77 res := &ServiceResponse{}
Tang Chenge29065c2016-07-14 12:29:42 +080078 res.Result = jsonData.(map[string]interface{})
79 res.RetCode = safeGetJSONInt(res.Result["retcode"])
Tang Chengf16121a2015-07-27 13:46:14 +080080 res.RetMsg = res.GetStrValue("retmsg")
81 return res
82}
Tang Chenge29065c2016-07-14 12:29:42 +080083
84// GetIntValue get int value
Tang Chengf16121a2015-07-27 13:46:14 +080085func (r *ServiceResponse) GetIntValue(name string) int {
Tang Chenge29065c2016-07-14 12:29:42 +080086 return safeGetJSONInt(r.Result[name])
Tang Chengf16121a2015-07-27 13:46:14 +080087}
88
Tang Chenge29065c2016-07-14 12:29:42 +080089// GetStrValue get string value
Tang Chengf16121a2015-07-27 13:46:14 +080090func (r *ServiceResponse) GetStrValue(name string) string {
Tang Chenge29065c2016-07-14 12:29:42 +080091 s, ok := r.Result[name]
92 if ok {
Tang Chengf16121a2015-07-27 13:46:14 +080093 return fmt.Sprintf("%v", s)
Tang Chengf16121a2015-07-27 13:46:14 +080094 }
Tang Chenge29065c2016-07-14 12:29:42 +080095 return ""
Tang Chengf16121a2015-07-27 13:46:14 +080096}
97
Tang Chenge29065c2016-07-14 12:29:42 +080098// GetInterfaceValue get value as interface
zongqiang.zhang134f4182016-06-14 15:23:22 +080099func (r *ServiceResponse) GetInterfaceValue(name string) interface{} {
Tang Chenge29065c2016-07-14 12:29:42 +0800100 s, ok := r.Result[name]
101 if ok {
zongqiang.zhang134f4182016-06-14 15:23:22 +0800102 return s
zongqiang.zhang134f4182016-06-14 15:23:22 +0800103 }
Tang Chenge29065c2016-07-14 12:29:42 +0800104 return nil
zongqiang.zhang134f4182016-06-14 15:23:22 +0800105}
Tang Chenge29065c2016-07-14 12:29:42 +0800106
107// GetFloatValue get float value
Tang Chengf16121a2015-07-27 13:46:14 +0800108func (r *ServiceResponse) GetFloatValue(name string) float64 {
109 if s, ok := r.Result[name]; ok {
110 t := fmt.Sprintf("%v", s)
Tang Chenge29065c2016-07-14 12:29:42 +0800111 f, err := strconv.ParseFloat(t, 64)
112 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +0800113 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800114 }
Tang Chenge29065c2016-07-14 12:29:42 +0800115 return f
Tang Chengf16121a2015-07-27 13:46:14 +0800116 }
Tang Chenge29065c2016-07-14 12:29:42 +0800117 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800118}
119
Tang Chenge29065c2016-07-14 12:29:42 +0800120// DoGet send GET request
Tang Chengf35646b2017-05-25 10:26:53 +0800121func (w *WebSession) DoGet(uri string, params map[string]string,
122 timeout int) (*goreq.Response, error) {
Tang Cheng32e32562015-07-08 17:08:03 +0800123
Tang Chenge29065c2016-07-14 12:29:42 +0800124 fullURL := w.BaseURL + uri
Tang Cheng32e32562015-07-08 17:08:03 +0800125
126 vl := url.Values{}
Tang Cheng32e32562015-07-08 17:08:03 +0800127
128 if params != nil {
129 for k, v := range params {
130 vl.Add(k, v)
131 }
132 }
Tang Chenge29065c2016-07-14 12:29:42 +0800133 fullURL = fullURL + "?" + vl.Encode()
Tang Chengf35646b2017-05-25 10:26:53 +0800134 return goreq.Request{Uri: fullURL,
Tang Chengcb9f8782019-01-08 16:00:37 +0800135 Method: "GET",
136 Insecure: !w.sslVerify,
137 Timeout: time.Duration(timeout) * time.Second}.Do()
Tang Cheng32e32562015-07-08 17:08:03 +0800138}
139
Tang Chenge29065c2016-07-14 12:29:42 +0800140// GetTimestamp get time stamp format 20160103133455
Tang Cheng32e32562015-07-08 17:08:03 +0800141func (w *WebSession) GetTimestamp() string {
142 t := time.Now()
143 return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(),
144 t.Hour(), t.Minute(), t.Second())
145}
146
Tang Chenge29065c2016-07-14 12:29:42 +0800147// SignWithKey sign with key
Tang Chengf16121a2015-07-27 13:46:14 +0800148func (w *WebSession) SignWithKey(key, message string) string {
149 mac := hmac.New(sha1.New, []byte(key))
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800150 mac.Write([]byte(message))
151 res := mac.Sum(nil)
Tang Cheng26b91152015-07-22 12:26:52 +0800152 return hex.EncodeToString(res)
Tang Cheng32e32562015-07-08 17:08:03 +0800153}
Tang Chenge29065c2016-07-14 12:29:42 +0800154
155// Sign sign data
Tang Chengf16121a2015-07-27 13:46:14 +0800156func (w *WebSession) Sign(message string) string {
Tang Chenge29065c2016-07-14 12:29:42 +0800157 return w.SignWithKey(w.AppSecret, message)
Tang Chengf16121a2015-07-27 13:46:14 +0800158}
Tang Cheng32e32562015-07-08 17:08:03 +0800159
Tang Chenge29065c2016-07-14 12:29:42 +0800160func newTransport(baseurl string, sslVerify bool) *http.Transport {
Tang Chengf8716aa2015-08-19 10:20:40 +0800161 var transport http.Transport
Tang Cheng78513ea2015-10-28 14:32:02 +0800162 if strings.HasPrefix(baseurl, "https://") {
Tang Cheng0b9abf12015-08-20 09:55:32 +0800163 var b bool
Tang Chenge29065c2016-07-14 12:29:42 +0800164 if sslVerify {
Tang Cheng0b9abf12015-08-20 09:55:32 +0800165 b = false
166 } else {
167 b = true
168 }
Tang Cheng78513ea2015-10-28 14:32:02 +0800169 transport = http.Transport{MaxIdleConnsPerHost: 0,
Tang Cheng91665852015-08-29 22:17:20 +0800170 TLSClientConfig: &tls.Config{InsecureSkipVerify: b},
Tang Cheng78513ea2015-10-28 14:32:02 +0800171 TLSHandshakeTimeout: time.Duration(1) * time.Second,
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 Cheng78513ea2015-10-28 14:32:02 +0800176 } else if strings.HasPrefix(baseurl, "http://") {
177 transport = http.Transport{MaxIdleConnsPerHost: 0,
Tang Cheng91665852015-08-29 22:17:20 +0800178 Dial: func(network, addr string) (net.Conn, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800179 defaultTimeout := time.Duration(1) * time.Second
180 return net.DialTimeout(network, addr, defaultTimeout)
Tang Cheng91665852015-08-29 22:17:20 +0800181 }}
Tang Chengf8716aa2015-08-19 10:20:40 +0800182 }
Tang Cheng78513ea2015-10-28 14:32:02 +0800183 log.Debugf("创建新连接")
184 return &transport
Tang Chengf16121a2015-07-27 13:46:14 +0800185}
Tang Chengf8716aa2015-08-19 10:20:40 +0800186
Tang Chenge29065c2016-07-14 12:29:42 +0800187// DoPost send POST request
Tang Chenga412d202016-01-27 09:24:53 +0800188func (w *WebSession) DoPost(uri string, param map[string]string) (*goreq.Response, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800189 param["app_id"] = w.AppID
190 param["term_id"] = w.TermID
Tang Cheng26b91152015-07-22 12:26:52 +0800191 param["sign_method"] = "HMAC"
Tang Chenge29065c2016-07-14 12:29:42 +0800192 param["session_key"] = w.sessionKey
Tang Cheng32e32562015-07-08 17:08:03 +0800193 ts := w.GetTimestamp()
Tang Cheng26b91152015-07-22 12:26:52 +0800194 param["timestamp"] = ts
Tang Chenge29065c2016-07-14 12:29:42 +0800195 param["sign"] = w.Sign(w.AppID + w.TermID + w.sessionKey + ts)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800196
Tang Chenge29065c2016-07-14 12:29:42 +0800197 fullURL := w.BaseURL + uri
Tang Cheng26b91152015-07-22 12:26:52 +0800198 data, err := json.Marshal(param)
199 if err != nil {
200 return nil, err
201 }
Tang Chenga412d202016-01-27 09:24:53 +0800202 var r *goreq.Response
203 r, err = goreq.Request{
Tang Chenge29065c2016-07-14 12:29:42 +0800204 Uri: fullURL,
Tang Chenga412d202016-01-27 09:24:53 +0800205 Method: "POST",
206 ContentType: "application/json",
207 Body: data,
Tang Chengcb9f8782019-01-08 16:00:37 +0800208 Insecure: !w.sslVerify,
Tang Chenga412d202016-01-27 09:24:53 +0800209 Timeout: time.Duration(3) * time.Second}.Do()
Tang Cheng32e32562015-07-08 17:08:03 +0800210 if err != nil || r.StatusCode != 200 {
211 log.Errorf("Status=%v, err=%v", r, err)
212 }
213 return r, err
214}
215
Tang Chenge29065c2016-07-14 12:29:42 +0800216// Auth authorization
Tang Cheng32e32562015-07-08 17:08:03 +0800217func (w *WebSession) Auth() error {
qiaoweica037fa2015-07-10 18:31:53 +0800218 token, err := w.getAuthToken()
219 if err != nil {
220 return err
221 }
222 err = w.getAppAccessKey(token)
223 if err != nil {
224 return err
225 }
Tang Cheng32e32562015-07-08 17:08:03 +0800226 return nil
227}
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800228
Tang Chenge29065c2016-07-14 12:29:42 +0800229// NewSession new session object
Tang Cheng0b9abf12015-08-20 09:55:32 +0800230func NewSession(appid, appsecret, termid, baseurl string, timeout int, sslVerify bool) *WebSession {
Tang Cheng84839422016-07-14 14:57:19 +0800231 if transport, ok := goreq.DefaultTransport.(*http.Transport); ok {
232 transport.TLSClientConfig = nil
233 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800234 return &WebSession{
Tang Chenge29065c2016-07-14 12:29:42 +0800235 AppID: appid,
236 AppSecret: appsecret,
237 TermID: termid,
238 BaseURL: baseurl,
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800239 DefaultTimeout: timeout,
Tang Chenge29065c2016-07-14 12:29:42 +0800240 sslVerify: sslVerify,
Tang Cheng78513ea2015-10-28 14:32:02 +0800241 httpConnectionPool: sync.Pool{New: func() interface{} {
242 return newTransport(baseurl, sslVerify)
243 }}}
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800244}
245
Tang Cheng51242e22016-07-14 14:52:07 +0800246// NewSessionWithCA new session ca
247func NewSessionWithCA(appID, appSecret, termID, baseURL string,
248 timeout int, ca []byte) (*WebSession, error) {
249 certs := x509.NewCertPool()
250 if !certs.AppendCertsFromPEM(ca) {
251 return nil, ErrBadCAPEM
252 }
253 if transport, ok := goreq.DefaultTransport.(*http.Transport); ok {
254 transport.TLSClientConfig = &tls.Config{RootCAs: certs}
255 }
256
Tang Cheng84839422016-07-14 14:57:19 +0800257 return &WebSession{
258 AppID: appID,
259 AppSecret: appSecret,
260 TermID: termID,
261 BaseURL: baseURL,
262 DefaultTimeout: timeout,
263 sslVerify: true,
264 }, nil
Tang Cheng51242e22016-07-14 14:52:07 +0800265}
266
qiaoweica037fa2015-07-10 18:31:53 +0800267func (w *WebSession) getAuthToken() (string, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800268 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800269 AppID string `json:"app_id"`
270 TermID string `json:"term_id"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800271 AccessToken string `json:"access_token"`
272 }
273
Tang Chenge29065c2016-07-14 12:29:42 +0800274 uri := fmt.Sprintf("/authservice/getauth/%v/getaccesstoken", w.AppID)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800275
276 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800277 params["term_id"] = w.TermID
Tang Chengf35646b2017-05-25 10:26:53 +0800278 r, err := w.DoGet(uri, params, 5)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800279
Tang Chengf8716aa2015-08-19 10:20:40 +0800280 if err != nil {
Tang Chengf8716aa2015-08-19 10:20:40 +0800281 return "", err
282 }
283 if r.StatusCode != 200 {
qiaoweica037fa2015-07-10 18:31:53 +0800284 return "", errors.New("请求失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800285 }
286
qiaoweica037fa2015-07-10 18:31:53 +0800287 body, err := ioutil.ReadAll(r.Body)
Tang Cheng91665852015-08-29 22:17:20 +0800288 defer r.Body.Close()
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800289
Tang Cheng51242e22016-07-14 14:52:07 +0800290 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800291 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800292 if err != nil {
293 log.Errorf("json unmarshal err %v", err)
qiaoweica037fa2015-07-10 18:31:53 +0800294 return "", errors.New("解析失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800295 }
qiaoweica037fa2015-07-10 18:31:53 +0800296 return s.AccessToken, nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800297}
Tang Chenge29065c2016-07-14 12:29:42 +0800298
qiaoweica037fa2015-07-10 18:31:53 +0800299func (w *WebSession) getAppAccessKey(token string) error {
Tang Cheng51242e22016-07-14 14:52:07 +0800300 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800301 AppID string `json:"app_id"`
302 TermID string `json:"term_id"`
qiaoweica037fa2015-07-10 18:31:53 +0800303 SessionKey string `json:"session_key"`
304 CardKey string `json:"card_key"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800305 }
306
Tang Chenge29065c2016-07-14 12:29:42 +0800307 uri := fmt.Sprintf("/authservice/getauth/%v", w.AppID)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800308
309 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800310 params["term_id"] = w.TermID
qiaoweica037fa2015-07-10 18:31:53 +0800311 params["access_token"] = token
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800312 params["timestamp"] = w.GetTimestamp()
313 params["v"] = "1"
qiaoweica037fa2015-07-10 18:31:53 +0800314 params["sign"] = w.Sign(token + params["timestamp"])
315 params["sign_method"] = "HMAC"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800316
Tang Chengf35646b2017-05-25 10:26:53 +0800317 r, err := w.DoGet(uri, params, 5)
Tang Cheng55814742015-09-08 17:24:05 +0800318 if r != nil {
319 defer r.Body.Close()
320 }
zongqiang.zhang134f4182016-06-14 15:23:22 +0800321 if err != nil {
322 log.Errorf("err = %v\n", err)
qiaoweica037fa2015-07-10 18:31:53 +0800323 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800324 }
zongqiang.zhang134f4182016-06-14 15:23:22 +0800325 if r.StatusCode != 200 {
326 log.Errorf(" errcode = %v\n", r.StatusCode)
Tang Cheng51242e22016-07-14 14:52:07 +0800327 return fmt.Errorf("code %v", r.StatusCode)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800328 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800329
qiaoweica037fa2015-07-10 18:31:53 +0800330 body, err := ioutil.ReadAll(r.Body)
qiaoweica037fa2015-07-10 18:31:53 +0800331
Tang Cheng51242e22016-07-14 14:52:07 +0800332 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800333 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800334 if err != nil {
335 log.Errorf("json unmarshal err %v", err)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800336 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800337 }
Tang Chenge29065c2016-07-14 12:29:42 +0800338 w.sessionKey = s.SessionKey
qiaoweica037fa2015-07-10 18:31:53 +0800339 return nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800340}
Tang Cheng26b91152015-07-22 12:26:52 +0800341
Tang Chenge29065c2016-07-14 12:29:42 +0800342// CallYKTApi call ykt api function
Tang Cheng26b91152015-07-22 12:26:52 +0800343func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800344 callData := request.Serialize()
Tang Cheng26b91152015-07-22 12:26:52 +0800345 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800346 params["funcdata"] = callData
Tang Cheng26b91152015-07-22 12:26:52 +0800347 r, err := w.DoPost("/ecardservice/ecardapi", params)
348
Tang Cheng55814742015-09-08 17:24:05 +0800349 if r != nil {
350 defer r.Body.Close()
351 }
Tang Chengf16121a2015-07-27 13:46:14 +0800352 if err != nil {
Tang Cheng26b91152015-07-22 12:26:52 +0800353 log.Errorf(" err = %v\n", err)
354 return nil, err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800355 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800356
Tang Chengf16121a2015-07-27 13:46:14 +0800357 if r.StatusCode != 200 {
Tang Cheng51242e22016-07-14 14:52:07 +0800358 return nil, fmt.Errorf("Request StatusCode:%v", r.StatusCode)
Tang Chengf16121a2015-07-27 13:46:14 +0800359 }
360
Tang Cheng26b91152015-07-22 12:26:52 +0800361 body, err := ioutil.ReadAll(r.Body)
Tang Cheng26b91152015-07-22 12:26:52 +0800362 return NewMessageReader(body), nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800363}
Tang Chengf16121a2015-07-27 13:46:14 +0800364
Tang Chenge29065c2016-07-14 12:29:42 +0800365// CallService call epay service
Tang Chengf16121a2015-07-27 13:46:14 +0800366func (w *WebSession) CallService(path string, params map[string]interface{},
Tang Chenge29065c2016-07-14 12:29:42 +0800367 signField []string, timeout int) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800368
Tang Chenge29065c2016-07-14 12:29:42 +0800369 return w.CallService2(path, params, timeout, signField...)
Tang Chengf16121a2015-07-27 13:46:14 +0800370}
371
Tang Chengcb9f8782019-01-08 16:00:37 +0800372// SetConnectionTimeout set global connection timeout
373func SetConnectionTimeout(ms int) {
374 connectionTimeout = time.Duration(ms) * time.Millisecond
Tang Cheng3880cf42019-01-11 08:59:34 +0800375 goreq.SetConnectTimeout(connectionTimeout)
Tang Chengcb9f8782019-01-08 16:00:37 +0800376}
377
Tang Chenge29065c2016-07-14 12:29:42 +0800378// CallService2 call epay service
Tang Chengf16121a2015-07-27 13:46:14 +0800379func (w *WebSession) CallService2(path string, params map[string]interface{}, timeout int,
Tang Chenge29065c2016-07-14 12:29:42 +0800380 signField ...string) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800381 err = nil
Tang Chenge29065c2016-07-14 12:29:42 +0800382 params["app_id"] = w.AppID
383 params["term_id"] = w.TermID
Tang Chengf16121a2015-07-27 13:46:14 +0800384 ts := w.GetTimestamp()
385 params["timestamp"] = ts
386
387 vl := &url.Values{}
388 for k, v := range params {
389 vl.Set(k, fmt.Sprintf("%v", v))
390 }
391
Tang Cheng51242e22016-07-14 14:52:07 +0800392 signData := ""
Tang Chenge29065c2016-07-14 12:29:42 +0800393 for _, k := range signField {
Tang Chengf16121a2015-07-27 13:46:14 +0800394 if v, ok := params[k]; ok {
Tang Cheng51242e22016-07-14 14:52:07 +0800395 signData += fmt.Sprintf("%v", v)
Tang Chengf16121a2015-07-27 13:46:14 +0800396 }
397 }
Tang Cheng51242e22016-07-14 14:52:07 +0800398 signData += ts + w.sessionKey
Tang Chengf16121a2015-07-27 13:46:14 +0800399 vl.Set("sign_method", "HMAC")
Tang Cheng51242e22016-07-14 14:52:07 +0800400 log.Debugf("Sign: key[%v] data[%v]\n", w.sessionKey, signData)
401 vl.Set("sign", w.SignWithKey(w.AppSecret, signData))
Tang Chengf16121a2015-07-27 13:46:14 +0800402
Tang Cheng51242e22016-07-14 14:52:07 +0800403 fullURL := w.BaseURL + path
404 log.Debugf("CallService: %v\n", fullURL)
Tang Chengcb9f8782019-01-08 16:00:37 +0800405 goreq.SetConnectTimeout(connectionTimeout)
Tang Chenga412d202016-01-27 09:24:53 +0800406 var r *goreq.Response
407 r, err = goreq.Request{
Tang Cheng51242e22016-07-14 14:52:07 +0800408 Uri: fullURL,
Tang Chenga412d202016-01-27 09:24:53 +0800409 Accept: "application/json",
410 ContentType: "application/x-www-form-urlencoded",
411 Method: "POST",
412 Timeout: time.Duration(timeout) * time.Second,
413 Body: vl.Encode()}.Do()
Tang Chengf16121a2015-07-27 13:46:14 +0800414 if err != nil {
415 log.Errorf("Status=%v, err=%v", r, err)
416 return
417 }
Tang Chengfb7ab582016-08-13 22:25:30 +0800418 if r != nil && r.Body != nil {
419 defer r.Body.Close()
420 }
421
Tang Chengf16121a2015-07-27 13:46:14 +0800422 if r.StatusCode != 200 {
423 log.Errorf("Request Error %v\n", r.StatusCode)
Tang Cheng51242e22016-07-14 14:52:07 +0800424 err = fmt.Errorf("Request Error, StatusCode : %v", r.StatusCode)
Tang Chengf16121a2015-07-27 13:46:14 +0800425 return
426 }
Tang Chengfb7ab582016-08-13 22:25:30 +0800427
Tang Chengf16121a2015-07-27 13:46:14 +0800428 body, err := ioutil.ReadAll(r.Body)
Tang Chengf16121a2015-07-27 13:46:14 +0800429 var s interface{}
430 err = json.Unmarshal(body, &s)
431 if err != nil {
432 log.Errorf("json unmarshal err %v", err)
433 return
434 }
Tang Chenge29065c2016-07-14 12:29:42 +0800435 response = NewServiceResponseFromJSON(s)
Tang Chengf16121a2015-07-27 13:46:14 +0800436 return
437}