pub fn parse_range(range: &str, size: u64) -> Result<(u64, u64), ()>Expand description
Parses an HTTP Range header into absolute byte offsets.
Implements a subset of HTTP range request syntax (RFC 7233), supporting only simple byte ranges without multi-part or suffix ranges.
§Supported Syntax
- Bounded range:
bytes=<start>-<end>(both offsets specified)- Example:
bytes=0-1023→ Returns(0, 1023)
- Example:
- Unbounded range:
bytes=<start>-(from start to EOF)- Example:
bytes=1024-→ Returns(1024, size-1)
- Example:
§Unsupported Syntax
- Suffix range:
bytes=-<length>(last N bytes)- Example:
bytes=-1024→ ReturnsErr(())
- Example:
- Multi-part range:
bytes=0-100,200-300- Example:
bytes=0-100,200-300→ ReturnsErr(())
- Example:
These are rejected because:
- They are rarely used in practice (<1% of range requests)
- They add significant parsing and response generation complexity
- The HTTP 416 error response is acceptable for clients that need them
§Arguments
range: The value of theRangeheader (e.g.,"bytes=0-1023")size: The total size of the stream in bytes (used to validate offsets)
§Returns
Ok((start, end)): Valid range with absolute byte offsets (both inclusive)Err(()): Invalid syntax or out-of-bounds range
§Error Conditions
Returns Err(()) if:
- Missing prefix: Header does not start with
"bytes="- Example:
"items=0-100"→ Error
- Example:
- Invalid integer: Start or end cannot be parsed as
u64- Example:
"bytes=abc-def"→ Error
- Example:
- Inverted range: Start offset is greater than end offset
- Example:
"bytes=1000-500"→ Error
- Example:
- Out of bounds: End offset is beyond the stream size
- Example:
"bytes=0-999999"when size is 1000 → Error
- Example:
§Parsing Algorithm
1. Check for "bytes=" prefix (RANGE_PREFIX_LEN = 6)
2. Split remaining string on '-' delimiter
3. Parse start offset (parts[0])
4. Parse end offset (parts[1] if present and non-empty, else size-1)
5. Validate: start <= end && end < size
6. Return (start, end)§Edge Cases
§Empty String After Prefix
Range: bytes=Returns Err(()) because there is no start offset.
§Single Byte Range
Range: bytes=0-0Returns Ok((0, 0)) (valid, requests exactly 1 byte).
§Range at EOF
Range: bytes=0-999 (size = 1000)Returns Ok((0, 999)) (valid, end is inclusive and equals size - 1).
§Range Beyond EOF
Range: bytes=0-1000 (size = 1000)Returns Err(()) because offset 1000 does not exist (valid range is 0-999).
§Examples
parse_range("bytes=0-1023", 10000) -> Ok((0, 1023))
parse_range("bytes=1024-", 10000) -> Ok((1024, 9999))
parse_range("0-1023", 10000) -> Err(()) // missing "bytes=" prefix
parse_range("bytes=0-10000", 10000) -> Err(()) // out of bounds
parse_range("bytes=1000-500", 10000)-> Err(()) // inverted range§Performance
- Time complexity: O(n) where n is the length of the range string (typically <20 chars)
- Allocation: One heap allocation for the
split('-')iterator’s internal state - Typical latency: <1 μs (negligible compared to snapshot read latency)
§Security
This function is resilient to malicious input:
- Integer overflow:
u64::parserejects values >2^64-1 - Unbounded length: The
Rangeheader is bounded by HTTP header size limits (typically 8 KB, enforced by the HTTP server) - No allocation attacks: Uses only one small allocation for splitting