in function/nodejs_14_x/src/response/range_mapper.ts [20:65]
export default function mapRange (rangeHeaderValue: string, transformedObject: Buffer): RangeResponse {
const matchArray = rangeHeaderValue.match(/^([a-z]+)=(\d+)?-(\d+)?$/);
if (matchArray === null) { // check if the range matches what we support
return getRangeInvalidResponse(rangeHeaderValue);
}
const [, rangeUnitStr, rangeStartStr, rangeEndStr] = matchArray;
let rangeStart: number;
let rangeEnd: number;
if (rangeUnitStr.toLowerCase() !== SUPPORTED_UNIT) {
return getRangeInvalidResponse(rangeHeaderValue,
`Cannot process units other than ${SUPPORTED_UNIT}`);
}
const isRangeStartPresent = rangeStartStr !== undefined;
const isRangeEndPresent = rangeEndStr !== undefined;
if (!isRangeStartPresent && !isRangeEndPresent) { // At least one should be present
return getRangeInvalidResponse(rangeHeaderValue);
} else if (!isRangeStartPresent) {
/* Range request was of the form <unit>=-<suffix-length> so we return the last `suffix-length` bytes. */
const suffixLength = Number(rangeEndStr);
rangeEnd = transformedObject.byteLength;
rangeStart = rangeEnd - suffixLength;
} else if (!isRangeEndPresent) {
/* Range request was of the form <unit>=<range-start>- so we return from range-start to the end
of the object. */
rangeStart = Number(rangeStartStr);
rangeEnd = transformedObject.byteLength;
} else {
/* Range request was of the form <unit>=<range-start>-<range-end> so we process both. */
rangeStart = Number(rangeStartStr);
const expectedLength = Number(rangeEndStr) + 1; // Add 1 as rangeEnd is inclusive
rangeEnd = Math.min(transformedObject.byteLength, expectedLength); // Should not exceed object length
}
const isRangeValid = rangeStart >= 0 && rangeStart <= rangeEnd;
if (!isRangeValid) {
return getRangeInvalidResponse(rangeHeaderValue);
}
return { object: transformedObject.slice(rangeStart, rangeEnd), hasError: false };
}