Skip to content

feat(services/s3): support source-side conditional copy#7614

Open
YuangGao wants to merge 6 commits into
apache:mainfrom
YuangGao:feat/s3-copy-with-source-if-match
Open

feat(services/s3): support source-side conditional copy#7614
YuangGao wants to merge 6 commits into
apache:mainfrom
YuangGao:feat/s3-copy-with-source-if-match

Conversation

@YuangGao
Copy link
Copy Markdown
Contributor

@YuangGao YuangGao commented May 25, 2026

Which issue does this PR close?

Closes #7090.

Rationale for this change

Destination-side If-Match protects the destination from being overwritten. Source-side x-amz-copy-source-if-* is the other half: it lets callers gate a copy on the source object's state, closing the race between stat(src) and copy(src, dst).

S3 CopyObject accepts four source-side conditions, mirroring the standard HTTP conditional set already exposed on OpStat / OpRead:

  • x-amz-copy-source-if-match (ETag)
  • x-amz-copy-source-if-none-match (ETag)
  • x-amz-copy-source-if-modified-since (HTTP-date)
  • x-amz-copy-source-if-unmodified-since (HTTP-date)

What changes are included in this PR?

Core:

  • Add Capability::copy_with_source_if_{match,none_match,modified_since,unmodified_since}.
  • Add the four matching fields to OpCopy / CopyOptions, builders on FutureCopy. ETag fields use Option<String>, time fields use Option<Timestamp> (same type already used by OpStat / OpRead).
  • Add the four matching checks in correctness_check.rs and the capability-check layer.

S3:

  • Set the four new capability flags to true on the S3 capability.
  • s3_copy_object and s3_complete_multipart_copy inject the four x-amz-copy-source-if-* headers when set.

Tests:

  • test_copy_with_source_if_match_match / _mismatch and the symmetric test_copy_with_source_if_none_match_* pair in core/tests/behavior/async_copy.rs. Time-based conditions share the same plumbing and are covered by the capability + correctness checks.

Are there any user-facing changes?

Yes, additive only — op.copy_with(from, to).source_if_match(etag) (and the three siblings) are new opt-in builders. Existing op.copy(from, to) is unchanged.

AI Usage Statement

AI-assisted implementation.

@YuangGao YuangGao marked this pull request as ready for review May 25, 2026 02:50
@YuangGao YuangGao requested a review from Xuanwo as a code owner May 25, 2026 02:50
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. releases-note/feat The PR implements a new feature or has a title that begins with "feat" labels May 25, 2026
Comment thread core/core/src/types/options.rs
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels May 25, 2026
@YuangGao YuangGao changed the title feat(services/s3): support source-side If-Match on copy feat(services/s3): support source-side conditional copy May 25, 2026
@asukaminato0721 asukaminato0721 requested a review from dentiny May 26, 2026 10:13
@asukaminato0721 asukaminato0721 enabled auto-merge (squash) May 26, 2026 10:13
auto-merge was automatically disabled May 29, 2026 00:38

Head branch was pushed to by a user without write access

@dentiny
Copy link
Copy Markdown
Member

dentiny commented Jun 1, 2026

Hi @YuangGao , I'm wondering if you could fix the CI? Ping me when ready, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

releases-note/feat The PR implements a new feature or has a title that begins with "feat" size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

new feature: s3 conditional copy & delete

2 participants