blob: c6e1be961e7cf30f2d72ced227252ebe3dd1cc7b [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 Chenge29065c2016-07-14 12:29:42 +080031// WebSession web session object
Tang Cheng32e32562015-07-08 17:08:03 +080032type WebSession struct {
Tang Chenge29065c2016-07-14 12:29:42 +080033 // AppId app id
34 AppID string
35 // TermId term id
36 TermID string
37 // Appsecret secret
38 AppSecret string
39 // BaseUrl base url
40 BaseURL string
41 // DefaultTimeout default time
Tang Cheng78513ea2015-10-28 14:32:02 +080042 DefaultTimeout int
Tang Chenge29065c2016-07-14 12:29:42 +080043 sessionKey string
44 sslVerify bool
Tang Cheng78513ea2015-10-28 14:32:02 +080045 httpConnectionPool sync.Pool
Tang Cheng32e32562015-07-08 17:08:03 +080046}
47
Tang Chenge29065c2016-07-14 12:29:42 +080048func safeGetJSONInt(value interface{}) int {
Tang Chengf16121a2015-07-27 13:46:14 +080049 if value == nil {
50 return 0
51 }
52 s := fmt.Sprintf("%v", value)
Tang Chenge29065c2016-07-14 12:29:42 +080053 i, err := strconv.Atoi(s)
54 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +080055 return 0
Tang Chengf16121a2015-07-27 13:46:14 +080056 }
Tang Chenge29065c2016-07-14 12:29:42 +080057 return i
Tang Chengf16121a2015-07-27 13:46:14 +080058}
59
Tang Chenge29065c2016-07-14 12:29:42 +080060// ServiceResponse service response object
Tang Chengf16121a2015-07-27 13:46:14 +080061type ServiceResponse struct {
Tang Chenge29065c2016-07-14 12:29:42 +080062 // RetCode return code
Tang Chengf16121a2015-07-27 13:46:14 +080063 RetCode int
Tang Chenge29065c2016-07-14 12:29:42 +080064 // RetMsg return message
65 RetMsg string
66 // Result return data
67 Result map[string]interface{}
Tang Chengf16121a2015-07-27 13:46:14 +080068}
69
Tang Chenge29065c2016-07-14 12:29:42 +080070// NewServiceResponseFromJSON parse json response data
71func NewServiceResponseFromJSON(jsonData interface{}) *ServiceResponse {
72 if jsonData == nil {
Tang Chengf16121a2015-07-27 13:46:14 +080073 return nil
74 }
75 res := &ServiceResponse{}
Tang Chenge29065c2016-07-14 12:29:42 +080076 res.Result = jsonData.(map[string]interface{})
77 res.RetCode = safeGetJSONInt(res.Result["retcode"])
Tang Chengf16121a2015-07-27 13:46:14 +080078 res.RetMsg = res.GetStrValue("retmsg")
79 return res
80}
Tang Chenge29065c2016-07-14 12:29:42 +080081
82// GetIntValue get int value
Tang Chengf16121a2015-07-27 13:46:14 +080083func (r *ServiceResponse) GetIntValue(name string) int {
Tang Chenge29065c2016-07-14 12:29:42 +080084 return safeGetJSONInt(r.Result[name])
Tang Chengf16121a2015-07-27 13:46:14 +080085}
86
Tang Chenge29065c2016-07-14 12:29:42 +080087// GetStrValue get string value
Tang Chengf16121a2015-07-27 13:46:14 +080088func (r *ServiceResponse) GetStrValue(name string) string {
Tang Chenge29065c2016-07-14 12:29:42 +080089 s, ok := r.Result[name]
90 if ok {
Tang Chengf16121a2015-07-27 13:46:14 +080091 return fmt.Sprintf("%v", s)
Tang Chengf16121a2015-07-27 13:46:14 +080092 }
Tang Chenge29065c2016-07-14 12:29:42 +080093 return ""
Tang Chengf16121a2015-07-27 13:46:14 +080094}
95
Tang Chenge29065c2016-07-14 12:29:42 +080096// GetInterfaceValue get value as interface
zongqiang.zhang134f4182016-06-14 15:23:22 +080097func (r *ServiceResponse) GetInterfaceValue(name string) interface{} {
Tang Chenge29065c2016-07-14 12:29:42 +080098 s, ok := r.Result[name]
99 if ok {
zongqiang.zhang134f4182016-06-14 15:23:22 +0800100 return s
zongqiang.zhang134f4182016-06-14 15:23:22 +0800101 }
Tang Chenge29065c2016-07-14 12:29:42 +0800102 return nil
zongqiang.zhang134f4182016-06-14 15:23:22 +0800103}
Tang Chenge29065c2016-07-14 12:29:42 +0800104
105// GetFloatValue get float value
Tang Chengf16121a2015-07-27 13:46:14 +0800106func (r *ServiceResponse) GetFloatValue(name string) float64 {
107 if s, ok := r.Result[name]; ok {
108 t := fmt.Sprintf("%v", s)
Tang Chenge29065c2016-07-14 12:29:42 +0800109 f, err := strconv.ParseFloat(t, 64)
110 if err != nil {
Tang Chengf16121a2015-07-27 13:46:14 +0800111 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800112 }
Tang Chenge29065c2016-07-14 12:29:42 +0800113 return f
Tang Chengf16121a2015-07-27 13:46:14 +0800114 }
Tang Chenge29065c2016-07-14 12:29:42 +0800115 return 0.0
Tang Chengf16121a2015-07-27 13:46:14 +0800116}
117
Tang Chenge29065c2016-07-14 12:29:42 +0800118// DoGet send GET request
Tang Cheng51242e22016-07-14 14:52:07 +0800119func (w *WebSession) DoGet(uri string, params map[string]string) (*goreq.Response, error) {
Tang Cheng32e32562015-07-08 17:08:03 +0800120
Tang Chenge29065c2016-07-14 12:29:42 +0800121 fullURL := w.BaseURL + uri
Tang Cheng32e32562015-07-08 17:08:03 +0800122
123 vl := url.Values{}
Tang Cheng32e32562015-07-08 17:08:03 +0800124
125 if params != nil {
126 for k, v := range params {
127 vl.Add(k, v)
128 }
129 }
Tang Chenge29065c2016-07-14 12:29:42 +0800130 fullURL = fullURL + "?" + vl.Encode()
Tang Cheng51242e22016-07-14 14:52:07 +0800131 return goreq.Request{Uri: fullURL, Method: "GET"}.Do()
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 {
143 mac := hmac.New(sha1.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 Chenge29065c2016-07-14 12:29:42 +0800181// DoPost send POST request
Tang Chenga412d202016-01-27 09:24:53 +0800182func (w *WebSession) DoPost(uri string, param map[string]string) (*goreq.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 Cheng26b91152015-07-22 12:26:52 +0800192 data, err := json.Marshal(param)
193 if err != nil {
194 return nil, err
195 }
Tang Chenga412d202016-01-27 09:24:53 +0800196 var r *goreq.Response
197 r, err = goreq.Request{
Tang Chenge29065c2016-07-14 12:29:42 +0800198 Uri: fullURL,
Tang Chenga412d202016-01-27 09:24:53 +0800199 Method: "POST",
200 ContentType: "application/json",
201 Body: data,
202 Timeout: time.Duration(3) * time.Second}.Do()
Tang Cheng32e32562015-07-08 17:08:03 +0800203 if err != nil || r.StatusCode != 200 {
204 log.Errorf("Status=%v, err=%v", r, err)
205 }
206 return r, err
207}
208
Tang Chenge29065c2016-07-14 12:29:42 +0800209// Auth authorization
Tang Cheng32e32562015-07-08 17:08:03 +0800210func (w *WebSession) Auth() error {
qiaoweica037fa2015-07-10 18:31:53 +0800211 token, err := w.getAuthToken()
212 if err != nil {
213 return err
214 }
215 err = w.getAppAccessKey(token)
216 if err != nil {
217 return err
218 }
Tang Cheng32e32562015-07-08 17:08:03 +0800219 return nil
220}
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800221
Tang Chenge29065c2016-07-14 12:29:42 +0800222// NewSession new session object
Tang Cheng0b9abf12015-08-20 09:55:32 +0800223func NewSession(appid, appsecret, termid, baseurl string, timeout int, sslVerify bool) *WebSession {
Tang Cheng84839422016-07-14 14:57:19 +0800224 if transport, ok := goreq.DefaultTransport.(*http.Transport); ok {
225 transport.TLSClientConfig = nil
226 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800227 return &WebSession{
Tang Chenge29065c2016-07-14 12:29:42 +0800228 AppID: appid,
229 AppSecret: appsecret,
230 TermID: termid,
231 BaseURL: baseurl,
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800232 DefaultTimeout: timeout,
Tang Chenge29065c2016-07-14 12:29:42 +0800233 sslVerify: sslVerify,
Tang Cheng78513ea2015-10-28 14:32:02 +0800234 httpConnectionPool: sync.Pool{New: func() interface{} {
235 return newTransport(baseurl, sslVerify)
236 }}}
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 }
246 if transport, ok := goreq.DefaultTransport.(*http.Transport); ok {
247 transport.TLSClientConfig = &tls.Config{RootCAs: certs}
248 }
249
Tang Cheng84839422016-07-14 14:57:19 +0800250 return &WebSession{
251 AppID: appID,
252 AppSecret: appSecret,
253 TermID: termID,
254 BaseURL: baseURL,
255 DefaultTimeout: timeout,
256 sslVerify: true,
257 }, nil
Tang Cheng51242e22016-07-14 14:52:07 +0800258}
259
qiaoweica037fa2015-07-10 18:31:53 +0800260func (w *WebSession) getAuthToken() (string, error) {
Tang Cheng51242e22016-07-14 14:52:07 +0800261 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800262 AppID string `json:"app_id"`
263 TermID string `json:"term_id"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800264 AccessToken string `json:"access_token"`
265 }
266
Tang Chenge29065c2016-07-14 12:29:42 +0800267 uri := fmt.Sprintf("/authservice/getauth/%v/getaccesstoken", w.AppID)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800268
269 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800270 params["term_id"] = w.TermID
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800271 r, err := w.DoGet(uri, params)
272
Tang Chengf8716aa2015-08-19 10:20:40 +0800273 if err != nil {
Tang Chengf8716aa2015-08-19 10:20:40 +0800274 return "", err
275 }
276 if r.StatusCode != 200 {
qiaoweica037fa2015-07-10 18:31:53 +0800277 return "", errors.New("请求失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800278 }
279
qiaoweica037fa2015-07-10 18:31:53 +0800280 body, err := ioutil.ReadAll(r.Body)
Tang Cheng91665852015-08-29 22:17:20 +0800281 defer r.Body.Close()
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800282
Tang Cheng51242e22016-07-14 14:52:07 +0800283 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800284 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800285 if err != nil {
286 log.Errorf("json unmarshal err %v", err)
qiaoweica037fa2015-07-10 18:31:53 +0800287 return "", errors.New("解析失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800288 }
qiaoweica037fa2015-07-10 18:31:53 +0800289 return s.AccessToken, nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800290}
Tang Chenge29065c2016-07-14 12:29:42 +0800291
qiaoweica037fa2015-07-10 18:31:53 +0800292func (w *WebSession) getAppAccessKey(token string) error {
Tang Cheng51242e22016-07-14 14:52:07 +0800293 type FormJSON struct {
Tang Chenge29065c2016-07-14 12:29:42 +0800294 AppID string `json:"app_id"`
295 TermID string `json:"term_id"`
qiaoweica037fa2015-07-10 18:31:53 +0800296 SessionKey string `json:"session_key"`
297 CardKey string `json:"card_key"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800298 }
299
Tang Chenge29065c2016-07-14 12:29:42 +0800300 uri := fmt.Sprintf("/authservice/getauth/%v", w.AppID)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800301
302 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800303 params["term_id"] = w.TermID
qiaoweica037fa2015-07-10 18:31:53 +0800304 params["access_token"] = token
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800305 params["timestamp"] = w.GetTimestamp()
306 params["v"] = "1"
qiaoweica037fa2015-07-10 18:31:53 +0800307 params["sign"] = w.Sign(token + params["timestamp"])
308 params["sign_method"] = "HMAC"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800309
qiaoweica037fa2015-07-10 18:31:53 +0800310 r, err := w.DoGet(uri, params)
Tang Cheng55814742015-09-08 17:24:05 +0800311 if r != nil {
312 defer r.Body.Close()
313 }
zongqiang.zhang134f4182016-06-14 15:23:22 +0800314 if err != nil {
315 log.Errorf("err = %v\n", err)
qiaoweica037fa2015-07-10 18:31:53 +0800316 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800317 }
zongqiang.zhang134f4182016-06-14 15:23:22 +0800318 if r.StatusCode != 200 {
319 log.Errorf(" errcode = %v\n", r.StatusCode)
Tang Cheng51242e22016-07-14 14:52:07 +0800320 return fmt.Errorf("code %v", r.StatusCode)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800321 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800322
qiaoweica037fa2015-07-10 18:31:53 +0800323 body, err := ioutil.ReadAll(r.Body)
qiaoweica037fa2015-07-10 18:31:53 +0800324
Tang Cheng51242e22016-07-14 14:52:07 +0800325 s := &FormJSON{}
qiaoweica037fa2015-07-10 18:31:53 +0800326 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800327 if err != nil {
328 log.Errorf("json unmarshal err %v", err)
zongqiang.zhang134f4182016-06-14 15:23:22 +0800329 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800330 }
Tang Chenge29065c2016-07-14 12:29:42 +0800331 w.sessionKey = s.SessionKey
qiaoweica037fa2015-07-10 18:31:53 +0800332 return nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800333}
Tang Cheng26b91152015-07-22 12:26:52 +0800334
Tang Chenge29065c2016-07-14 12:29:42 +0800335// CallYKTApi call ykt api function
Tang Cheng26b91152015-07-22 12:26:52 +0800336func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
Tang Chenge29065c2016-07-14 12:29:42 +0800337 callData := request.Serialize()
Tang Cheng26b91152015-07-22 12:26:52 +0800338 params := make(map[string]string)
Tang Chenge29065c2016-07-14 12:29:42 +0800339 params["funcdata"] = callData
Tang Cheng26b91152015-07-22 12:26:52 +0800340 r, err := w.DoPost("/ecardservice/ecardapi", params)
341
Tang Cheng55814742015-09-08 17:24:05 +0800342 if r != nil {
343 defer r.Body.Close()
344 }
Tang Chengf16121a2015-07-27 13:46:14 +0800345 if err != nil {
Tang Cheng26b91152015-07-22 12:26:52 +0800346 log.Errorf(" err = %v\n", err)
347 return nil, err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800348 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800349
Tang Chengf16121a2015-07-27 13:46:14 +0800350 if r.StatusCode != 200 {
Tang Cheng51242e22016-07-14 14:52:07 +0800351 return nil, fmt.Errorf("Request StatusCode:%v", r.StatusCode)
Tang Chengf16121a2015-07-27 13:46:14 +0800352 }
353
Tang Cheng26b91152015-07-22 12:26:52 +0800354 body, err := ioutil.ReadAll(r.Body)
Tang Cheng26b91152015-07-22 12:26:52 +0800355 return NewMessageReader(body), nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800356}
Tang Chengf16121a2015-07-27 13:46:14 +0800357
Tang Chenge29065c2016-07-14 12:29:42 +0800358// CallService call epay service
Tang Chengf16121a2015-07-27 13:46:14 +0800359func (w *WebSession) CallService(path string, params map[string]interface{},
Tang Chenge29065c2016-07-14 12:29:42 +0800360 signField []string, timeout int) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800361
Tang Chenge29065c2016-07-14 12:29:42 +0800362 return w.CallService2(path, params, timeout, signField...)
Tang Chengf16121a2015-07-27 13:46:14 +0800363}
364
Tang Chenge29065c2016-07-14 12:29:42 +0800365// CallService2 call epay service
Tang Chengf16121a2015-07-27 13:46:14 +0800366func (w *WebSession) CallService2(path string, params map[string]interface{}, timeout int,
Tang Chenge29065c2016-07-14 12:29:42 +0800367 signField ...string) (response *ServiceResponse, err error) {
Tang Chengf16121a2015-07-27 13:46:14 +0800368 err = nil
Tang Chenge29065c2016-07-14 12:29:42 +0800369 params["app_id"] = w.AppID
370 params["term_id"] = w.TermID
Tang Chengf16121a2015-07-27 13:46:14 +0800371 ts := w.GetTimestamp()
372 params["timestamp"] = ts
373
374 vl := &url.Values{}
375 for k, v := range params {
376 vl.Set(k, fmt.Sprintf("%v", v))
377 }
378
Tang Cheng51242e22016-07-14 14:52:07 +0800379 signData := ""
Tang Chenge29065c2016-07-14 12:29:42 +0800380 for _, k := range signField {
Tang Chengf16121a2015-07-27 13:46:14 +0800381 if v, ok := params[k]; ok {
Tang Cheng51242e22016-07-14 14:52:07 +0800382 signData += fmt.Sprintf("%v", v)
Tang Chengf16121a2015-07-27 13:46:14 +0800383 }
384 }
Tang Cheng51242e22016-07-14 14:52:07 +0800385 signData += ts + w.sessionKey
Tang Chengf16121a2015-07-27 13:46:14 +0800386 vl.Set("sign_method", "HMAC")
Tang Cheng51242e22016-07-14 14:52:07 +0800387 log.Debugf("Sign: key[%v] data[%v]\n", w.sessionKey, signData)
388 vl.Set("sign", w.SignWithKey(w.AppSecret, signData))
Tang Chengf16121a2015-07-27 13:46:14 +0800389
Tang Cheng51242e22016-07-14 14:52:07 +0800390 fullURL := w.BaseURL + path
391 log.Debugf("CallService: %v\n", fullURL)
Tang Chenga412d202016-01-27 09:24:53 +0800392 var r *goreq.Response
393 r, err = goreq.Request{
Tang Cheng51242e22016-07-14 14:52:07 +0800394 Uri: fullURL,
Tang Chenga412d202016-01-27 09:24:53 +0800395 Accept: "application/json",
396 ContentType: "application/x-www-form-urlencoded",
397 Method: "POST",
398 Timeout: time.Duration(timeout) * time.Second,
399 Body: vl.Encode()}.Do()
Tang Chengf16121a2015-07-27 13:46:14 +0800400 if err != nil {
401 log.Errorf("Status=%v, err=%v", r, err)
402 return
403 }
404 if r.StatusCode != 200 {
405 log.Errorf("Request Error %v\n", r.StatusCode)
Tang Cheng51242e22016-07-14 14:52:07 +0800406 err = fmt.Errorf("Request Error, StatusCode : %v", r.StatusCode)
Tang Chengf16121a2015-07-27 13:46:14 +0800407 return
408 }
Tang Chenga412d202016-01-27 09:24:53 +0800409 if r.Body != nil {
410 defer r.Body.Close()
411 }
Tang Chengf16121a2015-07-27 13:46:14 +0800412 body, err := ioutil.ReadAll(r.Body)
Tang Chengf16121a2015-07-27 13:46:14 +0800413 var s interface{}
414 err = json.Unmarshal(body, &s)
415 if err != nil {
416 log.Errorf("json unmarshal err %v", err)
417 return
418 }
Tang Chenge29065c2016-07-14 12:29:42 +0800419 response = NewServiceResponseFromJSON(s)
Tang Chengf16121a2015-07-27 13:46:14 +0800420 return
421}