mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-30 05:30:23 +00:00
* fix(s3): honor MetadataDirective=REPLACE for system metadata on CopyObject * fix(s3): match copy metadata keys case-insensitively for legacy data Legacy / non-S3 write paths (FUSE mount, direct filer HTTP API, older versions) may persist Cache-Control etc. in lowercase form. Make isManagedCopyMetadataKey case-insensitive so mergeCopyMetadata still clears stale source values under REPLACE, and let the COPY branch of processMetadataBytes fall back to a lowercase key on the source so legacy values survive into the destination (re-emitted as canonical). Mirrors the existing x-amz-meta-* backward-compat path. * fix(s3): keep legacy non-canonical tag and system metadata across COPY The previous case-insensitive isManagedCopyMetadataKey caused mergeCopyMetadata to delete legacy lowercase x-amz-tagging-* and mixed-case system headers, but the COPY branch in processMetadataBytes only matched canonical or strict-lowercase keys when re-populating them, so any non-canonical key was permanently dropped on COPY. - COPY now scans existing in a single pass and uses strings.EqualFold against the system header whitelist, re-emitting under the canonical header name. Handles any case folding (CACHE-CONTROL, Cache-control, etc.), not just strings.ToLower. - COPY tagging branch now uses hasPrefixFold(k, AmzObjectTagging) and re-emits the canonical X-Amz-Tagging-<suffix>, mirroring the existing X-Amz-Meta-* migration path. - Tests cover lowercase/uppercase/mixed-case system headers and tags surviving COPY. * fix(s3): make COPY of system metadata and tags deterministic across case variants Single-pass EqualFold matching let Go's randomized map iteration pick either the canonical or a legacy-cased value when both lived on the source, so the COPY result varied between calls. Both COPY branches now use two passes: a canonical-exact lookup first, then a case-insensitive fallback that only writes when the canonical slot is still empty. Mirrors the collision-check pattern used by the X-Amz-Meta-* migration path. Tests run the canonical-vs-legacy collision 32 times each to exercise varied map orders. * fix(s3): apply REPLACE Content-Type on in-place copy The metadata-only self-copy path never set Attributes.Mime, so a same-key CopyObject with REPLACE and a new Content-Type silently kept the old type. Route in place only when the Mime is unchanged; otherwise take the locked clone path (still metadata-only, reuses source chunks) and set the new Mime there. Also covers the versioned self-copy path. * perf(s3): drop per-key ToLower in isManagedCopyMetadataKey Use the allocation-free hasPrefixFold helper instead of lowercasing the key and both constant prefixes on every metadata-key check. --------- Co-authored-by: Chris Lu <chris.lu@gmail.com>