From e699287ffdc49bf0c5df4c65d2b464103e79e2bc Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Sun, 28 Feb 2021 16:48:51 +0800 Subject: [PATCH] Modify: mark as success when deleting a file that does not exist; Fix: minio is not usable in S3 policy Modify: use batch request to delete S3 files --- assets | 2 +- pkg/filesystem/driver/local/handler.go | 13 +++-- pkg/filesystem/driver/onedrive/api.go | 2 +- pkg/filesystem/driver/qiniu/handler.go | 2 +- pkg/filesystem/driver/s3/handler.go | 74 ++++++++++---------------- 5 files changed, 39 insertions(+), 54 deletions(-) diff --git a/assets b/assets index 92f6981..d626a4d 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 92f6981cb363046327deadd70d03015fd11deeb6 +Subproject commit d626a4d9ccd48ecc3f3508962752771774297f94 diff --git a/pkg/filesystem/driver/local/handler.go b/pkg/filesystem/driver/local/handler.go index 633150a..96e7b90 100644 --- a/pkg/filesystem/driver/local/handler.go +++ b/pkg/filesystem/driver/local/handler.go @@ -130,11 +130,14 @@ func (handler Driver) Delete(ctx context.Context, files []string) ([]string, err var retErr error for _, value := range files { - err := os.Remove(util.RelativePath(filepath.FromSlash(value))) - if err != nil { - util.Log().Warning("无法删除文件,%s", err) - retErr = err - deleteFailed = append(deleteFailed, value) + filePath := util.RelativePath(filepath.FromSlash(value)) + if util.Exists(filePath) { + err := os.Remove(filePath) + if err != nil { + util.Log().Warning("无法删除文件,%s", err) + retErr = err + deleteFailed = append(deleteFailed, value) + } } // 尝试删除文件的缩略图(如果有) diff --git a/pkg/filesystem/driver/onedrive/api.go b/pkg/filesystem/driver/onedrive/api.go index b791bbf..01cbf9f 100644 --- a/pkg/filesystem/driver/onedrive/api.go +++ b/pkg/filesystem/driver/onedrive/api.go @@ -370,7 +370,7 @@ func (client *Client) Delete(ctx context.Context, dst []string) ([]string, error func getDeleteFailed(res *BatchResponses) []string { var failed = make([]string, 0, len(res.Responses)) for _, v := range res.Responses { - if v.Status != 204 { + if v.Status != 204 && v.Status != 404 { failed = append(failed, v.ID) } } diff --git a/pkg/filesystem/driver/qiniu/handler.go b/pkg/filesystem/driver/qiniu/handler.go index d1b86b8..824c04c 100644 --- a/pkg/filesystem/driver/qiniu/handler.go +++ b/pkg/filesystem/driver/qiniu/handler.go @@ -206,7 +206,7 @@ func (handler Driver) Delete(ctx context.Context, files []string) ([]string, err if err != nil { failed := make([]string, 0, len(rets)) for k, ret := range rets { - if ret.Code != 200 { + if ret.Code != 200 && ret.Code != 612 { failed = append(failed, files[k]) } } diff --git a/pkg/filesystem/driver/s3/handler.go b/pkg/filesystem/driver/s3/handler.go index 4a4a079..b338d8f 100644 --- a/pkg/filesystem/driver/s3/handler.go +++ b/pkg/filesystem/driver/s3/handler.go @@ -8,13 +8,13 @@ import ( "encoding/hex" "encoding/json" "errors" + "github.com/cloudreve/Cloudreve/v3/pkg/util" "io" "net/http" "net/url" "path" "path/filepath" "strings" - "sync" "time" "github.com/aws/aws-sdk-go/aws" @@ -60,7 +60,7 @@ func (handler *Driver) InitS3Client() error { Credentials: credentials.NewStaticCredentials(handler.Policy.AccessKey, handler.Policy.SecretKey, ""), Endpoint: &handler.Policy.Server, Region: &handler.Policy.OptionsSerialized.Region, - S3ForcePathStyle: aws.Bool(false), + S3ForcePathStyle: aws.Bool(true), }) if err != nil { @@ -229,53 +229,35 @@ func (handler Driver) Delete(ctx context.Context, files []string) ([]string, err return files, err } - var ( - failed = make([]string, 0, len(files)) - lastErr error - currentIndex = 0 - indexLock sync.Mutex - failedLock sync.Mutex - wg sync.WaitGroup - routineNum = 4 - ) - wg.Add(routineNum) + failed := make([]string, 0, len(files)) + deleted := make([]string, 0, len(files)) - // S3不支持批量操作,这里开四个协程并行操作 - for i := 0; i < routineNum; i++ { - go func() { - for { - // 取得待删除文件 - indexLock.Lock() - if currentIndex >= len(files) { - // 所有文件处理完成 - wg.Done() - indexLock.Unlock() - return - } - path := files[currentIndex] - currentIndex++ - indexLock.Unlock() - - // 发送异步删除请求 - _, err := handler.svc.DeleteObject( - &s3.DeleteObjectInput{ - Bucket: &handler.Policy.BucketName, - Key: &path, - }) - - // 处理错误 - if err != nil { - failedLock.Lock() - lastErr = err - failed = append(failed, path) - failedLock.Unlock() - } - } - }() + keys := make([]*s3.ObjectIdentifier, 0, len(files)) + for _, file := range files { + filePath := file + keys = append(keys, &s3.ObjectIdentifier{Key: &filePath}) } - wg.Wait() - return failed, lastErr + // 发送异步删除请求 + res, err := handler.svc.DeleteObjects( + &s3.DeleteObjectsInput{ + Bucket: &handler.Policy.BucketName, + Delete: &s3.Delete{ + Objects: keys, + }, + }) + + if err != nil { + return files, err + } + + // 统计未删除的文件 + for _, deleteRes := range res.Deleted { + deleted = append(deleted, *deleteRes.Key) + } + failed = util.SliceDifference(failed, deleted) + + return failed, nil }