mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-16 02:58:35 +02:00
Update S3-Conditional-Operations.md
1 parent
661df744c8
commit
867ebb3740
1 file changed
+68
-11
+68
-11
@@ -14,12 +14,49 @@ ring changes.
|
||||
|
||||
## Supported Conditional Headers
|
||||
|
||||
| Header | Applies To | Condition | Use Case |
|
||||
|--------|------------|-----------|----------|
|
||||
| **If-Match** | GET, PUT, COPY | ETag matches | Ensure object hasn't changed |
|
||||
| **If-None-Match** | GET, PUT, COPY | ETag doesn't match | Prevent overwrites, caching |
|
||||
| **If-Modified-Since** | GET, COPY | Modified after date | Conditional downloads |
|
||||
| **If-Unmodified-Since** | GET, PUT, COPY | Not modified after date | Safe modifications |
|
||||
These conditions act on the **target object** (the object being read or
|
||||
written). All four are supported on GET, HEAD, PUT, POST
|
||||
(`CompleteMultipartUpload`), and COPY. DELETE supports only `If-Match`.
|
||||
|
||||
| Header | Type | Applies to | Special values |
|
||||
|--------|------|------------|----------------|
|
||||
| `If-Match` | ETag | GET, HEAD, PUT, POST, COPY, **DELETE** | `*` matches any existing object; comma-separated ETag list is honored |
|
||||
| `If-None-Match` | ETag | GET, HEAD, PUT, POST, COPY | `*` matches only when the object does **not** exist (compare-and-create); comma-separated ETag list is honored |
|
||||
| `If-Modified-Since` | RFC 1123 date | GET, HEAD, PUT, POST, COPY | — |
|
||||
| `If-Unmodified-Since` | RFC 1123 date | GET, HEAD, PUT, POST, COPY | — |
|
||||
|
||||
### Copy-source conditionals
|
||||
|
||||
`CopyObject` and `UploadPartCopy` accept a second set of headers that
|
||||
condition on the **source** object. They are independent of the four
|
||||
standard headers above (which condition on the destination), so a single
|
||||
copy request can carry conditions for both ends.
|
||||
|
||||
| Header | Type |
|
||||
|--------|------|
|
||||
| `x-amz-copy-source-if-match` | ETag |
|
||||
| `x-amz-copy-source-if-none-match` | ETag |
|
||||
| `x-amz-copy-source-if-modified-since` | RFC 1123 date |
|
||||
| `x-amz-copy-source-if-unmodified-since` | RFC 1123 date |
|
||||
|
||||
### Evaluation order
|
||||
|
||||
Per [RFC 7232 §6](https://datatracker.ietf.org/doc/html/rfc7232#section-6)
|
||||
and AWS S3, the conditions are evaluated in this order; later conditions
|
||||
are skipped when an earlier one is present:
|
||||
|
||||
1. `If-Match`
|
||||
2. `If-Unmodified-Since` — ignored if `If-Match` is present
|
||||
([RFC 7232 §3.4](https://datatracker.ietf.org/doc/html/rfc7232#section-3.4))
|
||||
3. `If-None-Match`
|
||||
4. `If-Modified-Since` — ignored if `If-None-Match` is present
|
||||
([RFC 7232 §3.3](https://datatracker.ietf.org/doc/html/rfc7232#section-3.3))
|
||||
|
||||
### Not supported
|
||||
|
||||
* `If-Range`. A `Range` request without `If-Range` works normally; there is
|
||||
no header to fall back to a full-object response when the source has
|
||||
changed.
|
||||
|
||||
## HTTP Examples
|
||||
|
||||
@@ -78,15 +115,35 @@ curl -X PUT \
|
||||
-H "x-amz-copy-source: /source-bucket/source-file.txt" \
|
||||
-H "x-amz-copy-source-if-match: \"source-etag\"" \
|
||||
"http://localhost:8333/dest-bucket/dest-file.txt"
|
||||
|
||||
# Same copy, but also refuse to overwrite the destination
|
||||
curl -X PUT \
|
||||
-H "x-amz-copy-source: /source-bucket/source-file.txt" \
|
||||
-H "x-amz-copy-source-if-match: \"source-etag\"" \
|
||||
-H "If-None-Match: *" \
|
||||
"http://localhost:8333/dest-bucket/dest-file.txt"
|
||||
```
|
||||
|
||||
### Conditional DELETE
|
||||
|
||||
```bash
|
||||
# Delete only if the object's ETag still matches what we read
|
||||
curl -X DELETE \
|
||||
-H "If-Match: \"d41d8cd98f00b204e9800998ecf8427e\"" \
|
||||
"http://localhost:8333/mybucket/myfile.txt"
|
||||
```
|
||||
|
||||
DELETE supports `If-Match` only; the other three conditional headers are
|
||||
ignored on DELETE per the AWS S3 spec.
|
||||
|
||||
## HTTP Status Codes
|
||||
|
||||
| Status Code | Condition | Meaning |
|
||||
|-------------|-----------|---------|
|
||||
| **200 OK** | Condition met | Operation succeeded |
|
||||
| **304 Not Modified** | If-None-Match matched | Object unchanged (GET only) |
|
||||
| **412 Precondition Failed** | Condition not met | Operation blocked by condition |
|
||||
| Status Code | When | Meaning |
|
||||
|-------------|------|---------|
|
||||
| **200 OK** | All conditions met | Operation succeeded normally |
|
||||
| **304 Not Modified** | GET/HEAD with `If-None-Match` match, or `If-Modified-Since` not exceeded | Object unchanged; response carries the ETag header but no body |
|
||||
| **400 Invalid Request** | `If-Modified-Since` or `If-Unmodified-Since` is not a valid RFC 1123 date | Header is malformed |
|
||||
| **412 Precondition Failed** | Any other failed condition (all writes; GET/HEAD with `If-Match` mismatch or `If-Unmodified-Since` exceeded) | Operation blocked by condition |
|
||||
|
||||
## Atomicity and concurrency
|
||||
|
||||
|
||||
Reference in new issue
Block a user