From 56b7df90e105eaa7246fa40a89d154b37e70b61f Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sun, 8 May 2016 02:21:12 -0700 Subject: [PATCH] xl/fs: ListObjectParts should set nextPartNumberMarker properly. (#1528) For list requests on parts more than 1000, would lead to an infinite loop. Fixes #1522 --- fs-objects-multipart.go | 2 +- object-common-multipart.go | 16 +++++++++++----- object-utils.go | 2 +- xl-objects-multipart.go | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/fs-objects-multipart.go b/fs-objects-multipart.go index 9db9175aa..e073f4832 100644 --- a/fs-objects-multipart.go +++ b/fs-objects-multipart.go @@ -118,7 +118,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload } // Save the s3 md5. - s3MD5, err := makeS3MD5(md5Sums...) + s3MD5, err := completeMultipartMD5(md5Sums...) if err != nil { return "", err } diff --git a/object-common-multipart.go b/object-common-multipart.go index e5be1143c..4f85512a1 100644 --- a/object-common-multipart.go +++ b/object-common-multipart.go @@ -495,8 +495,7 @@ func listMultipartUploadsCommon(layer ObjectLayer, bucket, prefix, keyMarker, up return result, nil } -// ListObjectParts - list object parts, common function across both -// object layers. +// ListObjectParts - list object parts, common function across both object layers. func listObjectPartsCommon(storage StorageAPI, bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, error) { // Verify if bucket is valid. if !IsValidBucketName(bucket) { @@ -527,15 +526,17 @@ func listObjectPartsCommon(storage StorageAPI, bucket, object, uploadID string, count := maxParts for _, entry := range newEntries { fi, err := storage.StatFile(minioMetaBucket, path.Join(mpartMetaPrefix, bucket, object, uploadID, entry)) - splitEntry := strings.Split(entry, ".") - partNum, err := strconv.Atoi(splitEntry[0]) + splitEntry := strings.SplitN(entry, ".", 2) + partStr := splitEntry[0] + etagStr := splitEntry[1] + partNum, err := strconv.Atoi(partStr) if err != nil { return ListPartsInfo{}, err } result.Parts = append(result.Parts, partInfo{ PartNumber: partNum, LastModified: fi.ModTime, - ETag: splitEntry[1], + ETag: etagStr, Size: fi.Size, }) count-- @@ -543,8 +544,13 @@ func listObjectPartsCommon(storage StorageAPI, bucket, object, uploadID string, break } } + // If listed entries are more than maxParts, we set IsTruncated as true. if len(newEntries) > len(result.Parts) { result.IsTruncated = true + // Make sure to fill next part number marker if IsTruncated is + // true for subsequent listing. + nextPartNumberMarker := result.Parts[len(result.Parts)-1].PartNumber + result.NextPartNumberMarker = nextPartNumberMarker } result.Bucket = bucket result.Object = object diff --git a/object-utils.go b/object-utils.go index 3d8548fad..cced1f4b8 100644 --- a/object-utils.go +++ b/object-utils.go @@ -109,7 +109,7 @@ func pathJoin(s1 string, s2 string) string { } // Create an s3 compatible MD5sum for complete multipart transaction. -func makeS3MD5(md5Strs ...string) (string, error) { +func completeMultipartMD5(md5Strs ...string) (string, error) { var finalMD5Bytes []byte for _, md5Str := range md5Strs { md5Bytes, err := hex.DecodeString(md5Str) diff --git a/xl-objects-multipart.go b/xl-objects-multipart.go index 54fe979a5..7e2458268 100644 --- a/xl-objects-multipart.go +++ b/xl-objects-multipart.go @@ -141,7 +141,7 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload } // Calculate and save s3 compatible md5sum. - s3MD5, err := makeS3MD5(md5Sums...) + s3MD5, err := completeMultipartMD5(md5Sums...) if err != nil { return "", err }