ele_client.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package client
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/hmac"
  6. "crypto/sha256"
  7. "encoding/hex"
  8. "encoding/json"
  9. xhttp "net/http"
  10. "strconv"
  11. "strings"
  12. "time"
  13. "go-common/library/log"
  14. bm "go-common/library/net/http/blademaster"
  15. pkgerr "github.com/pkg/errors"
  16. "github.com/satori/go.uuid"
  17. )
  18. const (
  19. _contentTypeJSON = "application/json"
  20. )
  21. //EleClient client is http client, for third ele server.
  22. type EleClient struct {
  23. client *bm.Client
  24. conf *Config
  25. }
  26. // Config is http client conf.
  27. type Config struct {
  28. *App
  29. }
  30. // App bilibili intranet authorization.
  31. type App struct {
  32. Key string
  33. Secret string
  34. }
  35. // NewEleClient new a http client.
  36. func NewEleClient(c *Config, client *bm.Client) *EleClient {
  37. cl := new(EleClient)
  38. cl.conf = c
  39. // check appkey
  40. if c.Key == "" || c.Secret == "" {
  41. panic("http client must config appkey and appsecret")
  42. }
  43. cl.client = client
  44. return cl
  45. }
  46. // Get a json req http get.
  47. func (cl *EleClient) Get(c context.Context, host, path string, args interface{}, res interface{}) (err error) {
  48. req, err := cl.newRequest(xhttp.MethodGet, host, path, args)
  49. if err != nil {
  50. return
  51. }
  52. return cl.client.Do(c, req, res)
  53. }
  54. // Post a json req http post.
  55. func (cl *EleClient) Post(c context.Context, host, path string, args interface{}, res interface{}) (err error) {
  56. req, err := cl.newRequest(xhttp.MethodPost, host, path, args)
  57. if err != nil {
  58. return
  59. }
  60. return cl.client.Do(c, req, res)
  61. }
  62. // IsSuccess check ele api is success.
  63. func IsSuccess(message string) bool {
  64. return message == "ok"
  65. }
  66. // newRequest new http request with host, path, method, ip, values and headers, without sign.
  67. func (cl *EleClient) newRequest(method, host, path string, args interface{}) (req *xhttp.Request, err error) {
  68. consumerKey := cl.conf.Key
  69. nonce := UUID4() //TODO uuid 有问题?
  70. timestamp := strconv.FormatInt(time.Now().Unix(), 10)
  71. sign := eleSign(consumerKey, nonce, timestamp, path, cl.conf.Secret)
  72. params := map[string]interface{}{}
  73. params["consumer_key"] = consumerKey
  74. params["nonce"] = nonce
  75. params["timestamp"] = timestamp
  76. params["sign"] = sign
  77. params["args"] = args
  78. url := host + path
  79. marshal, err := json.Marshal(params)
  80. if err != nil {
  81. err = pkgerr.Wrapf(err, "marshal:%v", params)
  82. return
  83. }
  84. rj := string(marshal)
  85. log.Info("ele_client req method(%s) url(%s) rj(%s)", method, url, rj)
  86. req, err = xhttp.NewRequest(method, url, strings.NewReader(rj))
  87. if err != nil {
  88. err = pkgerr.Wrapf(err, "uri:%s", url+" "+rj)
  89. return
  90. }
  91. req.Header.Set("Content-Type", _contentTypeJSON)
  92. return
  93. }
  94. func eleSign(consumerKey, nonce, timestamp, path, secret string) string {
  95. var b bytes.Buffer
  96. b.WriteString(path)
  97. b.WriteString("&")
  98. b.WriteString("consumer_key=")
  99. b.WriteString(consumerKey)
  100. b.WriteString("&nonce=")
  101. b.WriteString(nonce)
  102. b.WriteString("&timestamp=")
  103. b.WriteString(timestamp)
  104. return computeHmac256(b, secret)
  105. }
  106. func computeHmac256(b bytes.Buffer, secret string) string {
  107. key := []byte(secret)
  108. h := hmac.New(sha256.New, key)
  109. h.Write(b.Bytes())
  110. return hex.EncodeToString(h.Sum(nil))
  111. }
  112. // UUID4 is generate uuid
  113. func UUID4() string {
  114. return uuid.NewV4().String()
  115. }