All checks were successful
Build and Push Docker Image / docker (push) Successful in 9s
47 lines
1.4 KiB
JavaScript
47 lines
1.4 KiB
JavaScript
import fs from 'fs';
|
|
|
|
export function setCommonNoCacheHeaders(res) {
|
|
res.setHeader('Cache-Control', 'no-store');
|
|
res.setHeader('Accept-Ranges', 'bytes');
|
|
}
|
|
|
|
export function headFile(res, { size, mime }) {
|
|
setCommonNoCacheHeaders(res);
|
|
res.setHeader('Content-Type', mime);
|
|
res.setHeader('Content-Length', size);
|
|
res.status(200).end();
|
|
}
|
|
|
|
export function streamFile(req, res, { filePath, mime }) {
|
|
const stat = fs.statSync(filePath);
|
|
const size = stat.size;
|
|
const range = req.headers.range;
|
|
setCommonNoCacheHeaders(res);
|
|
if (range) {
|
|
const match = /bytes=(\d+)-(\d+)?/.exec(range);
|
|
let start = match?.[1] ? parseInt(match[1], 10) : 0;
|
|
let end = match?.[2] ? parseInt(match[2], 10) : size - 1;
|
|
if (Number.isNaN(start)) start = 0;
|
|
if (Number.isNaN(end)) end = size - 1;
|
|
start = Math.min(Math.max(0, start), Math.max(0, size - 1));
|
|
end = Math.min(Math.max(start, end), Math.max(0, size - 1));
|
|
if (start > end || start >= size) {
|
|
res.setHeader('Content-Range', `bytes */${size}`);
|
|
return res.status(416).end();
|
|
}
|
|
const chunkSize = end - start + 1;
|
|
res.writeHead(206, {
|
|
'Content-Range': `bytes ${start}-${end}/${size}`,
|
|
'Content-Length': chunkSize,
|
|
'Content-Type': mime,
|
|
});
|
|
fs.createReadStream(filePath, { start, end }).pipe(res);
|
|
} else {
|
|
res.writeHead(200, {
|
|
'Content-Length': size,
|
|
'Content-Type': mime,
|
|
});
|
|
fs.createReadStream(filePath).pipe(res);
|
|
}
|
|
}
|