fix(qiniu): cannot sign URL for file blob with `%` (#2463)

pull/2224/merge
Aaron Liu 2025-06-12 10:48:39 +08:00
parent e750cbfb77
commit 6561e3075f
2 changed files with 38 additions and 21 deletions

View File

@ -4,15 +4,17 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/driver" "github.com/cloudreve/Cloudreve/v4/pkg/filemanager/driver"
"github.com/cloudreve/Cloudreve/v4/pkg/mediameta" "github.com/cloudreve/Cloudreve/v4/pkg/mediameta"
"github.com/cloudreve/Cloudreve/v4/pkg/request" "github.com/cloudreve/Cloudreve/v4/pkg/request"
"github.com/samber/lo" "github.com/samber/lo"
"math"
"net/http"
"strconv"
"strings"
"time"
) )
const ( const (
@ -101,7 +103,9 @@ func (handler *Driver) extractImageMeta(ctx context.Context, path string) ([]dri
func (handler *Driver) extractMediaInfo(ctx context.Context, path string, param string) (string, error) { func (handler *Driver) extractMediaInfo(ctx context.Context, path string, param string) (string, error) {
mediaInfoExpire := time.Now().Add(mediaInfoTTL) mediaInfoExpire := time.Now().Add(mediaInfoTTL)
ediaInfoUrl := handler.signSourceURL(fmt.Sprintf("%s?%s", path, param), &mediaInfoExpire) ediaInfoUrl := handler.signSourceURL(path, url.Values{
param: []string{},
}, &mediaInfoExpire)
resp, err := handler.httpClient. resp, err := handler.httpClient.
Request(http.MethodGet, ediaInfoUrl, nil, request.WithContext(ctx)). Request(http.MethodGet, ediaInfoUrl, nil, request.WithContext(ctx)).
CheckHTTPResponse(http.StatusOK). CheckHTTPResponse(http.StatusOK).

View File

@ -274,10 +274,11 @@ func (handler *Driver) Delete(ctx context.Context, files ...string) ([]string, e
// Thumb 获取文件缩略图 // Thumb 获取文件缩略图
func (handler *Driver) Thumb(ctx context.Context, expire *time.Time, ext string, e fs.Entity) (string, error) { func (handler *Driver) Thumb(ctx context.Context, expire *time.Time, ext string, e fs.Entity) (string, error) {
w, h := handler.settings.ThumbSize(ctx) w, h := handler.settings.ThumbSize(ctx)
thumb := fmt.Sprintf("%s?imageView2/1/w/%d/h/%d", e.Source(), w, h)
return handler.signSourceURL( return handler.signSourceURL(
thumb, e.Source(),
url.Values{
fmt.Sprintf("imageView2/1/w/%d/h/%d", w, h): []string{},
},
expire, expire,
), nil ), nil
} }
@ -307,24 +308,36 @@ func (handler *Driver) Source(ctx context.Context, e fs.Entity, args *driver.Get
query.Add(trafficLimitParam, fmt.Sprintf("%d", args.Speed)) query.Add(trafficLimitParam, fmt.Sprintf("%d", args.Speed))
} }
if len(query) > 0 {
path = path + "?" + query.Encode()
}
// 取得原始文件地址 // 取得原始文件地址
return handler.signSourceURL(path, args.Expire), nil return handler.signSourceURL(path, query, args.Expire), nil
} }
func (handler *Driver) signSourceURL(path string, expire *time.Time) string { func (handler *Driver) signSourceURL(path string, query url.Values, expire *time.Time) string {
var sourceURL string var sourceURL string
if handler.policy.IsPrivate { deadline := time.Now().Add(time.Duration(24) * time.Hour * 365 * 20).Unix()
deadline := time.Now().Add(time.Duration(24) * time.Hour * 365 * 20).Unix() if expire != nil {
if expire != nil { deadline = expire.Unix()
deadline = expire.Unix() }
// If only one query key with empty value, use RawQuery
firstKey := ""
for key := range query {
firstKey = key
break
}
if len(query) == 1 && query.Get(firstKey) == "" {
if handler.policy.IsPrivate {
sourceURL = storage.MakePrivateURLv2WithQueryString(handler.mac, handler.policy.Settings.ProxyServer, path, firstKey, deadline)
} else {
sourceURL = storage.MakePublicURLv2WithQueryString(handler.policy.Settings.ProxyServer, path, firstKey)
} }
sourceURL = storage.MakePrivateURL(handler.mac, handler.policy.Settings.ProxyServer, path, deadline)
} else { } else {
sourceURL = storage.MakePublicURL(handler.policy.Settings.ProxyServer, path) if handler.policy.IsPrivate {
sourceURL = storage.MakePrivateURLv2WithQuery(handler.mac, handler.policy.Settings.ProxyServer, path, query, deadline)
} else {
sourceURL = storage.MakePublicURLv2WithQuery(handler.policy.Settings.ProxyServer, path, query)
}
} }
return sourceURL return sourceURL
} }