From 7700ec0b59f404cf69c94e9e474990225c832de6 Mon Sep 17 00:00:00 2001 From: chrislu Date: Mon, 17 Nov 2025 01:55:47 -0800 Subject: [PATCH] ensures PUT and GET operations return consistent ETags --- weed/s3api/s3api_object_handlers_copy.go | 2 +- weed/s3api/s3api_object_handlers_put.go | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/weed/s3api/s3api_object_handlers_copy.go b/weed/s3api/s3api_object_handlers_copy.go index 885b71ac0..53fbf547c 100644 --- a/weed/s3api/s3api_object_handlers_copy.go +++ b/weed/s3api/s3api_object_handlers_copy.go @@ -84,7 +84,7 @@ func (s3a *S3ApiServer) CopyObjectHandler(w http.ResponseWriter, r *http.Request return } writeSuccessResponseXML(w, r, CopyObjectResult{ - ETag: fmt.Sprintf("%x", entry.Attributes.Md5), + ETag: filer.ETag(entry), LastModified: time.Now().UTC(), }) return diff --git a/weed/s3api/s3api_object_handlers_put.go b/weed/s3api/s3api_object_handlers_put.go index 2d5a14d4a..c9c30558f 100644 --- a/weed/s3api/s3api_object_handlers_put.go +++ b/weed/s3api/s3api_object_handlers_put.go @@ -16,6 +16,7 @@ import ( "time" "github.com/pquerna/cachecontrol/cacheobject" + "github.com/seaweedfs/seaweedfs/weed/filer" "github.com/seaweedfs/seaweedfs/weed/glog" "github.com/seaweedfs/seaweedfs/weed/operation" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" @@ -372,12 +373,11 @@ func (s3a *S3ApiServer) putToFiler(r *http.Request, uploadUrl string, dataReader return "", s3err.ErrInternalError, SSEResponseMetadata{} } - // Step 3: Calculate ETag and add SSE metadata to chunks + // Step 3: Calculate MD5 hash and add SSE metadata to chunks md5Sum := chunkResult.Md5Hash.Sum(nil) - etag = fmt.Sprintf("%x", md5Sum) - glog.Infof("putToFiler: Chunked upload SUCCESS - path=%s, chunks=%d, size=%d, etag=%s", - filePath, len(chunkResult.FileChunks), chunkResult.TotalSize, etag) + glog.Infof("putToFiler: Chunked upload SUCCESS - path=%s, chunks=%d, size=%d", + filePath, len(chunkResult.FileChunks), chunkResult.TotalSize) // Log chunk details for debugging for i, chunk := range chunkResult.FileChunks { @@ -456,6 +456,12 @@ func (s3a *S3ApiServer) putToFiler(r *http.Request, uploadUrl string, dataReader entry.Attributes.Md5 = md5Sum } + // Calculate ETag using the same logic as GET to ensure consistency + // For single chunk: uses entry.Attributes.Md5 + // For multiple chunks: uses filer.ETagChunks() which returns "-" + etag = filer.ETag(entry) + glog.Infof("putToFiler: Calculated ETag=%s for %d chunks", etag, len(chunkResult.FileChunks)) + // Set object owner amzAccountId := r.Header.Get(s3_constants.AmzAccountId) if amzAccountId != "" {