block / block/cachew

Range + If-Range support, end-to-end

Open
#332 0 comments 0 reactions 0 assignees View on GitHub
etag-range-followup
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.