blob: ec8ff4cc1b774702fdaf3d1cbf3bf05be119533a [file] [log] [blame]
Tang Cheng26b91152015-07-22 12:26:52 +08001package swservice
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +08002
3import (
4 "bytes"
5 "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"
12 log "github.com/Sirupsen/logrus"
qiaoweica037fa2015-07-10 18:31:53 +080013 "io/ioutil"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080014 "net"
15 "net/http"
16 "net/url"
Tang Chengf16121a2015-07-27 13:46:14 +080017 "strconv"
Tang Chengf8716aa2015-08-19 10:20:40 +080018 "strings"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080019 "time"
20)
Tang Cheng32e32562015-07-08 17:08:03 +080021
22func dailTimeout(network, addr string) (net.Conn, error) {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080023 // default_timeout := time.Duration(theSession.DefaultTimeout) * time.Second
24 default_timeout := time.Duration(3) * time.Second
Tang Cheng32e32562015-07-08 17:08:03 +080025 return net.DialTimeout(network, addr, default_timeout)
26}
27
28type WebSession struct {
29 AppId string
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080030 TermId string
31 Appsecret string
Tang Cheng32e32562015-07-08 17:08:03 +080032 BaseUrl string
33 DefaultTimeout int
34 session_key string
35}
36
Tang Chengf16121a2015-07-27 13:46:14 +080037func safe_get_json_int(value interface{}) int {
38 if value == nil {
39 return 0
40 }
41 s := fmt.Sprintf("%v", value)
42 if i, err := strconv.Atoi(s); err != nil {
43 return 0
44 } else {
45 return i
46 }
47}
48
49type ServiceResponse struct {
50 RetCode int
51 RetMsg string
52 Result map[string]interface{}
53}
54
55func NewServiceResponseFromJson(json_data interface{}) *ServiceResponse {
56 if json_data == nil {
57 return nil
58 }
59 res := &ServiceResponse{}
60 res.Result = json_data.(map[string]interface{})
61 res.RetCode = safe_get_json_int(res.Result["retcode"])
62 res.RetMsg = res.GetStrValue("retmsg")
63 return res
64}
65func (r *ServiceResponse) GetIntValue(name string) int {
66 return safe_get_json_int(r.Result[name])
67}
68
69func (r *ServiceResponse) GetStrValue(name string) string {
70 if s, ok := r.Result[name]; ok {
71 return fmt.Sprintf("%v", s)
72 } else {
73 return ""
74 }
75}
76
77func (r *ServiceResponse) GetFloatValue(name string) float64 {
78 if s, ok := r.Result[name]; ok {
79 t := fmt.Sprintf("%v", s)
80 if f, err := strconv.ParseFloat(t, 64); err != nil {
81 return 0.0
82 } else {
83 return f
84 }
85 } else {
86 return 0.0
87 }
88}
89
Tang Cheng32e32562015-07-08 17:08:03 +080090func (w *WebSession) DoGet(uri string, params map[string]string) (*http.Response, error) {
Tang Chengf8716aa2015-08-19 10:20:40 +080091 client := w.NewClient(3)
Tang Cheng32e32562015-07-08 17:08:03 +080092
93 full_url := w.BaseUrl + uri
94
95 vl := url.Values{}
Tang Cheng32e32562015-07-08 17:08:03 +080096
97 if params != nil {
98 for k, v := range params {
99 vl.Add(k, v)
100 }
101 }
Tang Cheng32e32562015-07-08 17:08:03 +0800102 full_url = full_url + "?" + vl.Encode()
Tang Chengf16121a2015-07-27 13:46:14 +0800103 // fmt.Printf("%v\n", full_url)
Tang Cheng32e32562015-07-08 17:08:03 +0800104 return client.Get(full_url)
105}
106
107func (w *WebSession) GetTimestamp() string {
108 t := time.Now()
109 return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(),
110 t.Hour(), t.Minute(), t.Second())
111}
112
Tang Chengf16121a2015-07-27 13:46:14 +0800113func (w *WebSession) SignWithKey(key, message string) string {
114 mac := hmac.New(sha1.New, []byte(key))
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800115 mac.Write([]byte(message))
116 res := mac.Sum(nil)
Tang Cheng26b91152015-07-22 12:26:52 +0800117 return hex.EncodeToString(res)
Tang Cheng32e32562015-07-08 17:08:03 +0800118}
Tang Chengf16121a2015-07-27 13:46:14 +0800119func (w *WebSession) Sign(message string) string {
120 return w.SignWithKey(w.Appsecret, message)
121}
Tang Cheng32e32562015-07-08 17:08:03 +0800122
Tang Chengf16121a2015-07-27 13:46:14 +0800123func (w *WebSession) NewClient(timeout int) *http.Client {
Tang Chengf8716aa2015-08-19 10:20:40 +0800124 var transport http.Transport
125 if strings.HasPrefix(w.BaseUrl, "https://") {
126 transport = http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
127 TLSHandshakeTimeout: time.Duration(timeout) * time.Second}
128 } else if strings.HasPrefix(w.BaseUrl, "http://") {
129 transport = http.Transport{Dial: func(network, addr string) (net.Conn, error) {
130 default_timeout := time.Duration(timeout) * time.Second
131 return net.DialTimeout(network, addr, default_timeout)
132 }}
133 }
Tang Chengf16121a2015-07-27 13:46:14 +0800134 return &http.Client{Transport: &transport}
135}
Tang Chengf8716aa2015-08-19 10:20:40 +0800136
Tang Cheng26b91152015-07-22 12:26:52 +0800137func (w *WebSession) DoPost(uri string, param map[string]string) (*http.Response, error) {
Tang Chengf8716aa2015-08-19 10:20:40 +0800138 client := w.NewClient(3)
Tang Cheng26b91152015-07-22 12:26:52 +0800139 param["app_id"] = w.AppId
Tang Chengf8716aa2015-08-19 10:20:40 +0800140 param["term_id"] = w.TermId
Tang Cheng26b91152015-07-22 12:26:52 +0800141 param["sign_method"] = "HMAC"
142 param["session_key"] = w.session_key
Tang Cheng32e32562015-07-08 17:08:03 +0800143 ts := w.GetTimestamp()
Tang Cheng26b91152015-07-22 12:26:52 +0800144 param["timestamp"] = ts
145 param["sign"] = w.Sign(w.AppId + w.TermId + w.session_key + ts)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800146
Tang Cheng32e32562015-07-08 17:08:03 +0800147 full_url := w.BaseUrl + uri
Tang Cheng26b91152015-07-22 12:26:52 +0800148 data, err := json.Marshal(param)
149 if err != nil {
150 return nil, err
151 }
152 var r *http.Response
153 r, err = client.Post(full_url, "application/json", bytes.NewReader(data))
Tang Cheng32e32562015-07-08 17:08:03 +0800154 if err != nil || r.StatusCode != 200 {
155 log.Errorf("Status=%v, err=%v", r, err)
156 }
157 return r, err
158}
159
160func (w *WebSession) Auth() error {
qiaoweica037fa2015-07-10 18:31:53 +0800161 token, err := w.getAuthToken()
162 if err != nil {
163 return err
164 }
165 err = w.getAppAccessKey(token)
166 if err != nil {
167 return err
168 }
Tang Cheng32e32562015-07-08 17:08:03 +0800169 return nil
170}
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800171
172func NewSession(appid, appsecret, termid, baseurl string, timeout int) *WebSession {
173 return &WebSession{
174 AppId: appid,
175 Appsecret: appsecret,
176 TermId: termid,
177 BaseUrl: baseurl,
178 DefaultTimeout: timeout,
179 }
180}
181
qiaoweica037fa2015-07-10 18:31:53 +0800182func (w *WebSession) getAuthToken() (string, error) {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800183 type FormJson struct {
184 AppId string `json:"app_id"`
185 TermId string `json:"term_id"`
186 AccessToken string `json:"access_token"`
187 }
188
Tang Cheng26b91152015-07-22 12:26:52 +0800189 uri := fmt.Sprintf("/authservice/getauth/%v/getaccesstoken", w.AppId)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800190
191 params := make(map[string]string)
192 params["term_id"] = w.TermId
193 r, err := w.DoGet(uri, params)
194
Tang Chengf8716aa2015-08-19 10:20:40 +0800195 if err != nil {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800196 // log.Errorf("Status = %v, err = %v\n", r.StatusCode, err)
Tang Chengf8716aa2015-08-19 10:20:40 +0800197 return "", err
198 }
199 if r.StatusCode != 200 {
qiaoweica037fa2015-07-10 18:31:53 +0800200 return "", errors.New("请求失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800201 }
202
qiaoweica037fa2015-07-10 18:31:53 +0800203 body, err := ioutil.ReadAll(r.Body)
204 r.Body.Close()
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800205
qiaoweica037fa2015-07-10 18:31:53 +0800206 s := &FormJson{}
207 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800208 if err != nil {
209 log.Errorf("json unmarshal err %v", err)
qiaoweica037fa2015-07-10 18:31:53 +0800210 return "", errors.New("解析失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800211 }
qiaoweica037fa2015-07-10 18:31:53 +0800212 return s.AccessToken, nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800213}
qiaoweica037fa2015-07-10 18:31:53 +0800214func (w *WebSession) getAppAccessKey(token string) error {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800215 type FormJson struct {
qiaoweica037fa2015-07-10 18:31:53 +0800216 AppId string `json:"app_id"`
217 TermId string `json:"term_id"`
218 SessionKey string `json:"session_key"`
219 CardKey string `json:"card_key"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800220 }
221
Tang Cheng26b91152015-07-22 12:26:52 +0800222 uri := fmt.Sprintf("/authservice/getauth/%v", w.AppId)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800223
224 params := make(map[string]string)
225 params["term_id"] = w.TermId
qiaoweica037fa2015-07-10 18:31:53 +0800226 params["access_token"] = token
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800227 params["timestamp"] = w.GetTimestamp()
228 params["v"] = "1"
qiaoweica037fa2015-07-10 18:31:53 +0800229 params["sign"] = w.Sign(token + params["timestamp"])
230 params["sign_method"] = "HMAC"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800231
qiaoweica037fa2015-07-10 18:31:53 +0800232 r, err := w.DoGet(uri, params)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800233 if err != nil || r.StatusCode != 200 {
qiaoweica037fa2015-07-10 18:31:53 +0800234 log.Errorf(" err = %v\n", err)
235 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800236 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800237
qiaoweica037fa2015-07-10 18:31:53 +0800238 body, err := ioutil.ReadAll(r.Body)
239 r.Body.Close()
qiaoweica037fa2015-07-10 18:31:53 +0800240
241 s := &FormJson{}
242 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800243 if err != nil {
244 log.Errorf("json unmarshal err %v", err)
245 }
qiaoweica037fa2015-07-10 18:31:53 +0800246 w.session_key = s.SessionKey
247 return nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800248}
Tang Cheng26b91152015-07-22 12:26:52 +0800249
250func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
251 call_data := request.Serialize()
252 params := make(map[string]string)
253 params["funcdata"] = call_data
254 r, err := w.DoPost("/ecardservice/ecardapi", params)
255
Tang Chengf16121a2015-07-27 13:46:14 +0800256 if err != nil {
Tang Cheng26b91152015-07-22 12:26:52 +0800257 log.Errorf(" err = %v\n", err)
258 return nil, err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800259 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800260
Tang Chengf16121a2015-07-27 13:46:14 +0800261 if r.StatusCode != 200 {
262 return nil, errors.New(fmt.Sprintf("Request StatusCode:%v", r.StatusCode))
263 }
264
Tang Cheng26b91152015-07-22 12:26:52 +0800265 body, err := ioutil.ReadAll(r.Body)
266 r.Body.Close()
267 return NewMessageReader(body), nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800268}
Tang Chengf16121a2015-07-27 13:46:14 +0800269
270func (w *WebSession) CallService(path string, params map[string]interface{},
271 sign_field []string, timeout int) (response *ServiceResponse, err error) {
272
273 return w.CallService2(path, params, timeout, sign_field...)
274}
275
276func (w *WebSession) CallService2(path string, params map[string]interface{}, timeout int,
277 sign_field ...string) (response *ServiceResponse, err error) {
278 client := w.NewClient(timeout)
279 err = nil
280 params["app_id"] = w.AppId
281 params["term_id"] = w.TermId
282 ts := w.GetTimestamp()
283 params["timestamp"] = ts
284
285 vl := &url.Values{}
286 for k, v := range params {
287 vl.Set(k, fmt.Sprintf("%v", v))
288 }
289
290 sign_data := ""
291 for _, k := range sign_field {
292 if v, ok := params[k]; ok {
293 sign_data += fmt.Sprintf("%v", v)
294 }
295 }
296 sign_data += ts + w.session_key
297 vl.Set("sign_method", "HMAC")
298 log.Debugf("Sign: key[%v] data[%v]\n", w.session_key, sign_data)
299 vl.Set("sign", w.SignWithKey(w.Appsecret, sign_data))
300
301 full_url := w.BaseUrl + path
302 log.Debugf("CallService: %v\n", full_url)
303 var r *http.Response
304 r, err = client.Post(full_url, "application/x-www-form-urlencoded",
305 bytes.NewReader([]byte(vl.Encode())))
306 if err != nil {
307 log.Errorf("Status=%v, err=%v", r, err)
308 return
309 }
310 if r.StatusCode != 200 {
311 log.Errorf("Request Error %v\n", r.StatusCode)
312 err = errors.New(fmt.Sprintf("Request Error, StatusCode : %v", r.StatusCode))
313 return
314 }
315 body, err := ioutil.ReadAll(r.Body)
316 r.Body.Close()
317 var s interface{}
318 err = json.Unmarshal(body, &s)
319 if err != nil {
320 log.Errorf("json unmarshal err %v", err)
321 return
322 }
323 response = NewServiceResponseFromJson(s)
324 return
325}