fix(serve-static): correct Range header parsing edge cases#372
Conversation
- `bytes=-N` (suffix range) now returns the last N bytes instead of the first N+1 bytes. - `bytes=0-0` now returns 1 byte instead of the whole file (the old `parseInt(...) || size - 1` treated a valid 0 as falsy). - An unsatisfiable range (start beyond EOF, or start > end) now returns 416 instead of crashing createReadStream with a RangeError.
|
Thank you for creating the PR. I think this is a great way to implement it! I have two concerns: Malformed rangesNow that range parsing has been extracted into its own helper, I think Empty filesFor an empty file, |
…rash - Range segments with trailing garbage (e.g. `bytes=0-1x`) were silently truncated by parseInt into `0-1` instead of being treated as malformed. first-pos/last-pos/suffix-length are now validated as `1*DIGIT`. - A Range request on an empty file fell through to createReadStream with end=-1 and crashed with 500 instead of returning 416. Addresses review feedback from @usualoma on honojs#372.
|
@usualoma Could you review this again? |
|
Hi @otnc, Thank you for the update! I believe the functionality is now implemented correctly. Sorry to ask for one more thing, but I would prefer to merge this after a small refactor. I opened otnc#1 with a proposal. Could you please review it and merge it if it looks good to you? The main points are:
I could also merge this PR first and handle the refactoring separately, but I wanted to share the proposal in advance because I thought you might prefer to see it before this PR is merged. Apologies if this was unnecessary. |
refactor(serve-static): separate range parsing and resolution
|
Hi @usualoma ! |
|
Hi @otnc, |
serveStatic'sRangeparsing had three edge cases that didn't match RFC 9110:bytes=-N(suffix range) returned the first N+1 bytes instead of the last N.bytes=0-0returned the whole file instead of 1 byte (parseInt(...) || size - 1treated a valid0as falsy).bytes=100-200on a 17-byte file) crashedcreateReadStreamwithRangeErrorinstead of returning 416.Replaced the ad-hoc parsing with a
parseRange()helper that handles all three correctly while keeping the existing behavior for malformed headers (e.g.Range: hellostill serves the whole file, per the existing test).Added tests for each case; all existing tests still pass unchanged.