Content-Range Header Builder and Parser
Format and parse Content-Range response headers for byte ranges, validating start, end and total values in both directions.
Code
export interface ContentRange {
unit: "bytes";
start: number;
end: number;
total: number | "*";
}
export function formatContentRange(range: ContentRange): string {
if (range.unit !== "bytes") {
throw new RangeError("only the bytes unit is supported");
}
if (!Number.isInteger(range.start) || range.start < 0) {
throw new RangeError("start must be a non-negative integer");
}
if (!Number.isInteger(range.end) || range.end < range.start) {
throw new RangeError("end must be an integer not less than start");
}
if (
range.total !== "*" &&
(!Number.isInteger(range.total) || range.total <= range.end)
) {
throw new RangeError("total must be * or an integer greater than end");
}
return "bytes " + range.start + "-" + range.end + "/" + range.total;
}
export function parseContentRange(value: string): ContentRange {
if (typeof value !== "string") throw new TypeError("value must be a string");
const match = /^bytes (\d+)-(\d+)\/(\d+|\*)$/.exec(value.trim());
if (!match) throw new RangeError("invalid Content-Range header");
const start = Number(match[1]);
const end = Number(match[2]);
const total = match[3] === "*" ? "*" : Number(match[3]);
const range: ContentRange = { unit: "bytes", start, end, total };
formatContentRange(range);
return range;
}Report a problem with this exampleOpens a pre-filled issue on GitHub.