blob: 732f8be205be627145feb4c9f5c4d16d48ebd75f [file] [log] [blame]
package swservice
import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
log "github.com/Sirupsen/logrus"
"io/ioutil"
"net"
"net/http"
"net/url"
"time"
)
func dailTimeout(network, addr string) (net.Conn, error) {
// default_timeout := time.Duration(theSession.DefaultTimeout) * time.Second
default_timeout := time.Duration(3) * time.Second
return net.DialTimeout(network, addr, default_timeout)
}
type WebSession struct {
AppId string
TermId string
Appsecret string
BaseUrl string
DefaultTimeout int
session_key string
}
func (w *WebSession) DoGet(uri string, params map[string]string) (*http.Response, error) {
transport := http.Transport{Dial: dailTimeout}
client := http.Client{Transport: &transport}
full_url := w.BaseUrl + uri
vl := url.Values{}
if params != nil {
for k, v := range params {
vl.Add(k, v)
}
}
full_url = full_url + "?" + vl.Encode()
return client.Get(full_url)
}
func (w *WebSession) GetTimestamp() string {
t := time.Now()
return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(),
t.Hour(), t.Minute(), t.Second())
}
func (w *WebSession) Sign(message string) string {
mac := hmac.New(sha1.New, []byte(w.Appsecret))
mac.Write([]byte(message))
res := mac.Sum(nil)
return hex.EncodeToString(res)
}
func (w *WebSession) DoPost(uri string, param map[string]string) (*http.Response, error) {
transport := http.Transport{Dial: dailTimeout}
client := &http.Client{Transport: &transport}
param["app_id"] = w.AppId
param["term_id"] = w.TermId
param["sign_method"] = "HMAC"
param["session_key"] = w.session_key
ts := w.GetTimestamp()
param["timestamp"] = ts
param["sign"] = w.Sign(w.AppId + w.TermId + w.session_key + ts)
full_url := w.BaseUrl + uri
log.Debugf("Url=%v", full_url)
data, err := json.Marshal(param)
if err != nil {
return nil, err
}
var r *http.Response
r, err = client.Post(full_url, "application/json", bytes.NewReader(data))
if err != nil || r.StatusCode != 200 {
log.Errorf("Status=%v, err=%v", r, err)
}
return r, err
}
func (w *WebSession) Auth() error {
token, err := w.getAuthToken()
if err != nil {
return err
}
err = w.getAppAccessKey(token)
if err != nil {
return err
}
return nil
}
func NewSession(appid, appsecret, termid, baseurl string, timeout int) *WebSession {
return &WebSession{
AppId: appid,
Appsecret: appsecret,
TermId: termid,
BaseUrl: baseurl,
DefaultTimeout: timeout,
}
}
func (w *WebSession) getAuthToken() (string, error) {
type FormJson struct {
AppId string `json:"app_id"`
TermId string `json:"term_id"`
AccessToken string `json:"access_token"`
}
uri := fmt.Sprintf("/authservice/getauth/%v/getaccesstoken", w.AppId)
params := make(map[string]string)
params["term_id"] = w.TermId
r, err := w.DoGet(uri, params)
if err != nil || r.StatusCode != 200 {
fmt.Println("here")
// log.Errorf("Status = %v, err = %v\n", r.StatusCode, err)
return "", errors.New("请求失败")
}
body, err := ioutil.ReadAll(r.Body)
r.Body.Close()
s := &FormJson{}
err = json.Unmarshal(body, &s)
if err != nil {
log.Errorf("json unmarshal err %v", err)
return "", errors.New("解析失败")
}
return s.AccessToken, nil
}
func (w *WebSession) getAppAccessKey(token string) error {
type FormJson struct {
AppId string `json:"app_id"`
TermId string `json:"term_id"`
SessionKey string `json:"session_key"`
CardKey string `json:"card_key"`
}
uri := fmt.Sprintf("/authservice/getauth/%v", w.AppId)
params := make(map[string]string)
params["term_id"] = w.TermId
params["access_token"] = token
params["timestamp"] = w.GetTimestamp()
params["v"] = "1"
params["sign"] = w.Sign(token + params["timestamp"])
params["sign_method"] = "HMAC"
r, err := w.DoGet(uri, params)
if err != nil || r.StatusCode != 200 {
log.Errorf(" err = %v\n", err)
return err
}
body, err := ioutil.ReadAll(r.Body)
r.Body.Close()
s := &FormJson{}
err = json.Unmarshal(body, &s)
if err != nil {
log.Errorf("json unmarshal err %v", err)
}
w.session_key = s.SessionKey
return nil
}
func (w *WebSession) CallYKTApi(request *MessageWriter) (*MessageReader, error) {
call_data := request.Serialize()
params := make(map[string]string)
params["funcdata"] = call_data
r, err := w.DoPost("/ecardservice/ecardapi", params)
if err != nil || r.StatusCode != 200 {
log.Errorf(" err = %v\n", err)
return nil, err
}
body, err := ioutil.ReadAll(r.Body)
r.Body.Close()
return NewMessageReader(body), nil
}