Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
}
// This necessary to set correct Content-Length and validate Range requests
// Note: we need `size` (raw data), not `cumulativeSize` (data + DAGNodes)
const { size } = await ipfs.files.stat(`/ipfs/${data.cid}`)
// Handle Byte Range requests (https://tools.ietf.org/html/rfc7233#section-2.1)
const catOptions = {}
let rangeResponse = false
if (request.headers.range) {
// If-Range is respected (when present), but we compare it only against Etag
// (Last-Modified date is too weak for IPFS use cases)
if (!request.headers['if-range'] || request.headers['if-range'] === etag) {
const ranges = Ammo.header(request.headers.range, size)
if (!ranges) {
const error = Boom.rangeNotSatisfiable()
error.output.headers['content-range'] = `bytes */${size}`
throw error
}
if (ranges.length === 1) { // Ignore requests for multiple ranges (hard to map to ipfs.cat and not used in practice)
rangeResponse = true
const range = ranges[0]
catOptions.offset = range.from
catOptions.length = (range.to - range.from + 1)
}
}
}
const rawStream = ipfs.catReadableStream(data.cid, catOptions)
// Pass-through Content-Type sniffing over initial bytes
return null;
}
// Check If-Range
if (request.headers['if-range'] &&
request.headers['if-range'] !== response.headers.etag) { // Ignoring last-modified date (weak)
return null;
}
// Parse header
const ranges = Ammo.header(request.headers.range, length);
if (!ranges) {
const error = Boom.rangeNotSatisfiable();
error.output.headers['content-range'] = 'bytes */' + length;
throw error;
}
// Prepare transform
if (ranges.length !== 1) { // Ignore requests for multiple ranges
return null;
}
const range = ranges[0];
response.code(206);
response.bytes(range.to - range.from + 1);
response._header('content-range', 'bytes ' + range.from + '-' + range.to + '/' + length);
return new Ammo.Stream(range);
if (!request.headers['if-range'] ||
request.headers['if-range'] === response.headers.etag) { // Ignoring last-modified date (weak)
// Check that response is not encoded once transmitted
const mime = request.server.mime.type(response.headers['content-type'] || 'application/octet-stream');
const encoding = (request.server.settings.compression && mime.compressible && !response.headers['content-encoding'] ? request.info.acceptEncoding : null);
if (encoding === 'identity' || !encoding) {
// Parse header
const ranges = Ammo.header(request.headers.range, length);
if (!ranges) {
const error = Boom.rangeNotSatisfiable();
error.output.headers['content-range'] = 'bytes */' + length;
throw error;
}
// Prepare transform
if (ranges.length === 1) { // Ignore requests for multiple ranges
range = ranges[0];
response.code(206);
response.bytes(range.to - range.from + 1);
response.header('content-range', 'bytes ' + range.from + '-' + range.to + '/' + length);
}
}
}
}