diff --git a/rest/client.go b/rest/client.go index 5a4835b..0d45b71 100644 --- a/rest/client.go +++ b/rest/client.go @@ -185,8 +185,6 @@ func (c *Client) chain() http.RoundTripper { // mergeURL return the merged url with common header and params func (c *Client) mergeURL(u *url.URL) (*url.URL, error) { - query := make(url.Values) - if c.baseURL != nil { if u.Host != "" || u.Scheme != "" { return nil, fmt.Errorf("baseURL and request url host/schema can not be set at the same time") @@ -195,13 +193,21 @@ func (c *Client) mergeURL(u *url.URL) (*url.URL, error) { u.Scheme = c.baseURL.Scheme u.Host = c.baseURL.Host u.Path = path.Join(c.baseURL.Path, u.Path) - maps.Copy(query, c.baseURL.Query()) } - // change the url query - maps.Copy(query, c.commonQueryParams) - maps.Copy(query, u.Query()) - u.RawQuery = query.Encode() + // 收集 baseURL 和 commonQueryParams 中的额外查询参数, + // 仅当存在额外参数时才合并并重编码,保留原始 RawQuery 中的特殊字符不被误编码 + extra := make(url.Values) + if c.baseURL != nil { + maps.Copy(extra, c.baseURL.Query()) + } + maps.Copy(extra, c.commonQueryParams) + + if len(extra) > 0 { + query := u.Query() + maps.Copy(query, extra) + u.RawQuery = query.Encode() + } return u, nil } @@ -383,11 +389,13 @@ func (r *Request[T]) getURL(u string) (string, error) { return "", err } - // change the url query - query := newURL.Query() - maps.Copy(query, r.queryParams) - - newURL.RawQuery = query.Encode() + // 仅当有额外查询参数时才重编码,避免 url.Values.Encode() 将原始 RawQuery 中 + // 合法的特殊字符(如 CDN 签名令牌里的 '=')误编码为 %3D 导致服务端拒绝请求 + if len(r.queryParams) > 0 { + query := newURL.Query() + maps.Copy(query, r.queryParams) + newURL.RawQuery = query.Encode() + } return newURL.String(), nil }