From d8ae111fa5ca30977eff9a32d2d090655f9a9e42 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sun, 16 Nov 2025 16:35:39 -0800 Subject: [PATCH] refactor --- weed/s3api/filer_multipart.go | 102 +++++++++++----------------------- 1 file changed, 33 insertions(+), 69 deletions(-) diff --git a/weed/s3api/filer_multipart.go b/weed/s3api/filer_multipart.go index 5a1bc2e5e..2ccc52b5c 100644 --- a/weed/s3api/filer_multipart.go +++ b/weed/s3api/filer_multipart.go @@ -118,6 +118,36 @@ type CompleteMultipartUploadResult struct { VersionId *string `xml:"-"` } +// copySSEHeadersFromFirstPart copies all SSE-related headers from the first part to the destination entry +// This is critical for detectPrimarySSEType to work correctly and ensures encryption metadata is preserved +func copySSEHeadersFromFirstPart(dst *filer_pb.Entry, firstPart *filer_pb.Entry, context string) { + if firstPart == nil || firstPart.Extended == nil { + return + } + + // Copy ALL SSE-related headers (not just SeaweedFSSSEKMSKey) + sseKeys := []string{ + // SSE-C headers + s3_constants.SeaweedFSSSEIV, + s3_constants.AmzServerSideEncryptionCustomerAlgorithm, + s3_constants.AmzServerSideEncryptionCustomerKeyMD5, + // SSE-KMS headers + s3_constants.SeaweedFSSSEKMSKey, + s3_constants.AmzServerSideEncryptionAwsKmsKeyId, + // SSE-S3 headers + s3_constants.SeaweedFSSSES3Key, + // Common SSE header (for SSE-KMS and SSE-S3) + s3_constants.AmzServerSideEncryption, + } + + for _, key := range sseKeys { + if value, exists := firstPart.Extended[key]; exists { + dst.Extended[key] = value + glog.V(4).Infof("completeMultipartUpload: copied SSE header %s from first part (%s)", key, context) + } + } +} + func (s3a *S3ApiServer) completeMultipartUpload(r *http.Request, input *s3.CompleteMultipartUploadInput, parts *CompleteMultipartUpload) (output *CompleteMultipartUploadResult, code s3err.ErrorCode) { glog.V(2).Infof("completeMultipartUpload input %v", input) @@ -321,29 +351,7 @@ func (s3a *S3ApiServer) completeMultipartUpload(r *http.Request, input *s3.Compl // SSE metadata is stored in individual parts, not the upload directory if len(completedPartNumbers) > 0 && len(partEntries[completedPartNumbers[0]]) > 0 { firstPartEntry := partEntries[completedPartNumbers[0]][0] - if firstPartEntry.Extended != nil { - // Copy ALL SSE-related headers (not just SeaweedFSSSEKMSKey) - // This is critical for detectPrimarySSEType to work correctly - sseKeys := []string{ - // SSE-C headers - s3_constants.SeaweedFSSSEIV, - s3_constants.AmzServerSideEncryptionCustomerAlgorithm, - s3_constants.AmzServerSideEncryptionCustomerKeyMD5, - // SSE-KMS headers - s3_constants.SeaweedFSSSEKMSKey, - s3_constants.AmzServerSideEncryptionAwsKmsKeyId, - // SSE-S3 headers - s3_constants.SeaweedFSSSES3Key, - // Common SSE header (for SSE-KMS and SSE-S3) - s3_constants.AmzServerSideEncryption, - } - for _, key := range sseKeys { - if value, exists := firstPartEntry.Extended[key]; exists { - versionEntry.Extended[key] = value - glog.V(4).Infof("completeMultipartUpload: copied SSE header %s from first part (versioned)", key) - } - } - } + copySSEHeadersFromFirstPart(versionEntry, firstPartEntry, "versioned") } if pentry.Attributes.Mime != "" { versionEntry.Attributes.Mime = pentry.Attributes.Mime @@ -402,29 +410,7 @@ func (s3a *S3ApiServer) completeMultipartUpload(r *http.Request, input *s3.Compl // SSE metadata is stored in individual parts, not the upload directory if len(completedPartNumbers) > 0 && len(partEntries[completedPartNumbers[0]]) > 0 { firstPartEntry := partEntries[completedPartNumbers[0]][0] - if firstPartEntry.Extended != nil { - // Copy ALL SSE-related headers (not just SeaweedFSSSEKMSKey) - // This is critical for detectPrimarySSEType to work correctly - sseKeys := []string{ - // SSE-C headers - s3_constants.SeaweedFSSSEIV, - s3_constants.AmzServerSideEncryptionCustomerAlgorithm, - s3_constants.AmzServerSideEncryptionCustomerKeyMD5, - // SSE-KMS headers - s3_constants.SeaweedFSSSEKMSKey, - s3_constants.AmzServerSideEncryptionAwsKmsKeyId, - // SSE-S3 headers - s3_constants.SeaweedFSSSES3Key, - // Common SSE header (for SSE-KMS and SSE-S3) - s3_constants.AmzServerSideEncryption, - } - for _, key := range sseKeys { - if value, exists := firstPartEntry.Extended[key]; exists { - entry.Extended[key] = value - glog.V(4).Infof("completeMultipartUpload: copied SSE header %s from first part (suspended versioning)", key) - } - } - } + copySSEHeadersFromFirstPart(entry, firstPartEntry, "suspended versioning") } if pentry.Attributes.Mime != "" { entry.Attributes.Mime = pentry.Attributes.Mime @@ -473,29 +459,7 @@ func (s3a *S3ApiServer) completeMultipartUpload(r *http.Request, input *s3.Compl // SSE metadata is stored in individual parts, not the upload directory if len(completedPartNumbers) > 0 && len(partEntries[completedPartNumbers[0]]) > 0 { firstPartEntry := partEntries[completedPartNumbers[0]][0] - if firstPartEntry.Extended != nil { - // Copy ALL SSE-related headers (not just SeaweedFSSSEKMSKey) - // This is critical for detectPrimarySSEType to work correctly - sseKeys := []string{ - // SSE-C headers - s3_constants.SeaweedFSSSEIV, - s3_constants.AmzServerSideEncryptionCustomerAlgorithm, - s3_constants.AmzServerSideEncryptionCustomerKeyMD5, - // SSE-KMS headers - s3_constants.SeaweedFSSSEKMSKey, - s3_constants.AmzServerSideEncryptionAwsKmsKeyId, - // SSE-S3 headers - s3_constants.SeaweedFSSSES3Key, - // Common SSE header (for SSE-KMS and SSE-S3) - s3_constants.AmzServerSideEncryption, - } - for _, key := range sseKeys { - if value, exists := firstPartEntry.Extended[key]; exists { - entry.Extended[key] = value - glog.V(4).Infof("completeMultipartUpload: copied SSE header %s from first part (non-versioned)", key) - } - } - } + copySSEHeadersFromFirstPart(entry, firstPartEntry, "non-versioned") } if pentry.Attributes.Mime != "" { entry.Attributes.Mime = pentry.Attributes.Mime