Feat: get source url in COS

pull/247/head
HFO4 4 years ago
parent dc32e85492
commit c34f211d7e

@ -15,6 +15,7 @@ require (
github.com/gin-gonic/gin v1.4.0
github.com/go-ini/ini v1.50.0
github.com/gomodule/redigo v2.0.0+incompatible
github.com/google/go-querystring v1.0.0
github.com/jinzhu/gorm v1.9.11
github.com/juju/ratelimit v1.0.1
github.com/mattn/go-colorable v0.1.4 // indirect

@ -12,8 +12,10 @@ import (
"github.com/HFO4/cloudreve/pkg/filesystem/fsctx"
"github.com/HFO4/cloudreve/pkg/filesystem/response"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/google/go-querystring/query"
cossdk "github.com/tencentyun/cos-go-sdk-v5"
"io"
"net/http"
"net/url"
"time"
)
@ -31,6 +33,11 @@ type MetaData struct {
CallbackURL string
}
type urlOption struct {
Speed int `url:"x-cos-traffic-limit,omitempty"`
ContentDescription string `url:"response-content-disposition,omitempty"`
}
// Driver 腾讯云COS适配器模板
type Driver struct {
Policy *model.Policy
@ -87,7 +94,67 @@ func (handler Driver) Source(
isDownload bool,
speed int,
) (string, error) {
return "", errors.New("未实现")
// 尝试从上下文获取文件名
fileName := ""
if file, ok := ctx.Value(fsctx.FileModelCtx).(model.File); ok {
fileName = file.Name
}
// 添加各项设置
options := urlOption{}
if speed > 0 {
if speed < 819200 {
speed = 819200
}
if speed > 838860800 {
speed = 838860800
}
options.Speed = speed
}
if isDownload {
options.ContentDescription = "attachment; filename=\"" + url.PathEscape(fileName) + "\""
}
return handler.signSourceURL(ctx, path, ttl, &options)
}
func (handler Driver) signSourceURL(ctx context.Context, path string, ttl int64, options *urlOption) (string, error) {
cdnURL, err := url.Parse(handler.Policy.BaseURL)
if err != nil {
return "", err
}
// 公有空间不需要签名
if !handler.Policy.IsPrivate {
file, err := url.Parse(path)
if err != nil {
return "", err
}
// 非签名URL不支持设置响应header
options.ContentDescription = ""
optionQuery, err := query.Values(*options)
if err != nil {
return "", err
}
file.RawQuery = optionQuery.Encode()
sourceURL := cdnURL.ResolveReference(file)
return sourceURL.String(), nil
}
presignedURL, err := handler.Client.Object.GetPresignedURL(ctx, http.MethodGet, path,
handler.Policy.AccessKey, handler.Policy.SecretKey, time.Duration(ttl)*time.Second, options)
if err != nil {
return "", err
}
// 将最终生成的签名URL域名换成用户自定义的加速域名如果有
presignedURL.Host = cdnURL.Host
presignedURL.Scheme = cdnURL.Scheme
return presignedURL.String(), nil
}
// Token 获取上传策略和认证Token

@ -388,7 +388,7 @@ func TestClient_UploadChunk(t *testing.T) {
ChunkSize: 10,
Total: 100,
Retried: 0,
Data: strings.NewReader("1231312"),
Data: []byte("12313121231312"),
})
clientMock.AssertExpectations(t)
asserts.NoError(err)
@ -418,7 +418,7 @@ func TestClient_UploadChunk(t *testing.T) {
ChunkSize: 10,
Total: 100,
Retried: 0,
Data: strings.NewReader("1231312"),
Data: []byte("12313112313122"),
})
clientMock.AssertExpectations(t)
asserts.Error(err)
@ -448,7 +448,7 @@ func TestClient_UploadChunk(t *testing.T) {
ChunkSize: 5,
Total: 100,
Retried: 0,
Data: strings.NewReader("1231312"),
Data: []byte("1231312"),
})
clientMock.AssertExpectations(t)
asserts.NoError(err)
@ -483,7 +483,7 @@ func TestClient_UploadChunk(t *testing.T) {
ChunkSize: 5,
Total: 100,
Retried: 0,
Data: strings.NewReader("1231312"),
Data: []byte("1231312"),
}
res, err := client.UploadChunk(context.Background(), "http://dev.com", chunk)
clientMock.AssertExpectations(t)

Loading…
Cancel
Save