51 lines
1.3 KiB
TypeScript
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;
|
|
}
|
|
}
|