@triliumnext/express-partial-content
Version:
A partial content handler implementation for any readable stream with Express. Based on this blog post: https://www.codeproject.com/Articles/813480/HTTP-Partial-Content-In-Node-js.
47 lines • 2.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseRangeHeader = parseRangeHeader;
const RangeParserError_1 = require("./RangeParserError");
const rangeRegEx = /bytes=([0-9]*)-([0-9]*)/;
function parseRangeHeader(range, totalSize, logger) {
logger.debug("Un-parsed range is: ", range);
// 1. If range is not specified or the file is empty, return null.
if (!range || range === null || range.length === 0 || totalSize === 0) {
return null;
}
const splitRange = range.split(rangeRegEx);
const [, startValue, endValue] = splitRange;
let start = Number.parseInt(startValue);
let end = Number.parseInt(endValue);
// 2. Parse start and end values and ensure they are within limits.
// 2.1. start: >= 0.
// 2.2. end: >= 0, <= totalSize - 1
let result = {
start: Number.isNaN(start) ? 0 : Math.max(start, 0),
end: Number.isNaN(end) ? totalSize - 1 : Math.min(Math.max(end, 0), totalSize - 1)
};
// 3.1. If end is not provided, set end to the last byte (totalSize - 1).
if (!Number.isNaN(start) && Number.isNaN(end)) {
logger.debug("End is not provided.");
result.start = start;
result.end = totalSize - 1;
}
// 3.2. If start is not provided, set it to the offset of last "end" bytes from the end of the file.
// And set end to the last byte.
// This way we return the last "end" bytes.
if (Number.isNaN(start) && !Number.isNaN(end)) {
logger.debug(`Start is not provided, "end" will be treated as last "end" bytes of the content.`);
result.start = Math.max(totalSize - end, 0);
result.end = totalSize - 1;
}
// 4. Handle invalid ranges.
if (start < 0 || start > end || end > totalSize) {
throw new RangeParserError_1.RangeParserError(start, end);
}
logRange(logger, result);
return result;
}
function logRange(logger, range) {
logger.debug("Range is: ", JSON.stringify(range));
}
//# sourceMappingURL=parseRangeHeader.js.map