feat(static): add byte-range request support - #275
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughStatic file serving now supports configurable single-byte ChangesStatic byte-range handling
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/static.ts`:
- Around line 370-371: Update the range-header detection near rangeHeader and
the parseRange() function to accept case-insensitive “bytes” units and optional
whitespace after the equals sign, including values such as “Bytes=” and “bytes=
0-4”. Normalize the unit and trim permitted optional whitespace before parsing,
while preserving partial-content handling for valid ranges.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fc87c279-3f5f-4d60-a62f-e0d2ee28644b
📒 Files selected for processing (2)
src/static.tstest/static.test.ts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e's grammar Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/static.ts`:
- Around line 396-399: Update the Range header detection near rangeRequest
initialization in src/static.ts lines 396-399 to accept case-insensitive “bytes”
units and optional spaces or tabs after “=”, while preserving the existing
header fallback behavior. Also update the range parsing regex in src/static.ts
lines 731-738 to accept the same case variations and optional whitespace so
extracted boundaries remain correct.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
Adds single-range
Range: bytes=support toserveStatic, behind a newrangesoption (defaulttrue).Behavior
206 Partial Contentfor a single-range GET:Content-Range: bytes <start>-<end>/<size>, part-lengthContent-Length, body streamed from the fd withcreateReadStream({ start, end }). Validators,Cache-Control, andVarycarry over from the 200.bytes=range request bypasses content negotiation — no precompressed variant, no on-the-fly compression. Range consumers (media seek, download resumption) target already-compressed types, and a range over chunked on-the-fly output is not expressible. A non-bytesunit is treated as no Range header at all.If-None-Match/If-Modified-Sincestill evaluate first, so a304outranks a range.If-Rangeis honored: the entity-tag form never matches (our ETags are weak and the comparison must be strong — clients fall back to a full 200), the date form matches on exact-second equality withLast-Modified.416withContent-Range: bytes */<size>when nothing is satisfiable (start past EOF,bytes=-0, any range on an empty file). Malformed and multi-range headers are ignored per RFC §14.2 and answered with the full 200.Accept-Ranges: bytesadvertised on identity (non-encoded) responses; omitted on encoded responses and entirely whenranges: false.Also rewords the
computeETagcomment whose "this middleware does not answer byte-range requests" rationale is now stale.Tests
18 new tests in
test/static.test.ts: basic/open-ended/suffix/clamped ranges, multi-range and malformed fallbacks, both 416 shapes, all threeIf-Rangeforms, HEAD ignoring Range, identity-only ranges on compressible files (on-the-fly and disk-variant paths), 304-beats-Range,ranges: false, andAccept-Rangespresence/absence.vitest run test/static.test.ts test/static-nonblock.test.ts: 160/160 passing.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Range: bytes=...) support for static files with correct206 Partial ContentContent-Rangeand length handling.Accept-Ranges: bytesfor eligible identity200responses.ranges?: booleanoption to enable/disable range handling (default enabled).Bug Fixes
If-Rangematching semantics and fallbacks: malformed/multi-range/non-matching cases serve full200; unsatisfiable ranges return416withContent-Range: bytes */<length>.HEADignoresRange, and range responses avoid content negotiation/compressed variants.Tests
If-Range, and disabled-range behavior.