96 lines
2.1 KiB
Go
96 lines
2.1 KiB
Go
|
package vip
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"context"
|
||
|
"crypto/md5"
|
||
|
"encoding/hex"
|
||
|
xhttp "net/http"
|
||
|
"net/url"
|
||
|
"strings"
|
||
|
|
||
|
"go-common/library/conf/env"
|
||
|
bm "go-common/library/net/http/blademaster"
|
||
|
|
||
|
pkgerr "github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
//Clientl Client is http client, for url sign.
|
||
|
type Clientl struct {
|
||
|
client *bm.Client
|
||
|
conf *bm.ClientConfig
|
||
|
}
|
||
|
|
||
|
// NewClientl new a http client.
|
||
|
func NewClientl(c *bm.ClientConfig, client *bm.Client) *Clientl {
|
||
|
// check appkey
|
||
|
if c.Key == "" || c.Secret == "" {
|
||
|
panic("http client must config appkey and appsecret")
|
||
|
}
|
||
|
cl := new(Clientl)
|
||
|
cl.client = client
|
||
|
cl.conf = c
|
||
|
return cl
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
_httpHeaderRemoteIP = "x-backend-bili-real-ip"
|
||
|
_noKickUserAgent = "haoguanwei@bilibili.com "
|
||
|
)
|
||
|
|
||
|
func (cl *Clientl) get(c context.Context, host, path, realIP string, params url.Values, res interface{}) (err error) {
|
||
|
req, err := cl.newGetRequest(host, path, realIP, params)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
return cl.client.Do(c, req, res)
|
||
|
}
|
||
|
|
||
|
// newGetRequest new get http request with host, path, ip, values and headers, without sign.
|
||
|
func (cl *Clientl) newGetRequest(host, path, realIP string, params url.Values) (req *xhttp.Request, err error) {
|
||
|
if params == nil {
|
||
|
params = url.Values{}
|
||
|
}
|
||
|
params.Add("client_id", cl.conf.App.Key)
|
||
|
enc := sign(params, path, cl.conf.App.Secret)
|
||
|
ru := host + path
|
||
|
if enc != "" {
|
||
|
ru = ru + "?" + enc
|
||
|
}
|
||
|
req, err = xhttp.NewRequest(xhttp.MethodGet, ru, nil)
|
||
|
if err != nil {
|
||
|
err = pkgerr.Wrapf(err, "uri:%s", ru)
|
||
|
return
|
||
|
}
|
||
|
const (
|
||
|
_userAgent = "User-Agent"
|
||
|
)
|
||
|
if realIP != "" {
|
||
|
req.Header.Set(_httpHeaderRemoteIP, realIP)
|
||
|
}
|
||
|
req.Header.Set(_userAgent, _noKickUserAgent+" "+env.AppID)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func sign(params url.Values, path, secret string) string {
|
||
|
if params == nil {
|
||
|
params = url.Values{}
|
||
|
}
|
||
|
tmp := params.Encode()
|
||
|
if strings.IndexByte(tmp, '+') > -1 {
|
||
|
tmp = strings.Replace(tmp, "+", "%20", -1)
|
||
|
}
|
||
|
var b bytes.Buffer
|
||
|
b.WriteString(path)
|
||
|
b.WriteString("?")
|
||
|
b.WriteString(tmp)
|
||
|
b.WriteString(secret)
|
||
|
mh := md5.Sum(b.Bytes())
|
||
|
// query
|
||
|
var qb bytes.Buffer
|
||
|
qb.WriteString(tmp)
|
||
|
qb.WriteString("&sign=")
|
||
|
qb.WriteString(hex.EncodeToString(mh[:]))
|
||
|
return qb.String()
|
||
|
}
|