parseRangeHeader function

List<ByteRange>? parseRangeHeader(
  1. String header
)

Parses header (e.g. bytes=0-499,1000-) into byte ranges, or null if the unit is not bytes or any range is malformed.

A range is malformed when it has no digits on either side, when both bounds are present but start > end, or when a number fails to parse. An empty range list (e.g. bytes=) is also null.

Example:

parseRangeHeader('bytes=0-499');  // [ByteRange(0, 499)]
parseRangeHeader('bytes=-500');   // [ByteRange(null, 500)] (last 500 bytes)
parseRangeHeader('bytes=500-');   // [ByteRange(500, null)] (offset 500 to end)
parseRangeHeader('items=0-1');    // null (unsupported unit)

Audited: 2026-06-12 11:26 EDT

Implementation

List<ByteRange>? parseRangeHeader(String header) {
  final int eq = header.indexOf('=');
  if (eq < 0) {
    return null;
  }
  // eq is an in-range index from indexOf, so both substrings below are bounded:
  // [0, eq) for the unit and [eq + 1, length) for the spec.
  // ignore: avoid_string_substring -- eq provably within length (indexOf + guard)
  final String unit = header.substring(0, eq).trim().toLowerCase();
  if (unit != 'bytes') {
    return null;
  }

  // ignore: avoid_string_substring -- eq + 1 <= length (eq is a valid index)
  final String spec = header.substring(eq + 1).trim();
  if (spec.isEmpty) {
    return null;
  }

  final List<ByteRange> ranges = <ByteRange>[];
  for (final String raw in spec.split(',')) {
    final ByteRange? range = _parseRange(raw.trim());
    if (range == null) {
      // One bad sub-range invalidates the whole header per RFC 7233.
      return null;
    }
    ranges.add(range);
  }
  return ranges.isEmpty ? null : ranges;
}