serverus/handlers/static.ts

51 lines
1.3 KiB
TypeScript

/**
* Handles requests for static files.
* @module
*/
import * as path from '@std/path';
import * as media_types from '@std/media-types';
/**
* Handles requests for static files.
*
* @param request The incoming HTTP request
* @returns Either a response (a static file was requested and returned properly) or undefined if unhandled.
*/
export default async function handle_static_files(request: Request): Promise<Response | undefined> {
const url = new URL(request.url);
const normalized_path = path.resolve(path.normalize(url.pathname).replace(/^\/+/, ''));
if (!normalized_path.startsWith(Deno.cwd())) {
return;
}
try {
const stat = await Deno.stat(normalized_path);
if (stat.isFile) {
const extension = path.extname(normalized_path)?.slice(1)?.toLowerCase() ?? '';
const content_type = media_types.contentType(extension) ?? 'application/octet-stream';
return new Response(await Deno.readFile(normalized_path), {
headers: {
'Content-Type': content_type
}
});
}
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
return;
}
if (error instanceof Deno.errors.PermissionDenied) {
return new Response('Permission Denied', {
status: 400,
headers: {
'Content-Type': 'text/plain'
}
});
}
throw error;
}
}