This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
import { createReadStream } from 'node:fs';
|
||||
import { stat } from 'node:fs/promises';
|
||||
import { extname } from 'node:path';
|
||||
import { httpError } from '../http/httpError.mjs';
|
||||
import { mimeTypes } from './mimeTypes.mjs';
|
||||
import { resolveInside } from './resolveInside.mjs';
|
||||
|
||||
export async function serveFile(response, root, pathname, method) {
|
||||
const filePath = resolveInside(root, pathname);
|
||||
|
||||
if (!filePath) {
|
||||
throw httpError(403, 'Forbidden');
|
||||
}
|
||||
|
||||
const fileStat = await getFileStat(filePath);
|
||||
|
||||
response.writeHead(200, {
|
||||
'Content-Length': fileStat.size,
|
||||
'Content-Type': mimeTypes[extname(filePath).toLowerCase()] || 'application/octet-stream',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
});
|
||||
|
||||
if (method === 'HEAD') {
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
|
||||
createReadStream(filePath).pipe(response);
|
||||
}
|
||||
|
||||
async function getFileStat(filePath) {
|
||||
let fileStat;
|
||||
try {
|
||||
fileStat = await stat(filePath);
|
||||
} catch {
|
||||
throw httpError(404, 'Not found');
|
||||
}
|
||||
|
||||
if (!fileStat.isFile()) {
|
||||
throw httpError(404, 'Not found');
|
||||
}
|
||||
|
||||
return fileStat;
|
||||
}
|
||||
Reference in New Issue
Block a user