rustfs icon indicating copy to clipboard operation
rustfs copied to clipboard

Add support for `If-None-Match` header (ETag-based conditional GET)

Open sunfkny opened this issue 1 month ago • 13 comments

Is your feature request related to a problem? Please describe. Currently, RustFS does not support the If-None-Match HTTP header for conditional GET requests. This prevents clients from efficiently checking if an object has changed, resulting in unnecessary downloads and wasted bandwidth.

Describe the solution you'd like Add support for the If-None-Match header so that RustFS can respond with 304 Not Modified when the object's ETag matches. This would improve caching efficiency and compatibility with S3 clients that rely on ETag validation.

Describe alternatives you've considered There is no practical alternative: conditional GET based on ETag requires server-side support.

Additional context https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html#API_GetObject_RequestSyntax

sunfkny avatar Nov 05 '25 02:11 sunfkny

Your suggestion is fantastic!

Let's see how to implement this feature.

loverustfs avatar Nov 05 '25 03:11 loverustfs

s3s has parsed If-None-Match header into the input struct. This feature needs implementation on rustfs side.

Nugine avatar Nov 15 '25 14:11 Nugine

Hey @sunfkny ,

This feature is now implemented. Could you share your test plan or the cases you'll be using for verification?

https://github.com/rustfs/rustfs/pull/885

loverustfs avatar Nov 18 '25 08:11 loverustfs

@loverustfs

There is a bug in ETag comparison: info.etag is unquoted (Some("440747666b49289943af5176aab06a47")) while if_none_match is wrapped in quotes (Some("\"440747666b49289943af5176aab06a47\"")). This causes requests that should return 304 Not Modified to return 200 OK.

https://github.com/rustfs/rustfs/blob/494fe7d71e3218c43a4753153ce823de4ba87a4f/rustfs/src/storage/ecfs.rs#L1673-L1677

Test plan

  1. Create a public bucket (e.g., test-bucket) and upload a file (e.g., README.md) to it.

  2. Save the ETag of the file.

    curl --etag-save etag.txt -LsSf http://localhost:9000/test-bucket/README.md -o /dev/null
    
  3. Get object again with the ETag. Check http status code, it should be 304.

    curl --etag-compare etag.txt -LsSf http://localhost:9000/test-bucket/README.md -w 'status code: %{http_code}' -v -o /dev/null
    

sunfkny avatar Nov 19 '25 02:11 sunfkny

Milvus startup exception: panic: CheckIfConditionWriteSupport failed: PutObjectIfNoneMatch not supported or failed. BucketName: milvus, ObjectKey: files/wp/conditional_write_test_object, Error: The specified key does not exist.

it seems "If-None-Match" returns PreconditionFailed, causing milvus to fail to start, in put_object and complete_multipart_upload。

halfpreschooler avatar Dec 05 '25 16:12 halfpreschooler

#1034

shiroleeee avatar Dec 07 '25 05:12 shiroleeee

Fixed.

https://github.com/rustfs/rustfs/pull/1034

loverustfs avatar Dec 08 '25 07:12 loverustfs

#1034

Doesn't it need to be modified in complete_multipart_upload?

halfpreschooler avatar Dec 08 '25 10:12 halfpreschooler

#1034

Doesn't it need to be modified in complete_multipart_upload?

@shiroleeee

loverustfs avatar Dec 08 '25 11:12 loverustfs

#1034

Doesn't it need to be modified in complete_multipart_upload?

Hey @halfpreschooler ,

Thank you very much.

https://github.com/rustfs/rustfs/pull/1065

Fixed.

loverustfs avatar Dec 08 '25 11:12 loverustfs

Hey @halfpreschooler @sunfkny ,

This bug has been fixed in the latest release. I'm closing this issue for now.

https://github.com/rustfs/rustfs/releases/tag/1.0.0-alpha.73

If the problem persists, please leave a comment and we'll reopen it.

loverustfs avatar Dec 11 '25 03:12 loverustfs

Hey @halfpreschooler @sunfkny ,

This bug has been fixed in the latest release. I'm closing this issue for now.

https://github.com/rustfs/rustfs/releases/tag/1.0.0-alpha.73

If the problem persists, please leave a comment and we'll reopen it.

@loverustfs

Thanks for the update. This issue https://github.com/rustfs/rustfs/issues/791#issuecomment-3550337057 has not been resolved yet.

The underlying fix https://github.com/s3s-project/s3s/pull/403 was made in s3s and has already been merged and released in v0.12.0-rc.5. ETag is now strongly typed, and once RustFS upgrades to this version, the type system will prevent incorrect ETag comparisons and ensure correct conditional request behavior.

Edit: FYI, in PR #1008, get_object was refactored, but this effectively removed the precondition check logic. The intention was to move the checks to precondition_check, but get_object does not actually call get_object_info, which includes the precondition checks.

sunfkny avatar Dec 11 '25 05:12 sunfkny

Ok, reopened.

loverustfs avatar Dec 11 '25 06:12 loverustfs

Hey @sunfkny ,

Thank you for using RustFS.

This bug has been fixed. Please upgrade to the latest version, alpha.75: https://github.com/rustfs/rustfs/releases/tag/1.0.0-alpha.75

Please verify that this resolves the issue. If the problem persists, please leave a comment below and we will reopen this issue.

loverustfs avatar Dec 19 '25 06:12 loverustfs