fix: multipart replication and encrypted etag for sse-s3 (#13171)

Replication was not working properly for encrypted
objects in single PUT object for preserving etag,

We need to make sure to preserve etag such that replication
works properly and not gets into infinite loops of copying
due to ETag mismatches.
This commit is contained in:
Harshavardhana
2021-09-08 22:25:23 -07:00
committed by GitHub
parent 9af4e7b1da
commit 0892f1e406
10 changed files with 30 additions and 54 deletions

View File

@@ -3046,8 +3046,10 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
// Complete parts.
completeParts := make([]CompletePart, 0, len(complMultipartUpload.Parts))
originalCompleteParts := make([]CompletePart, 0, len(complMultipartUpload.Parts))
for _, part := range complMultipartUpload.Parts {
part.ETag = canonicalizeETag(part.ETag)
originalCompleteParts = append(originalCompleteParts, part)
if isEncrypted {
// ETag is stored in the backend in encrypted form. Validate client sent ETag with
// decrypted ETag.
@@ -3063,6 +3065,9 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
completeParts = append(completeParts, part)
}
// Calculate s3 compatible md5sum for complete multipart.
s3MD5 := getCompleteMultipartMD5(originalCompleteParts)
completeMultiPartUpload := objectAPI.CompleteMultipartUpload
// This code is specifically to handle the requirements for slow
@@ -3104,6 +3109,11 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
return
}
// preserve ETag if set, or set from parts.
if _, ok := opts.UserDefined["etag"]; !ok {
opts.UserDefined["etag"] = s3MD5
}
w = &whiteSpaceWriter{ResponseWriter: w, Flusher: w.(http.Flusher)}
completeDoneCh := sendWhiteSpace(w)
objInfo, err := completeMultiPartUpload(ctx, bucket, object, uploadID, completeParts, opts)