@httpland/range-request-middleware
Version:
HTTP range request middleware
45 lines (44 loc) • 2.49 kB
JavaScript
// Copyright 2023-latest the httpland authors. All rights reserved. MIT license.
// This module is browser compatible.
Object.defineProperty(exports, "__esModule", { value: true });
exports.withContentRange = exports.withAcceptRanges = void 0;
const deps_js_1 = require("./deps.js");
const utils_js_1 = require("./utils.js");
function withAcceptRanges(response, unit) {
const units = (0, deps_js_1.isString)(unit) ? [unit] : unit;
const unitValue = (0, deps_js_1.distinct)(units).join(", ");
if (!response.headers.has(deps_js_1.RangeHeader.AcceptRanges)) {
response.headers.set(deps_js_1.RangeHeader.AcceptRanges, unitValue);
}
return response;
}
exports.withAcceptRanges = withAcceptRanges;
async function withContentRange(response, context) {
if (response.status !== deps_js_1.Status.OK ||
response.headers.has(deps_js_1.RangeHeader.ContentRange) ||
response.bodyUsed)
return response;
const acceptRanges = response.headers.get(deps_js_1.RangeHeader.AcceptRanges);
if ((0, deps_js_1.isString)(acceptRanges) && (0, utils_js_1.hasToken)(acceptRanges, utils_js_1.RangeUnit.None)) {
return response;
}
const rangeContainer = (0, deps_js_1.unsafe)(() => (0, deps_js_1.parseRange)(context.rangeValue));
if ((0, deps_js_1.isErr)(rangeContainer)) {
// A server that supports range requests MAY ignore or reject a Range header field that contains an invalid ranges-specifier (Section 14.1.1), a ranges-specifier with more than two overlapping ranges, or a set of many small ranges that are not listed in ascending order, since these are indications of either a broken client or a deliberate denial-of-service attack (Section 17.15).
// https://www.rfc-editor.org/rfc/rfc9110#section-14.2-6
return response;
}
const parsedRange = rangeContainer.value;
const matchedRange = Array.from(context.ranges).find(({ rangeUnit }) => (0, utils_js_1.equalsCaseInsensitive)(rangeUnit, parsedRange.rangeUnit));
const body = await response.clone().arrayBuffer();
if (!matchedRange) {
// @see https://www.rfc-editor.org/rfc/rfc9110#section-14.2-13
return new utils_js_1.RequestedRangeNotSatisfiableResponse({
rangeUnit: parsedRange.rangeUnit,
completeLength: body.byteLength,
}, { headers: response.headers });
}
return matchedRange.respond(response, parsedRange);
}
exports.withContentRange = withContentRange;
;