aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api/filer_multipart.go
diff options
context:
space:
mode:
authorchrislu <chris.lu@gmail.com>2022-03-23 01:05:14 -0700
committerchrislu <chris.lu@gmail.com>2022-03-23 01:05:14 -0700
commite48764be75d285fe7edfbd88ca7ff419580c48d1 (patch)
tree9a4c5553a1179de27983a910d1bc47b4eec4c9a5 /weed/s3api/filer_multipart.go
parent18ae8943ef599a1cbadfad9598653dc28db01d1f (diff)
downloadseaweedfs-e48764be75d285fe7edfbd88ca7ff419580c48d1.tar.xz
seaweedfs-e48764be75d285fe7edfbd88ca7ff419580c48d1.zip
s3: multipart upload verifies uploaded parts
Diffstat (limited to 'weed/s3api/filer_multipart.go')
-rw-r--r--weed/s3api/filer_multipart.go30
1 files changed, 26 insertions, 4 deletions
diff --git a/weed/s3api/filer_multipart.go b/weed/s3api/filer_multipart.go
index 1514e2aa8..5a039382b 100644
--- a/weed/s3api/filer_multipart.go
+++ b/weed/s3api/filer_multipart.go
@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
"path/filepath"
+ "sort"
"strconv"
"strings"
"time"
@@ -62,10 +63,15 @@ type CompleteMultipartUploadResult struct {
s3.CompleteMultipartUploadOutput
}
-func (s3a *S3ApiServer) completeMultipartUpload(input *s3.CompleteMultipartUploadInput) (output *CompleteMultipartUploadResult, code s3err.ErrorCode) {
+func (s3a *S3ApiServer) completeMultipartUpload(input *s3.CompleteMultipartUploadInput, parts *CompleteMultipartUpload) (output *CompleteMultipartUploadResult, code s3err.ErrorCode) {
glog.V(2).Infof("completeMultipartUpload input %v", input)
+ completedParts := parts.Parts
+ sort.Slice(completedParts, func(i, j int) bool {
+ return completedParts[i].PartNumber < completedParts[j].PartNumber
+ })
+
uploadDirectory := s3a.genUploadsFolder(*input.Bucket) + "/" + *input.UploadId
entries, _, err := s3a.list(uploadDirectory, "", "", false, maxPartsList)
@@ -80,14 +86,16 @@ func (s3a *S3ApiServer) completeMultipartUpload(input *s3.CompleteMultipartUploa
return nil, s3err.ErrNoSuchUpload
}
+ mime := pentry.Attributes.Mime
+
var finalParts []*filer_pb.FileChunk
var offset int64
- var mime string
for _, entry := range entries {
if strings.HasSuffix(entry.Name, ".part") && !entry.IsDirectory {
- if entry.Name == "0001.part" && entry.Attributes.Mime != "" {
- mime = entry.Attributes.Mime
+ _, found := findByPartNumber(entry.Name, completedParts)
+ if !found {
+ continue
}
for _, chunk := range entry.Chunks {
p := &filer_pb.FileChunk{
@@ -156,6 +164,20 @@ func (s3a *S3ApiServer) completeMultipartUpload(input *s3.CompleteMultipartUploa
return
}
+func findByPartNumber(fileName string, parts []CompletedPart) (etag string, found bool) {
+ partNumber, formatErr := strconv.Atoi(fileName[:4])
+ if formatErr != nil {
+ return
+ }
+ x := sort.Search(len(parts), func(i int) bool {
+ return parts[i].PartNumber >= partNumber
+ })
+ if parts[x].PartNumber != partNumber {
+ return
+ }
+ return parts[x].ETag, true
+}
+
func (s3a *S3ApiServer) abortMultipartUpload(input *s3.AbortMultipartUploadInput) (output *s3.AbortMultipartUploadOutput, code s3err.ErrorCode) {
glog.V(2).Infof("abortMultipartUpload input %v", input)