basic.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package datacenter_client
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "encoding/hex"
  6. "encoding/json"
  7. "fmt"
  8. "io/ioutil"
  9. "metawant.greentech.com.cn/gaoyagang/gt-common/httplib"
  10. "net/http"
  11. "net/url"
  12. "sort"
  13. "time"
  14. )
  15. type DcApiClient struct {
  16. ServerIp string
  17. AppName string
  18. AppSecret string
  19. }
  20. const (
  21. S2_MIN_LENGTH = 2048
  22. S2_HEAD_LENGTH = 200
  23. S2_TAIL_LENGTH = 200
  24. )
  25. func CreateDcApiClient(ip, appName, appSecret string) *DcApiClient {
  26. return &DcApiClient{
  27. ServerIp: ip,
  28. AppName: appName,
  29. AppSecret: appSecret,
  30. }
  31. }
  32. func (d *DcApiClient) RequestMiddleProcess(h *httplib.HTTPRequest, projectId string) ([]byte, error) {
  33. //h.Header("X-Forwarded-For", "127.0.0.1")
  34. h.Header("APP-NAME", d.AppName)
  35. ts := time.Now().Unix()
  36. h.Param("project_id", projectId)
  37. h.Param("ts", fmt.Sprintf("%d", ts))
  38. sign := d.CreateSign(h)
  39. h.Param("sign", sign)
  40. return h.Bytes()
  41. }
  42. func (d *DcApiClient)CreateSign(h *httplib.HTTPRequest) string {
  43. s2, err := parseBody(h)
  44. if err != nil {
  45. fmt.Println("parseBody Error: ", err.Error())
  46. }
  47. contentLength := h.GetRequest().ContentLength
  48. if contentLength > S2_MIN_LENGTH {
  49. h.Param("sign_flag", "1")
  50. s2 = cutS2(s2)
  51. } else {
  52. s2, _ = sortS2(s2)
  53. }
  54. s3 := contentLength
  55. s1 := parseQuery(h)
  56. m := md5.New()
  57. m.Write([]byte(fmt.Sprintf("%s%s%d%s", s1, s2, s3, d.AppSecret)))
  58. md5Str := hex.EncodeToString(m.Sum(nil))
  59. //fmt.Println("s1", s1)
  60. //fmt.Println("s2", s2)
  61. //fmt.Println("s3", s3)
  62. //fmt.Println("md5", md5Str)
  63. return md5Str
  64. }
  65. func cutS2(s2 string) string {
  66. s2l := len(s2)
  67. //if s2l <= S2_MIN_LENGTH {
  68. // return s2
  69. //}
  70. return fmt.Sprintf("%s%s", s2[:S2_HEAD_LENGTH], s2[s2l-S2_TAIL_LENGTH:])
  71. }
  72. func sortS2(s2 string) (string, error) {
  73. var mi map[string]interface{}
  74. if err := json.Unmarshal([]byte(s2), &mi); err != nil {
  75. return "", err
  76. }
  77. smi := SortMapByKey(mi)
  78. if bs, err := json.Marshal(smi); err != nil {
  79. return "", err
  80. } else {
  81. return string(bs), nil
  82. }
  83. }
  84. func parseBody(r *httplib.HTTPRequest) (s2 string, err error) {
  85. if r.GetRequest().Method == http.MethodGet {
  86. return "", nil
  87. }
  88. body := r.GetRequest().Body
  89. cnt, _ := ioutil.ReadAll(body)
  90. r.GetRequest().Body = ioutil.NopCloser(bytes.NewReader(cnt))
  91. return string(cnt), nil
  92. }
  93. func parseQuery(r *httplib.HTTPRequest) string {
  94. params := r.GetQueryParam()
  95. delete(params, "sign")
  96. val := url.Values{}
  97. for k, v := range params {
  98. for index, s := range v {
  99. if index == 0 {
  100. val.Set(k, s)
  101. } else {
  102. val.Add(k, s)
  103. }
  104. }
  105. }
  106. return val.Encode()
  107. }
  108. // SortMapByKey 对 map[string]interface{} 按照键进行排序
  109. func SortMapByKey(m map[string]interface{}) map[string]interface{} {
  110. // 创建一个 map[string]int,用于记录键的索引
  111. indexMap := make(map[string]int)
  112. for k := range m {
  113. indexMap[k] = len(indexMap)
  114. }
  115. // 对键进行排序
  116. keys := make([]string, 0, len(indexMap))
  117. for k := range indexMap {
  118. keys = append(keys, k)
  119. }
  120. sort.Strings(keys)
  121. // 创建排序后的 map[string]interface{}
  122. sortedMap := make(map[string]interface{})
  123. for _, k := range keys {
  124. sortedMap[k] = m[k]
  125. }
  126. return sortedMap
  127. }