@helia/verified-fetch
Version:
A fetch-like API for obtaining verified & trustless IPFS content on the web
69 lines • 2.18 kB
JavaScript
import { InvalidRangeError } from "../errors.js";
import { badRequestResponse, notSatisfiableResponse } from "./responses.js";
function parseValue(val) {
if (val == null || val === '') {
return;
}
const num = Number(val);
if (isNaN(num)) {
throw new InvalidRangeError(`Invalid range specification: could not parse "${num}" as number`);
}
return num;
}
function getByteRangeFromHeader(rangeHeader) {
if (rangeHeader == null || rangeHeader === '') {
return [];
}
/**
* Range: bytes=<start>-<end> | bytes=<start2>- | bytes=-<end2> | bytes=<start1>-<end1>,<start2>-<end2>,...
*/
if (!rangeHeader.startsWith('bytes=')) {
throw new InvalidRangeError('Invalid range request');
}
const rangesStr = rangeHeader.substring(6); // Remove "bytes=" prefix
const rangeParts = rangesStr.split(',').map(part => part.trim());
const ranges = [];
for (const part of rangeParts) {
const match = part.match(/^(?<start>\d+)?-(?<end>\d+)?$/);
if (match?.groups == null) {
throw new InvalidRangeError(`Invalid range specification: ${part}`);
}
if (part.startsWith('-')) {
ranges.push({
end: parseValue(part)
});
}
else {
const { start, end } = match.groups;
ranges.push({
start: parseValue(start),
end: parseValue(end)
});
}
}
return ranges;
}
export function getRangeHeader(resource, headers) {
const header = headers.get('range');
// not a range request
if (header == null) {
return;
}
try {
const ranges = getByteRangeFromHeader(header);
if (ranges.length === 0) {
return;
}
return {
multipartBoundary: `multipart_byteranges_${Math.floor(Math.random() * 1_000_000_000)}`,
ranges
};
}
catch (e) {
if (e.name === 'InvalidRangeError') {
return notSatisfiableResponse(resource);
}
return badRequestResponse(resource, e);
}
}
//# sourceMappingURL=get-range-header.js.map