|
@@ -0,0 +1,149 @@
|
|
|
+package datacenter_client
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "crypto/md5"
|
|
|
+ "encoding/hex"
|
|
|
+ "encoding/json"
|
|
|
+ "fmt"
|
|
|
+ "io/ioutil"
|
|
|
+ "metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
|
|
|
+ "net/http"
|
|
|
+ "net/url"
|
|
|
+ "sort"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+type DcApiClient struct {
|
|
|
+ ServerIp string
|
|
|
+ AppName string
|
|
|
+ AppSecret string
|
|
|
+}
|
|
|
+
|
|
|
+const (
|
|
|
+ S2_MIN_LENGTH = 2048
|
|
|
+ S2_HEAD_LENGTH = 200
|
|
|
+ S2_TAIL_LENGTH = 200
|
|
|
+)
|
|
|
+
|
|
|
+func CreateDcApiClient(ip, appName, appSecret string) *DcApiClient {
|
|
|
+ return &DcApiClient{
|
|
|
+ ServerIp: ip,
|
|
|
+ AppName: appName,
|
|
|
+ AppSecret: appSecret,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (d *DcApiClient) RequestMiddleProcess(h *httplib.HTTPRequest, projectId string) ([]byte, error) {
|
|
|
+ //h.Header("X-Forwarded-For", "127.0.0.1")
|
|
|
+ h.Header("APP-NAME", d.AppName)
|
|
|
+ ts := time.Now().Unix()
|
|
|
+ h.Param("project_id", projectId)
|
|
|
+ h.Param("ts", fmt.Sprintf("%d", ts))
|
|
|
+ sign := d.CreateSign(h)
|
|
|
+ h.Param("sign", sign)
|
|
|
+ return h.Bytes()
|
|
|
+}
|
|
|
+
|
|
|
+func (d *DcApiClient)CreateSign(h *httplib.HTTPRequest) string {
|
|
|
+ s2, err := parseBody(h)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("parseBody Error: ", err.Error())
|
|
|
+ }
|
|
|
+ contentLength := h.GetRequest().ContentLength
|
|
|
+ if contentLength > S2_MIN_LENGTH {
|
|
|
+ h.Param("sign_flag", "1")
|
|
|
+ s2 = cutS2(s2)
|
|
|
+ } else {
|
|
|
+ s2, _ = sortS2(s2)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ s3 := contentLength
|
|
|
+ s1 := parseQuery(h)
|
|
|
+
|
|
|
+ m := md5.New()
|
|
|
+ m.Write([]byte(fmt.Sprintf("%s%s%d%s", s1, s2, s3, d.AppSecret)))
|
|
|
+ md5Str := hex.EncodeToString(m.Sum(nil))
|
|
|
+ //fmt.Println("s1", s1)
|
|
|
+ //fmt.Println("s2", s2)
|
|
|
+ //fmt.Println("s3", s3)
|
|
|
+ //fmt.Println("md5", md5Str)
|
|
|
+ return md5Str
|
|
|
+}
|
|
|
+
|
|
|
+func cutS2(s2 string) string {
|
|
|
+ s2l := len(s2)
|
|
|
+ //if s2l <= S2_MIN_LENGTH {
|
|
|
+ // return s2
|
|
|
+ //}
|
|
|
+ return fmt.Sprintf("%s%s", s2[:S2_HEAD_LENGTH], s2[s2l-S2_TAIL_LENGTH:])
|
|
|
+}
|
|
|
+
|
|
|
+func sortS2(s2 string) (string, error) {
|
|
|
+ var mi map[string]interface{}
|
|
|
+ if err := json.Unmarshal([]byte(s2), &mi); err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+
|
|
|
+ smi := SortMapByKey(mi)
|
|
|
+
|
|
|
+ if bs, err := json.Marshal(smi); err != nil {
|
|
|
+ return "", err
|
|
|
+ } else {
|
|
|
+ return string(bs), nil
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func parseBody(r *httplib.HTTPRequest) (s2 string, err error) {
|
|
|
+ if r.GetRequest().Method == http.MethodGet {
|
|
|
+ return "", nil
|
|
|
+ }
|
|
|
+ body := r.GetRequest().Body
|
|
|
+
|
|
|
+ cnt, _ := ioutil.ReadAll(body)
|
|
|
+ r.GetRequest().Body = ioutil.NopCloser(bytes.NewReader(cnt))
|
|
|
+
|
|
|
+ return string(cnt), nil
|
|
|
+}
|
|
|
+
|
|
|
+func parseQuery(r *httplib.HTTPRequest) string {
|
|
|
+ params := r.GetQueryParam()
|
|
|
+ delete(params, "sign")
|
|
|
+
|
|
|
+ val := url.Values{}
|
|
|
+ for k, v := range params {
|
|
|
+ for index, s := range v {
|
|
|
+ if index == 0 {
|
|
|
+ val.Set(k, s)
|
|
|
+ } else {
|
|
|
+ val.Add(k, s)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return val.Encode()
|
|
|
+}
|
|
|
+
|
|
|
+// SortMapByKey 对 map[string]interface{} 按照键进行排序
|
|
|
+func SortMapByKey(m map[string]interface{}) map[string]interface{} {
|
|
|
+ // 创建一个 map[string]int,用于记录键的索引
|
|
|
+ indexMap := make(map[string]int)
|
|
|
+ for k := range m {
|
|
|
+ indexMap[k] = len(indexMap)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 对键进行排序
|
|
|
+ keys := make([]string, 0, len(indexMap))
|
|
|
+ for k := range indexMap {
|
|
|
+ keys = append(keys, k)
|
|
|
+ }
|
|
|
+ sort.Strings(keys)
|
|
|
+
|
|
|
+ // 创建排序后的 map[string]interface{}
|
|
|
+ sortedMap := make(map[string]interface{})
|
|
|
+ for _, k := range keys {
|
|
|
+ sortedMap[k] = m[k]
|
|
|
+ }
|
|
|
+
|
|
|
+ return sortedMap
|
|
|
+}
|