simple-fs-server/routes/fs/[...path].ts
2023-01-06 18:24:27 +09:00

83 lines
2.4 KiB
TypeScript

import { HandlerContext, Handlers } from "$fresh/server.ts";
import { serveFile } from "http/file_server.ts";
import { removePrefixFromPathname } from "../../util/util.ts";
export async function GET(
req: Request,
ctx: HandlerContext,
): Promise<Response> {
const url = new URL(req.url);
const path = removePrefixFromPathname(decodeURI(url.pathname), "/fs");
// if auth is required, check if the user is logged in.
// if not, return a 401.
const authRequired = Deno.env.get("AUTH_REQUIRED") === "true";
if (authRequired) {
const login = ctx.state["login"];
if (!login) {
return new Response(null, {
status: 302,
headers: {
"Location": "/login",
"content-type": "text/plain",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"Access-Control-Allow-Headers":
"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With",
},
});
}
}
try {
const fileInfo = await Deno.stat(path);
if (fileInfo.isDirectory) {
// if index.html exists, serve it.
// otherwise, serve a directory listing.
const indexPath = path + "/index.html";
try {
await Deno.stat(indexPath);
const res = await serveFile(req, indexPath);
return res;
} catch (e) {
if (e instanceof Deno.errors.NotFound) {
const list: Deno.DirEntry[] = [];
for await (const entry of Deno.readDir(path)) {
list.push(entry);
}
return new Response(
JSON.stringify(
list,
),
{
headers: {
"content-type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods":
"GET,HEAD,PUT,PATCH,POST,DELETE",
"Access-Control-Allow-Headers":
"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With",
},
status: 200,
},
);
}
}
}
const res = await serveFile(req, path, {
fileInfo,
});
return res;
} catch (e) {
if (e instanceof Deno.errors.NotFound) {
return new Response("Not Found", {
status: 404,
});
}
throw e;
}
}
export const handler: Handlers = {
GET,
};