From f88c7e37ee5dc6275ca1eb66e8d50bc13f073dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jergu=C5=A1=20Lejko?= Date: Wed, 4 Mar 2026 22:03:53 +0100 Subject: [PATCH 1/2] WIP --- src/aws/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/aws/mod.rs b/src/aws/mod.rs index 7eefad31..8abed2c2 100644 --- a/src/aws/mod.rs +++ b/src/aws/mod.rs @@ -183,7 +183,7 @@ impl ObjectStore for AmazonS3 { (PutMode::Overwrite, _) => request.idempotent(true).do_put().await, (PutMode::Create, S3ConditionalPut::Disabled) => Err(Error::NotImplemented), (PutMode::Create, S3ConditionalPut::ETagMatch) => { - match request.header(&IF_NONE_MATCH, "*").do_put().await { + match request.header(&IF_NONE_MATCH, "*").idempotent(true).do_put().await { // Technically If-None-Match should return NotModified but some stores, // such as R2, instead return PreconditionFailed // https://developers.cloudflare.com/r2/api/s3/extensions/#conditional-operations-in-putobject @@ -205,6 +205,10 @@ impl ObjectStore for AmazonS3 { S3ConditionalPut::ETagMatch => { match request .header(&IF_MATCH, etag.as_str()) + // Conditional PUTs with If-Match are idempotent: + // if the first attempt succeeds and changes the + // ETag, retries will fail with PreconditionFailed. + .idempotent(true) // Real S3 will occasionally report 409 Conflict // if there are concurrent `If-Match` requests // in flight, so we need to be prepared to retry From 10522c57a91c948ebc01341cc4b3d3948beec316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jergu=C5=A1=20Lejko?= Date: Wed, 4 Mar 2026 22:14:05 +0100 Subject: [PATCH 2/2] WIP --- src/aws/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/aws/mod.rs b/src/aws/mod.rs index 8abed2c2..5785d955 100644 --- a/src/aws/mod.rs +++ b/src/aws/mod.rs @@ -183,7 +183,13 @@ impl ObjectStore for AmazonS3 { (PutMode::Overwrite, _) => request.idempotent(true).do_put().await, (PutMode::Create, S3ConditionalPut::Disabled) => Err(Error::NotImplemented), (PutMode::Create, S3ConditionalPut::ETagMatch) => { - match request.header(&IF_NONE_MATCH, "*").idempotent(true).do_put().await { + match request + .header(&IF_NONE_MATCH, "*") + // Conditional put with If-None-Match is idempotent. + .idempotent(true) + .do_put() + .await + { // Technically If-None-Match should return NotModified but some stores, // such as R2, instead return PreconditionFailed // https://developers.cloudflare.com/r2/api/s3/extensions/#conditional-operations-in-putobject @@ -205,9 +211,7 @@ impl ObjectStore for AmazonS3 { S3ConditionalPut::ETagMatch => { match request .header(&IF_MATCH, etag.as_str()) - // Conditional PUTs with If-Match are idempotent: - // if the first attempt succeeds and changes the - // ETag, retries will fail with PreconditionFailed. + // Conditional PUTs with If-Match are idempotent. .idempotent(true) // Real S3 will occasionally report 409 Conflict // if there are concurrent `If-Match` requests