You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.4 KiB
90 lines
2.4 KiB
2 years ago
|
package http
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"encoding/json"
|
||
|
"gitea.drugeyes.vip/pharnexbase/tools/request"
|
||
|
"github.com/go-kratos/kratos/v2/errors"
|
||
|
"github.com/go-kratos/kratos/v2/transport/http"
|
||
|
"github.com/go-kratos/kratos/v2/transport/http/binding"
|
||
|
"github.com/tidwall/gjson"
|
||
|
"io"
|
||
|
"net/url"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var SignErr = errors.Forbidden("SignError", "签名错误")
|
||
|
|
||
|
func (t *Transport) RequestQueryDecoder() http.DecodeRequestFunc {
|
||
|
return func(r *http.Request, v interface{}) error {
|
||
|
// 将post和query参数合并
|
||
|
params := make(map[string]string)
|
||
|
for _, val := range strings.Split(r.URL.RawQuery, "&") {
|
||
|
vals := strings.Split(val, "=")
|
||
|
if len(vals) < 2 {
|
||
|
continue
|
||
|
}
|
||
|
params[vals[0]], _ = url.PathUnescape(vals[1])
|
||
|
}
|
||
|
signature := request.NewSignature(t.apiKey, request.NewSHA1HashAlg())
|
||
|
signStr := signature.GenSignature(params)
|
||
|
if signStr != r.Header.Get("sm5") {
|
||
|
return SignErr
|
||
|
}
|
||
|
if err := binding.BindQuery(r.URL.Query(), v); err != nil {
|
||
|
return errors.BadRequest("CODEC", err.Error())
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// RequestDecoder 请求拦截
|
||
|
func (t *Transport) RequestDecoder() http.DecodeRequestFunc {
|
||
|
return func(r *http.Request, v interface{}) error {
|
||
|
// 从Request Header的Content-Type中提取出对应的解码器
|
||
|
codec, ok := http.CodecForRequest(r, "Content-Type")
|
||
|
// 如果找不到对应的解码器此时会报错
|
||
|
if !ok {
|
||
|
return errors.BadRequest("CODEC", r.Header.Get("Content-Type"))
|
||
|
}
|
||
|
data, err := io.ReadAll(r.Body)
|
||
|
if err != nil {
|
||
|
return errors.BadRequest("CODEC", err.Error())
|
||
|
}
|
||
|
|
||
|
// 将post和query参数合并
|
||
|
params := make(map[string]string)
|
||
|
gjson.ParseBytes(data).ForEach(func(key, value gjson.Result) bool {
|
||
|
switch value.Type {
|
||
|
case gjson.JSON:
|
||
|
var buf bytes.Buffer
|
||
|
json.Compact(&buf, []byte(value.String()))
|
||
|
params[key.String()] = buf.String()
|
||
|
default:
|
||
|
params[key.String()] = value.String()
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
})
|
||
|
for _, val := range strings.Split(r.URL.RawQuery, "&") {
|
||
|
vals := strings.Split(val, "=")
|
||
|
if len(vals) < 2 {
|
||
|
continue
|
||
|
}
|
||
|
params[vals[0]], _ = url.PathUnescape(vals[1])
|
||
|
}
|
||
|
signature := request.NewSignature(t.apiKey, request.NewSHA1HashAlg())
|
||
|
signStr := signature.GenSignature(params)
|
||
|
if signStr != r.Header.Get("sm5") {
|
||
|
return SignErr
|
||
|
}
|
||
|
|
||
|
if err = codec.Unmarshal(data, v); err != nil {
|
||
|
return errors.BadRequest("CODEC", err.Error())
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
}
|