修复aksk query参数顺序未按字母排序问题

This commit is contained in:
Liujian
2024-12-22 22:28:44 +08:00
parent 4835b678fa
commit d7e2d87d61
5 changed files with 127 additions and 62 deletions

View File

@@ -6,6 +6,7 @@ import (
"encoding/hex"
"errors"
"fmt"
"net/url"
"strings"
http_service "github.com/eolinker/eosc/eocontext/http-context"
@@ -31,7 +32,20 @@ func buildHexCanonicalRequest(ctx http_service.IHttpContext, signedHeaders []str
cr.WriteString(strings.ToUpper(ctx.Request().Method()) + "\n")
cr.WriteString(buildPath(ctx.Request().URI().Path()) + "\n")
cr.WriteString(ctx.Request().URI().RawQuery() + "\n")
// 对query参数排序
rawQuery := ctx.Request().URI().RawQuery()
query := url.Values{}
queryArgs := strings.Split(strings.TrimSpace(rawQuery), "&")
for i := 0; i < len(queryArgs); i++ {
params := strings.Split(queryArgs[i], "=")
if len(params) != 2 {
//query.Set(params[0], "")
continue
}
query.Set(params[0], params[1])
}
cr.WriteString(query.Encode() + "\n")
//cr.WriteString(ctx.Request().URI().RawQuery() + "\n")
for _, header := range signedHeaders {
if strings.ToLower(header) == "host" {

View File

@@ -0,0 +1,35 @@
package aksk
import (
"net/url"
"testing"
http_context "github.com/eolinker/apinto/node/http-context"
"github.com/valyala/fasthttp"
)
func TestAksk_Check(t *testing.T) {
req := fasthttp.AcquireRequest()
u := fasthttp.AcquireURI()
uri, _ := url.Parse("https://gateway.hr-soft.cn/api/redapi/tech/redteams/tag/tagUser?userId=8e211885-b622-11ec-8e03-14187749a8c0&tagId=37")
u.SetPath(uri.Path)
u.SetScheme(uri.Scheme)
u.SetHost(uri.Host)
u.SetQueryString(uri.RawQuery)
req.SetURI(u)
req.SetHostBytes(u.Host())
req.Header.Set("x-gateway-date", "20200605T104456Z")
req.Header.Set("content-type", "application/json")
req.Header.SetHostBytes(u.Host())
ctx := &fasthttp.RequestCtx{
Request: *req,
}
origin := buildToSign(http_context.NewContext(ctx, 9000), "HMAC-SHA256", []string{"content-type", "host", "x-gateway-date"})
t.Log("origin", origin)
sign := hMaxBySHA256("8f8154ff07f7153eea59a2ba44b5fcfe443dba1e4c45f87c549e6a05f699145d", origin)
if sign != "523a1d901873fbbc19df355dba6f8bb695a2ef3435206615e7724490054b0529" {
t.Fatalf("sign error %s", sign)
}
t.Logf("sign %s", sign)
}

View File

@@ -1,6 +1,7 @@
package websocket
import (
"crypto/tls"
"net/http"
"net/url"
"time"
@@ -14,6 +15,9 @@ import (
var dialer = &websocket.Dialer{
Proxy: http.ProxyFromEnvironment,
HandshakeTimeout: 45 * time.Second,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
var skipHeaders = []string{

View File

@@ -1,6 +1,7 @@
package fasthttp_client
import (
"context"
"crypto/tls"
"fmt"
"net"
@@ -22,7 +23,7 @@ func ProxyTimeout(scheme string, host string, node eocontext.INode, req *fasthtt
return err
}
var defaultClient Client
var defaultClient = NewClient()
const (
DefaultMaxConns = 10240
@@ -38,9 +39,21 @@ const (
//
// The fields of a Client should not be changed while it is in use.
type Client struct {
mLock sync.Mutex
mLock sync.RWMutex
m map[string]*fasthttp.HostClient
ms map[string]*fasthttp.HostClient
ctx context.Context
cancel context.CancelFunc
}
func NewClient() *Client {
ctx, cancel := context.WithCancel(context.Background())
return &Client{
m: make(map[string]*fasthttp.HostClient),
ms: make(map[string]*fasthttp.HostClient),
ctx: ctx,
cancel: cancel,
}
}
func readAddress(addr string) (scheme, host string) {
@@ -54,31 +67,31 @@ func (c *Client) getHostClient(addr string, rewriteHost string) (*fasthttp.HostC
scheme, nodeAddr := readAddress(addr)
host := nodeAddr
isTLS := false
if strings.EqualFold(scheme, "https") {
isTLS = true
host = fmt.Sprintf("%s-%s", rewriteHost, nodeAddr)
isTLS := strings.EqualFold(scheme, "https")
} else if !strings.EqualFold(scheme, "http") {
if !strings.EqualFold(scheme, "http") && !isTLS {
return nil, "", fmt.Errorf("unsupported protocol %q. http and https are supported", scheme)
}
startCleaner := false
c.mLock.Lock()
c.mLock.RLock()
m := c.m
if isTLS {
m = c.ms
}
if m == nil {
m = make(map[string]*fasthttp.HostClient)
if isTLS {
c.ms = m
} else {
c.m = m
}
}
hc := m[host]
c.mLock.RUnlock()
if hc != nil {
return hc, scheme, nil
}
c.mLock.Lock()
defer c.mLock.Unlock()
if isTLS {
m = c.ms
} else {
m = c.m
}
if hc == nil {
dial := Dial
dialAddr := addMissingPort(nodeAddr, isTLS)
@@ -109,14 +122,10 @@ func (c *Client) getHostClient(addr string, rewriteHost string) (*fasthttp.HostC
}
m[host] = hc
if len(m) == 1 {
startCleaner = true
go c.startCleaner(m)
}
}
c.mLock.Unlock()
if startCleaner {
go c.mCleaner(m)
}
return hc, scheme, nil
}
@@ -159,39 +168,42 @@ func (c *Client) ProxyTimeout(addr string, host string, req *fasthttp.Request, r
resp.SetConnectionClose()
}
}()
//var deadline time.Time
//var requestURI string
//redirectCount := 0
//for {
client, scheme, err := c.getHostClient(addr, host)
if err != nil {
return err
}
request.URI().SetScheme(scheme)
//if redirectCount == 0 {
// deadline = time.Now().Add(timeout)
//} else {
// request.SetRequestURI(requestURI)
//}
//log.Info("requestURI:", request.URI().String()+", host:", request.Host(), " body:", string(request.Body()))
return client.DoTimeout(req, resp, timeout)
//if err != nil {
// return err
//}
//if !fasthttp.StatusCodeIsRedirect(resp.StatusCode()) || redirectCount >= DefaultMaxRedirectCount {
// break
//}
//redirectCount++
//location := resp.Header.Peek("Location")
//if len(location) == 0 {
// return fasthttp.ErrMissingLocation
//}
//addr, requestURI = getRedirectURL(req.URI().String(), location)
//}
//return nil
}
func (c *Client) startCleaner(m map[string]*fasthttp.HostClient) {
sleep := time.Second * 10
mustStop := false
for {
select {
case <-c.ctx.Done():
return
case <-time.After(sleep):
c.mLock.Lock()
for k, v := range m {
if v.ConnsCount() == 0 {
v.CloseIdleConnections()
delete(m, k)
}
}
if len(m) == 0 {
mustStop = true
}
c.mLock.Unlock()
if mustStop {
return
}
}
}
}
func (c *Client) mCleaner(m map[string]*fasthttp.HostClient) {

View File

@@ -69,7 +69,7 @@ func (ur *URIRequest) GetQuery(key string) string {
}
func (ur *URIRequest) RawQuery() string {
return string(ur.uri.QueryArgs().String())
return ur.uri.QueryArgs().String()
}
func (ur *URIRequest) SetPath(s string) {