From 4abd5b234671c5a3385b4b7a40eca7597c93de50 Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Sat, 25 Jan 2020 11:43:13 +0800 Subject: [PATCH] Feat: cos policy upload/download in server-side --- pkg/filesystem/driver/cos/handller.go | 43 ++++++++++++++++++++--- pkg/filesystem/driver/oss/handler_test.go | 13 +++++++ pkg/filesystem/driver/oss/handller.go | 19 ++++++---- pkg/filesystem/filesystem.go | 1 + 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/pkg/filesystem/driver/cos/handller.go b/pkg/filesystem/driver/cos/handller.go index 812b800..1445c14 100644 --- a/pkg/filesystem/driver/cos/handller.go +++ b/pkg/filesystem/driver/cos/handller.go @@ -11,6 +11,7 @@ import ( model "github.com/HFO4/cloudreve/models" "github.com/HFO4/cloudreve/pkg/filesystem/fsctx" "github.com/HFO4/cloudreve/pkg/filesystem/response" + "github.com/HFO4/cloudreve/pkg/request" "github.com/HFO4/cloudreve/pkg/serializer" "github.com/google/go-querystring/query" cossdk "github.com/tencentyun/cos-go-sdk-v5" @@ -40,18 +41,52 @@ type urlOption struct { // Driver 腾讯云COS适配器模板 type Driver struct { - Policy *model.Policy - Client *cossdk.Client + Policy *model.Policy + Client *cossdk.Client + HTTPClient request.Client } // Get 获取文件 func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { - return nil, errors.New("未实现") + // 获取文件源地址 + downloadURL, err := handler.Source( + ctx, + path, + url.URL{}, + int64(model.GetIntSetting("preview_timeout", 60)), + false, + 0, + ) + if err != nil { + return nil, err + } + + // 获取文件数据流 + resp, err := handler.HTTPClient.Request( + "GET", + downloadURL, + nil, + request.WithContext(ctx), + ).CheckHTTPResponse(200).GetRSCloser() + if err != nil { + return nil, err + } + + resp.SetFirstFakeChunk() + + // 尝试自主获取文件大小 + if file, ok := ctx.Value(fsctx.FileModelCtx).(model.File); ok { + resp.SetContentLength(int64(file.Size)) + } + + return resp, nil } // Put 将文件流保存到指定目录 func (handler Driver) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error { - return errors.New("未实现") + opt := &cossdk.ObjectPutOptions{} + _, err := handler.Client.Object.Put(ctx, dst, file, opt) + return err } // Delete 删除一个或多个文件, diff --git a/pkg/filesystem/driver/oss/handler_test.go b/pkg/filesystem/driver/oss/handler_test.go index 9d8e9d7..f379e28 100644 --- a/pkg/filesystem/driver/oss/handler_test.go +++ b/pkg/filesystem/driver/oss/handler_test.go @@ -79,6 +79,7 @@ func TestDriver_Source(t *testing.T) { SecretKey: "sk", BucketName: "test", Server: "test.com", + IsPrivate: true, }, } @@ -138,6 +139,18 @@ func TestDriver_Source(t *testing.T) { asserts.EqualValues("838860800", query.Get("x-oss-traffic-limit")) asserts.NotEmpty(query.Get("response-content-disposition")) } + + // 公共空间 + { + handler.Policy.IsPrivate = false + res, err := handler.Source(context.Background(), "/123", url.URL{}, 10, false, 0) + asserts.NoError(err) + resURL, err := url.Parse(res) + asserts.NoError(err) + query := resURL.Query() + asserts.Empty(query.Get("Signature")) + asserts.Empty(query.Get("Expires")) + } } func TestDriver_Thumb(t *testing.T) { diff --git a/pkg/filesystem/driver/oss/handller.go b/pkg/filesystem/driver/oss/handller.go index 5c51b62..b0f3ffe 100644 --- a/pkg/filesystem/driver/oss/handller.go +++ b/pkg/filesystem/driver/oss/handller.go @@ -236,10 +236,21 @@ func (handler Driver) Source( } func (handler Driver) signSourceURL(ctx context.Context, path string, ttl int64, options []oss.Option) (string, error) { - // 是否带有 Version ID - if _, ok := ctx.Value(VersionID).(int64); ok { + 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 + } + sourceURL := cdnURL.ResolveReference(file) + return sourceURL.String(), nil } + signedURL, err := handler.bucket.SignURL(path, oss.HTTPGet, ttl, options...) if err != nil { return "", err @@ -250,10 +261,6 @@ func (handler Driver) signSourceURL(ctx context.Context, path string, ttl int64, if err != nil { return "", err } - cdnURL, err := url.Parse(handler.Policy.BaseURL) - if err != nil { - return "", err - } finalURL.Host = cdnURL.Host finalURL.Scheme = cdnURL.Scheme diff --git a/pkg/filesystem/filesystem.go b/pkg/filesystem/filesystem.go index 12584a2..a9ceb3e 100644 --- a/pkg/filesystem/filesystem.go +++ b/pkg/filesystem/filesystem.go @@ -205,6 +205,7 @@ func (fs *FileSystem) DispatchHandler() error { SecretKey: currentPolicy.SecretKey, }, }), + HTTPClient: request.HTTPClient{}, } return nil default: