Range + If-Range support, end-to-end
- Dominant language
- Go
- Stars
- 41
- Forks
- 12
- PR merge metrics
- No merged PRs in 30d
Description
Follow-up from the ETag support assessment (label: etag-range-followup).
The strong content-hash ETag is already a suitable, tier-stable `If-Range` validator (a range continuation served from a different tier/pod validates correctly; a changed object correctly forces a full `200`). The validator value is fine; the surrounding machinery is entirely missing.
### Current gaps
- `apiv1.getObject` (`internal/strategy/apiv1.go`) does `io.Copy(w, cr)` — always `200`, never honours `Range`, never sets `Accept-Ranges`, never returns `206`/`Content-Range`/`416`.
- The `cache.Cache` interface (`internal/cache/api.go`) only exposes a whole-object `Open` returning an `io.ReadCloser`; there is no partial-read / seek capability. Only the disk backend reader happens to be seekable.
- `checkConditionals` does not evaluate `If-Range`.
### Work
- Add a partial-read capability to the cache interface — either a range-aware open (offset + length) or a documented seekable-reader contract — and implement it for `disk`, `memory`, `s3` (S3 already does parallel range GETs internally, see `s3_parallel_get.go`), `tiered`, and `remote`.
- Implement server-side range handling in `apiv1.getObject`: parse `Range`, emit `Accept-Ranges: bytes`, return `206` with `Content-Range` for satisfiable ranges and `416` for unsatisfiable ones.
- Evaluate `If-Range` (against the strong ETag; fall back to full `200` when the validator does not match) before serving a partial response.
- Plumb `Range`/`If-Range` through the client (`client/`) and remote backend as needed so a tiered remote tier can serve ranges.
### Acceptance
Ranged GET against each backend returns the correct bytes with `206`/`Content-Range`; `If-Range` with a stale ETag returns the full object with `200`; unsatisfiable ranges return `416`.
Contributor guide
Research direction
Start with internal/strategy/apiv1.go and internal/cache/api.go, then inspect s3_parallel_get.go and the disk, memory, tiered, and remote backends to understand the existing read paths. Trace the client/ and remote plumbing for Range and If-Range handling. Done means each backend returns correct ranged bytes with 206 and Content-Range, stale If-Range returns 200, and unsatisfiable ranges return 416.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100