Skip to content

Support suffix byte ranges and stop masking upstream 416s as 404s - #4

Merged
fangpenlin merged 2 commits into
mainfrom
cursor/suffix-ranges-and-upstream-416-cc15
Aug 28, 2026
Merged

fangpenlin merged 2 commits into
mainfrom
cursor/suffix-ranges-and-upstream-416-cc15

Conversation

@fangpenlin

@fangpenlin fangpenlin commented Aug 27, 2026 •

Copy link
Copy Markdown

Port of the two range-handling follow-ups from cloudflare/serverless-registry#147 onto this fork's main. Core range forwarding is already here (PR #1 + d0d3838); these two edge cases were not.

Suffix ranges (bytes=-<n>)

Range: bytes=-1024 is the RFC 9110 suffix form asking for the last 1024 bytes. The parser required at least one digit before the dash, so this valid form was treated as malformed and silently downgraded to a full 200 response.

BlobRangeRequest is now a union of an offset range and a suffix range. The R2 backend resolves the suffix against the object size, and RegistryHTTPClient forwards it upstream verbatim as bytes=-<n>. Per RFC 9110, a suffix longer than the object is satisfied by the whole object, while a zero-length suffix is unsatisfiable and returns 416.

Upstream 416 reported as 404

When a blob is not cached in R2, the handler falls back to the configured upstream registries. The loop treated every upstream error as a miss and continued, so an upstream 416 was discarded and the request bottomed out at a synthetic 404 BLOB_UNKNOWN.

That told the client the blob does not exist, when it does, and dropped the Content-Range: bytes */<size> header carrying the size the client needs in order to retry. An upstream 416 is now returned directly, matching how a 416 from the primary R2 store is already handled. Other failures still fall through to the next registry.

Testing

New tests, all driven through the worker or the real HTTP client:

  • suffix range returns the last bytes as 206, oversized suffix returns the whole object, bytes=-0 returns 416, and bytes=- still serves the full object
  • an uncached blob whose upstream answers 416 reaches the client as 416 with its Content-Range intact
  • a non-416 upstream failure still falls through to a second registry
  • RegistryHTTPClient forwards { suffix: 4 } as Range: bytes=-4 and surfaces the partial content

Verified against main's production code (tests from this branch, source from main): suffix range returns 200 instead of 206, and an upstream 416 is reported as 404. After the port both assertions pass.

pnpm typecheck, pnpm lint and pnpm format:check all pass. The 7 new tests plus the existing blob-range suite pass. The full suite is 71 passed / 2 failed; both failures are the pre-existing background layer caching tests exceeding the default 5s vitest timeout, which reproduce on unmodified main.

This supersedes draft PR #3, which has the same two commits on an older agent branch.

Open in Web Open in Cursor 

cursoragent and others added 2 commits August 27, 2026 22:43
Clients may resume or probe a blob with the RFC 9110 suffix form
'Range: bytes=-<n>', asking for the last n bytes. That form was parsed
as malformed and silently downgraded to a full 200 response.

Model BlobRangeRequest as a union of an offset range and a suffix range,
resolve suffixes against the object size in the R2 backend, and forward
them upstream verbatim. A suffix longer than the object is satisfied by
the whole object, while a zero-length suffix is unsatisfiable.

Co-authored-by: Fang-Pen Lin <hello@fangpenlin.com>
When a blob is not cached in R2, the blob GET handler falls back to the
configured upstream registries. Any error from an upstream was treated
as a miss, so an unsatisfiable range reached the client as a synthetic
404 BLOB_UNKNOWN, telling it the blob does not exist and discarding the
Content-Range that carries the real object size.

Report a 416 from an upstream directly, matching how a 416 from the
primary R2 store is already handled. Other failures keep falling through
to the next registry.

Co-authored-by: Fang-Pen Lin <hello@fangpenlin.com>
@fangpenlin
fangpenlin marked this pull request as ready for review August 27, 2026 22:45
@fangpenlin
fangpenlin merged commit 61f06d6 into main Aug 28, 2026
@fangpenlin
fangpenlin deleted the cursor/suffix-ranges-and-upstream-416-cc15 branch August 28, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants