85 lines
1.7 KiB
Go
85 lines
1.7 KiB
Go
package pkg
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/md5"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net/url"
|
|
"sort"
|
|
"strings"
|
|
|
|
"go-common/library/log"
|
|
|
|
"github.com/google/go-querystring/query"
|
|
)
|
|
|
|
const (
|
|
_sign = "sign"
|
|
)
|
|
|
|
// Signer.
|
|
type Signer struct {
|
|
Key string
|
|
}
|
|
|
|
func (s *Signer) struct2Values(in interface{}) (out url.Values, err error) {
|
|
out, err = query.Values(in)
|
|
if err != nil {
|
|
return
|
|
}
|
|
out.Del(_sign)
|
|
return
|
|
}
|
|
|
|
func (s *Signer) encodeUrlValues(values url.Values) (res string) {
|
|
keys := make([]string, 0)
|
|
for key := range values {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
kvSli := make([]string, 0)
|
|
for _, key := range keys {
|
|
kvStr := fmt.Sprintf("%s=%s", key, values.Get(key))
|
|
kvSli = append(kvSli, kvStr)
|
|
}
|
|
paramsStr := strings.Join(kvSli, "&")
|
|
return strings.ToLower(paramsStr) + "&key=" + s.Key
|
|
}
|
|
|
|
func (s *Signer) escapeStr(str string) (res string) {
|
|
return s.adapt(url.QueryEscape(str))
|
|
}
|
|
|
|
func (s *Signer) md5(str string) (res string) {
|
|
var (
|
|
buf bytes.Buffer
|
|
)
|
|
buf.WriteString(str)
|
|
hexMd5 := md5.Sum(buf.Bytes())
|
|
return strings.ToUpper(hex.EncodeToString(hexMd5[:]))
|
|
}
|
|
|
|
// Sign makes sign for yst request.
|
|
func (s *Signer) Sign(in interface{}) (sign string, err error) {
|
|
var (
|
|
values url.Values
|
|
)
|
|
if values, err = s.struct2Values(in); err != nil {
|
|
log.Error("signer.struct2Values(%+v) err(%+v)", in, err)
|
|
return
|
|
}
|
|
encodedVals := s.encodeUrlValues(values)
|
|
escapedVals := s.escapeStr(encodedVals)
|
|
sign = s.md5(escapedVals)
|
|
log.Info("Signer.Sign(%+v) sign(%s)", in, sign)
|
|
return
|
|
}
|
|
|
|
// NOTE: 经核对,云视听只有 `*` 不需要转义
|
|
func (s *Signer) adapt(str string) string {
|
|
res := str
|
|
res = strings.Replace(res, "%2A", "*", -1)
|
|
return res
|
|
}
|