@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.
65 lines • 3.54 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPartialContentHandler = createPartialContentHandler;
const parseRangeHeader_1 = require("./parseRangeHeader");
const RangeParserError_1 = require("./RangeParserError");
const ContentDoesNotExistError_1 = require("./ContentDoesNotExistError");
const utils_1 = require("./utils");
function createPartialContentHandler(contentProvider, logger) {
return function handler(req, res) {
return __awaiter(this, void 0, void 0, function* () {
let content;
try {
content = yield contentProvider(req);
}
catch (error) {
logger.debug("createPartialContentHandler: ContentProvider threw exception: ", error);
if (error instanceof ContentDoesNotExistError_1.ContentDoesNotExistError) {
return res.status(404).send(error.message);
}
return res.sendStatus(500);
}
let { getStream, mimeType, fileName, totalSize } = content;
const rangeHeader = (0, utils_1.getRangeHeader)(req);
let range;
try {
range = (0, parseRangeHeader_1.parseRangeHeader)(rangeHeader, totalSize, logger);
}
catch (error) {
logger.debug(`createPartialContentHandler: parseRangeHeader error: `, error);
if (error instanceof RangeParserError_1.RangeParserError) {
(0, utils_1.setContentRangeHeader)(null, totalSize, res);
return res.status(416).send(`Invalid value for Range: ${rangeHeader}`);
}
return res.sendStatus(500);
}
(0, utils_1.setContentTypeHeader)(mimeType, res);
(0, utils_1.setContentDispositionHeader)(fileName, res);
(0, utils_1.setAcceptRangesHeader)(res);
// If range is not specified, or the file is empty, return the full stream
if (range === null) {
logger.debug("createPartialContentHandler: No range found, returning full content.");
(0, utils_1.setContentLengthHeader)(totalSize, res);
return getStream().pipe(res);
}
(0, utils_1.setContentRangeHeader)(range, totalSize, res);
let { start, end } = range;
(0, utils_1.setContentLengthHeader)(start === end ? 0 : end - start + 1, res);
(0, utils_1.setCacheControlHeaderNoCache)(res);
// Return 206 Partial Content status
logger.debug("createPartialContentHandler: Returning partial content for range: ", JSON.stringify(range));
res.status(206);
return getStream(range).pipe(res);
});
};
}
//# sourceMappingURL=createPartialContentHandler.js.map