/** * 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 { 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.isDirectory) { const extensions: string[] = media_types.allExtensions('text/html') ?? ['html', 'htm']; for (const extension of extensions) { const index_path = path.join(normalized_path, `index.${extension}`); const index_stat = await Deno.stat(index_path); if (index_stat.isFile) { return new Response(await Deno.readFile(index_path), { headers: { 'Content-Type': 'text/html' } }); } } return; } 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; } }