UNPKG

@helia/verified-fetch

Version:

A fetch-like API for obtaining verified & trustless IPFS content on the web

69 lines 2.18 kB
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