From 51d1e6f75b236153b3083594f4281848da980a8f Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 10 Nov 2016 07:41:02 -0800 Subject: [PATCH] Fix missing CompleteMultipartUpload Etag. (#3227) Fixes #3224 --- cmd/fs-v1-multipart.go | 2 +- cmd/object-api-multipart_test.go | 2 +- cmd/object-handlers.go | 4 +++- cmd/object-handlers_test.go | 2 +- cmd/object-utils.go | 2 +- cmd/object-utils_test.go | 2 +- cmd/server_test.go | 9 ++++++++- cmd/xl-v1-multipart.go | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/cmd/fs-v1-multipart.go b/cmd/fs-v1-multipart.go index 90c6caa4f..5523b3159 100644 --- a/cmd/fs-v1-multipart.go +++ b/cmd/fs-v1-multipart.go @@ -660,7 +660,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload defer appendPathLock.Unlock() // Calculate s3 compatible md5sum for complete multipart. - s3MD5, err := getCompleteMultipartMD5(parts...) + s3MD5, err := getCompleteMultipartMD5(parts) if err != nil { return "", err } diff --git a/cmd/object-api-multipart_test.go b/cmd/object-api-multipart_test.go index 29edf7a6d..ae11cf5cf 100644 --- a/cmd/object-api-multipart_test.go +++ b/cmd/object-api-multipart_test.go @@ -1864,7 +1864,7 @@ func testObjectCompleteMultipartUpload(obj ObjectLayer, instanceType string, t T }, }, } - s3MD5, err := getCompleteMultipartMD5(inputParts[3].parts...) + s3MD5, err := getCompleteMultipartMD5(inputParts[3].parts) if err != nil { t.Fatalf("Obtaining S3MD5 failed") } diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index f12466ae0..4e29b5739 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -877,7 +877,6 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite } md5Sum, err = objectAPI.CompleteMultipartUpload(bucket, object, uploadID, completeParts) - if err != nil { err = errorCause(err) errorIf(err, "Unable to complete multipart upload.") @@ -903,6 +902,9 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite return } + // Set etag. + w.Header().Set("ETag", "\""+md5Sum+"\"") + // Write success response. w.Write(encodedSuccessResponse) w.(http.Flusher).Flush() diff --git a/cmd/object-handlers_test.go b/cmd/object-handlers_test.go index 9e7837188..c9c241d52 100644 --- a/cmd/object-handlers_test.go +++ b/cmd/object-handlers_test.go @@ -1507,7 +1507,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s } // on successful complete multipart operation the s3MD5 for the parts uploaded will be returned. - s3MD5, err := getCompleteMultipartMD5(inputParts[3].parts...) + s3MD5, err := getCompleteMultipartMD5(inputParts[3].parts) if err != nil { t.Fatalf("Obtaining S3MD5 failed") } diff --git a/cmd/object-utils.go b/cmd/object-utils.go index d43ed80e3..24289cb27 100644 --- a/cmd/object-utils.go +++ b/cmd/object-utils.go @@ -141,7 +141,7 @@ func getUUID() (uuidStr string) { } // Create an s3 compatible MD5sum for complete multipart transaction. -func getCompleteMultipartMD5(parts ...completePart) (string, error) { +func getCompleteMultipartMD5(parts []completePart) (string, error) { var finalMD5Bytes []byte for _, part := range parts { md5Bytes, err := hex.DecodeString(part.ETag) diff --git a/cmd/object-utils_test.go b/cmd/object-utils_test.go index 3df4823fe..7f8c7998d 100644 --- a/cmd/object-utils_test.go +++ b/cmd/object-utils_test.go @@ -158,7 +158,7 @@ func TestGetCompleteMultipartMD5(t *testing.T) { } for i, test := range testCases { - result, err := getCompleteMultipartMD5(test.parts...) + result, err := getCompleteMultipartMD5(test.parts) if result != test.expectedResult { t.Fatalf("test %d failed: expected: result=%v, got=%v", i+1, test.expectedResult, result) } diff --git a/cmd/server_test.go b/cmd/server_test.go index e1d783bc3..2139ed0d4 100644 --- a/cmd/server_test.go +++ b/cmd/server_test.go @@ -2503,5 +2503,12 @@ func (s *TestSuiteCommon) TestObjectMultipart(c *C) { c.Assert(err, IsNil) // verify whether complete multipart was successful. c.Assert(response.StatusCode, Equals, http.StatusOK) - + var parts []completePart + for _, part := range completeUploads.Parts { + part.ETag = strings.Trim(part.ETag, "\"") + parts = append(parts, part) + } + etag, err := getCompleteMultipartMD5(parts) + c.Assert(err, IsNil) + c.Assert(strings.Trim(response.Header.Get("Etag"), "\""), Equals, etag) } diff --git a/cmd/xl-v1-multipart.go b/cmd/xl-v1-multipart.go index e9786ed9a..9ffb6aed3 100644 --- a/cmd/xl-v1-multipart.go +++ b/cmd/xl-v1-multipart.go @@ -664,7 +664,7 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload return "", traceError(InvalidUploadID{UploadID: uploadID}) } // Calculate s3 compatible md5sum for complete multipart. - s3MD5, err := getCompleteMultipartMD5(parts...) + s3MD5, err := getCompleteMultipartMD5(parts) if err != nil { return "", err }