You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(s3frontend): S3 surface — HEAD Range/Expires, ?partNumber, default checksum
- HEAD honors Range (206/Content-Range, 416 on unsatisfiable); carry the Expires header
- GET/HEAD by ?partNumber=N (part byte-span + x-amz-mp-parts-count)
- server-computed default CRC64NVME checksum when the client names none
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
re-checked at commit), additional checksums (`x-amz-checksum-*` validate + echo), `DeleteObjects`,
755
+
re-checked at commit), additional checksums (`x-amz-checksum-*` validate + echo, with a
756
+
server-computed full-object `CRC64NVME` default when the client names none — S3's
757
+
default-checksum-on-store), `DeleteObjects`,
754
758
metadata-only `CopyObject`, multipart (`Create`/`UploadPart`/`Complete`/`Abort` with the
755
-
single-winner latch and the `-N` ETag), zero-byte objects.
759
+
single-winner latch and the `-N` ETag), zero-byte objects. Ranged reads return `206`/`Content-Range`
760
+
on **both** `GetObject` and `HeadObject` (`416` on an unsatisfiable range); the system headers
761
+
carried through PUT and replayed on GET/HEAD include `Content-Encoding`/`Disposition`/`Language`,
762
+
`Cache-Control`, and the `Expires` caching header. GET/HEAD also accept `?partNumber=N`: a completed
763
+
multipart object records each part's byte length on the manifest (`Body.PartSizes`), so part `N`
764
+
resolves to its byte span (`206` + `Content-Range` + `x-amz-mp-parts-count`); a single-PUT object
765
+
exposes the whole body as part 1 (no parts-count), and `N` past the part count is `416`.
756
766
757
767
### Deferred by deliberate scope decision
758
768
@@ -774,6 +784,15 @@ These are intentional simplifications of the target topology, not bugs:
774
784
are recorded in a local Postgres `blob_locations` table behind a `Locator` seam, rather than read
775
785
back through the indexing-service ([§5](#5-the-data-layer), [§8](#8-retrieval-addressing-when-bodies-need-a-sharded-dag-index)). The indexer-backed `Locator` is an `indexer-ready` swap-in.
776
786
787
+
### Object lifecycle (not implemented)
788
+
789
+
The `Expires` HTTP header *is* implemented — it is a passthrough caching header (RFC 7234) stored on
790
+
the manifest and replayed on GET/HEAD, not a lifecycle control. True S3 **Lifecycle** management
791
+
(`PutBucketLifecycleConfiguration` expiration/transition rules that actually delete or tier objects
792
+
after N days, surfaced via the `x-amz-expiration` response header) is a separate, unimplemented
793
+
feature. It would be its own subsystem — a per-bucket rule store plus a background sweeper driving the
794
+
reference index — and is out of scope for this iteration.
795
+
777
796
### Deferred as forge-mode glue (validated live in smelt, not the in-process harness)
778
797
779
798
The in-memory harness uses a no-op uploader and serves reads from the spool, so these forge-network
0 commit comments