blob: 067b1725d17f135f63be3d84cc21ecd8f760e6b7 [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 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"
11 log "github.com/Sirupsen/logrus"
qiaoweica037fa2015-07-10 18:31:53 +080012 "io/ioutil"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080013 "net"
14 "net/http"
15 "net/url"
Tang Chengf16121a2015-07-27 13:46:14 +080016 "strconv"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080017 "time"
18)
Tang Cheng32e32562015-07-08 17:08:03 +080019
20func dailTimeout(network, addr string) (net.Conn, error) {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080021 // default_timeout := time.Duration(theSession.DefaultTimeout) * time.Second
22 default_timeout := time.Duration(3) * time.Second
Tang Cheng32e32562015-07-08 17:08:03 +080023 return net.DialTimeout(network, addr, default_timeout)
24}
25
26type WebSession struct {
27 AppId string
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +080028 TermId string
29 Appsecret string
Tang Cheng32e32562015-07-08 17:08:03 +080030 BaseUrl string
31 DefaultTimeout int
32 session_key string
33}
34
Tang Chengf16121a2015-07-27 13:46:14 +080035func safe_get_json_int(value interface{}) int {
36 if value == nil {
37 return 0
38 }
39 s := fmt.Sprintf("%v", value)
40 if i, err := strconv.Atoi(s); err != nil {
41 return 0
42 } else {
43 return i
44 }
45}
46
47type ServiceResponse struct {
48 RetCode int
49 RetMsg string
50 Result map[string]interface{}
51}
52
53func NewServiceResponseFromJson(json_data interface{}) *ServiceResponse {
54 if json_data == nil {
55 return nil
56 }
57 res := &ServiceResponse{}
58 res.Result = json_data.(map[string]interface{})
59 res.RetCode = safe_get_json_int(res.Result["retcode"])
60 res.RetMsg = res.GetStrValue("retmsg")
61 return res
62}
63func (r *ServiceResponse) GetIntValue(name string) int {
64 return safe_get_json_int(r.Result[name])
65}
66
67func (r *ServiceResponse) GetStrValue(name string) string {
68 if s, ok := r.Result[name]; ok {
69 return fmt.Sprintf("%v", s)
70 } else {
71 return ""
72 }
73}
74
75func (r *ServiceResponse) GetFloatValue(name string) float64 {
76 if s, ok := r.Result[name]; ok {
77 t := fmt.Sprintf("%v", s)
78 if f, err := strconv.ParseFloat(t, 64); err != nil {
79 return 0.0
80 } else {
81 return f
82 }
83 } else {
84 return 0.0
85 }
86}
87
Tang Cheng32e32562015-07-08 17:08:03 +080088func (w *WebSession) DoGet(uri string, params map[string]string) (*http.Response, error) {
89 transport := http.Transport{Dial: dailTimeout}
90
91 client := http.Client{Transport: &transport}
92
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 {
124 transport := http.Transport{Dial: func(network, addr string) (net.Conn, error) {
125 default_timeout := time.Duration(timeout) * time.Second
126 return net.DialTimeout(network, addr, default_timeout)
127 }}
128
129 return &http.Client{Transport: &transport}
130}
Tang Cheng26b91152015-07-22 12:26:52 +0800131func (w *WebSession) DoPost(uri string, param map[string]string) (*http.Response, error) {
Tang Cheng32e32562015-07-08 17:08:03 +0800132 transport := http.Transport{Dial: dailTimeout}
133 client := &http.Client{Transport: &transport}
Tang Cheng26b91152015-07-22 12:26:52 +0800134 param["app_id"] = w.AppId
Tang Chengf16121a2015-07-27 13:46:14 +0800135 // param["term_id"] = w.TermId
Tang Cheng26b91152015-07-22 12:26:52 +0800136 param["sign_method"] = "HMAC"
137 param["session_key"] = w.session_key
Tang Cheng32e32562015-07-08 17:08:03 +0800138 ts := w.GetTimestamp()
Tang Cheng26b91152015-07-22 12:26:52 +0800139 param["timestamp"] = ts
140 param["sign"] = w.Sign(w.AppId + w.TermId + w.session_key + ts)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800141
Tang Cheng32e32562015-07-08 17:08:03 +0800142 full_url := w.BaseUrl + uri
Tang Chengf16121a2015-07-27 13:46:14 +0800143 // log.Debugf("Url=%v", full_url)
Tang Cheng26b91152015-07-22 12:26:52 +0800144 data, err := json.Marshal(param)
145 if err != nil {
146 return nil, err
147 }
148 var r *http.Response
149 r, err = client.Post(full_url, "application/json", bytes.NewReader(data))
Tang Cheng32e32562015-07-08 17:08:03 +0800150 if err != nil || r.StatusCode != 200 {
151 log.Errorf("Status=%v, err=%v", r, err)
152 }
153 return r, err
154}
155
156func (w *WebSession) Auth() error {
qiaoweica037fa2015-07-10 18:31:53 +0800157 token, err := w.getAuthToken()
158 if err != nil {
159 return err
160 }
161 err = w.getAppAccessKey(token)
162 if err != nil {
163 return err
164 }
Tang Cheng32e32562015-07-08 17:08:03 +0800165 return nil
166}
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800167
168func NewSession(appid, appsecret, termid, baseurl string, timeout int) *WebSession {
169 return &WebSession{
170 AppId: appid,
171 Appsecret: appsecret,
172 TermId: termid,
173 BaseUrl: baseurl,
174 DefaultTimeout: timeout,
175 }
176}
177
qiaoweica037fa2015-07-10 18:31:53 +0800178func (w *WebSession) getAuthToken() (string, error) {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800179 type FormJson struct {
180 AppId string `json:"app_id"`
181 TermId string `json:"term_id"`
182 AccessToken string `json:"access_token"`
183 }
184
Tang Cheng26b91152015-07-22 12:26:52 +0800185 uri := fmt.Sprintf("/authservice/getauth/%v/getaccesstoken", w.AppId)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800186
187 params := make(map[string]string)
188 params["term_id"] = w.TermId
189 r, err := w.DoGet(uri, params)
190
191 if err != nil || r.StatusCode != 200 {
192 fmt.Println("here")
193 // log.Errorf("Status = %v, err = %v\n", r.StatusCode, err)
qiaoweica037fa2015-07-10 18:31:53 +0800194 return "", errors.New("请求失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800195 }
196
qiaoweica037fa2015-07-10 18:31:53 +0800197 body, err := ioutil.ReadAll(r.Body)
198 r.Body.Close()
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800199
qiaoweica037fa2015-07-10 18:31:53 +0800200 s := &FormJson{}
201 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800202 if err != nil {
203 log.Errorf("json unmarshal err %v", err)
qiaoweica037fa2015-07-10 18:31:53 +0800204 return "", errors.New("解析失败")
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800205 }
qiaoweica037fa2015-07-10 18:31:53 +0800206 return s.AccessToken, nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800207}
qiaoweica037fa2015-07-10 18:31:53 +0800208func (w *WebSession) getAppAccessKey(token string) error {
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800209 type FormJson struct {
qiaoweica037fa2015-07-10 18:31:53 +0800210 AppId string `json:"app_id"`
211 TermId string `json:"term_id"`
212 SessionKey string `json:"session_key"`
213 CardKey string `json:"card_key"`
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800214 }
215
Tang Cheng26b91152015-07-22 12:26:52 +0800216 uri := fmt.Sprintf("/authservice/getauth/%v", w.AppId)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800217
218 params := make(map[string]string)
219 params["term_id"] = w.TermId
qiaoweica037fa2015-07-10 18:31:53 +0800220 params["access_token"] = token
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800221 params["timestamp"] = w.GetTimestamp()
222 params["v"] = "1"
qiaoweica037fa2015-07-10 18:31:53 +0800223 params["sign"] = w.Sign(token + params["timestamp"])
224 params["sign_method"] = "HMAC"
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800225
qiaoweica037fa2015-07-10 18:31:53 +0800226 r, err := w.DoGet(uri, params)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800227 if err != nil || r.StatusCode != 200 {
qiaoweica037fa2015-07-10 18:31:53 +0800228 log.Errorf(" err = %v\n", err)
229 return err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800230 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800231
qiaoweica037fa2015-07-10 18:31:53 +0800232 body, err := ioutil.ReadAll(r.Body)
233 r.Body.Close()
qiaoweica037fa2015-07-10 18:31:53 +0800234
235 s := &FormJson{}
236 err = json.Unmarshal(body, &s)
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800237 if err != nil {
238 log.Errorf("json unmarshal err %v", err)
239 }
qiaoweica037fa2015-07-10 18:31:53 +0800240 w.session_key = s.SessionKey
241 return nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800242}
Tang Cheng26b91152015-07-22 12:26:52 +0800243
244func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
245 call_data := request.Serialize()
246 params := make(map[string]string)
247 params["funcdata"] = call_data
248 r, err := w.DoPost("/ecardservice/ecardapi", params)
249
Tang Chengf16121a2015-07-27 13:46:14 +0800250 if err != nil {
Tang Cheng26b91152015-07-22 12:26:52 +0800251 log.Errorf(" err = %v\n", err)
252 return nil, err
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800253 }
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800254
Tang Chengf16121a2015-07-27 13:46:14 +0800255 if r.StatusCode != 200 {
256 return nil, errors.New(fmt.Sprintf("Request StatusCode:%v", r.StatusCode))
257 }
258
Tang Cheng26b91152015-07-22 12:26:52 +0800259 body, err := ioutil.ReadAll(r.Body)
260 r.Body.Close()
261 return NewMessageReader(body), nil
zongqiang.zhangb8ab9b42015-07-10 17:45:20 +0800262}
Tang Chengf16121a2015-07-27 13:46:14 +0800263
264func (w *WebSession) CallService(path string, params map[string]interface{},
265 sign_field []string, timeout int) (response *ServiceResponse, err error) {
266
267 return w.CallService2(path, params, timeout, sign_field...)
268}
269
270func (w *WebSession) CallService2(path string, params map[string]interface{}, timeout int,
271 sign_field ...string) (response *ServiceResponse, err error) {
272 client := w.NewClient(timeout)
273 err = nil
274 params["app_id"] = w.AppId
275 params["term_id"] = w.TermId
276 ts := w.GetTimestamp()
277 params["timestamp"] = ts
278
279 vl := &url.Values{}
280 for k, v := range params {
281 vl.Set(k, fmt.Sprintf("%v", v))
282 }
283
284 sign_data := ""
285 for _, k := range sign_field {
286 if v, ok := params[k]; ok {
287 sign_data += fmt.Sprintf("%v", v)
288 }
289 }
290 sign_data += ts + w.session_key
291 vl.Set("sign_method", "HMAC")
292 log.Debugf("Sign: key[%v] data[%v]\n", w.session_key, sign_data)
293 vl.Set("sign", w.SignWithKey(w.Appsecret, sign_data))
294
295 full_url := w.BaseUrl + path
296 log.Debugf("CallService: %v\n", full_url)
297 var r *http.Response
298 r, err = client.Post(full_url, "application/x-www-form-urlencoded",
299 bytes.NewReader([]byte(vl.Encode())))
300 if err != nil {
301 log.Errorf("Status=%v, err=%v", r, err)
302 return
303 }
304 if r.StatusCode != 200 {
305 log.Errorf("Request Error %v\n", r.StatusCode)
306 err = errors.New(fmt.Sprintf("Request Error, StatusCode : %v", r.StatusCode))
307 return
308 }
309 body, err := ioutil.ReadAll(r.Body)
310 r.Body.Close()
311 var s interface{}
312 err = json.Unmarshal(body, &s)
313 if err != nil {
314 log.Errorf("json unmarshal err %v", err)
315 return
316 }
317 response = NewServiceResponseFromJson(s)
318 return
319}