84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
import { PageProps, Handlers, HandlerContext } from "$fresh/server.ts";
|
|
import { Head, asset } from "$fresh/runtime.ts";
|
|
import {removePrefixFromPathname} from "../../util/util.ts";
|
|
import { join } from "path/posix.ts";
|
|
import DirList, { EntryInfo } from "../../islands/DirList.tsx";
|
|
import FileViewer from "../../islands/FileViewer.tsx";
|
|
|
|
type DirProps = {
|
|
type: "dir";
|
|
path: string;
|
|
stat: Deno.FileInfo;
|
|
files: EntryInfo[];
|
|
}
|
|
type FileProps = {
|
|
type: "file";
|
|
path: string;
|
|
stat: Deno.FileInfo;
|
|
}
|
|
|
|
type DirOrFileProps = DirProps | FileProps;
|
|
|
|
async function GET(req: Request, ctx: HandlerContext): Promise<Response>{
|
|
const authRequired = Deno.env.get("AUTH_REQUIRED") === "true";
|
|
if (authRequired) {
|
|
const login = ctx.state["login"];
|
|
if (!login) {
|
|
return new Response(null, {
|
|
status: 401,
|
|
headers: {
|
|
"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"
|
|
}
|
|
});
|
|
}
|
|
}
|
|
const url = new URL(req.url);
|
|
const path = removePrefixFromPathname(decodeURI(url.pathname), "/dir");
|
|
const stat = await Deno.stat(path);
|
|
if (stat.isDirectory){
|
|
const filesIter = await Deno.readDir(path);
|
|
const files: EntryInfo[] = []
|
|
for await (const file of filesIter){
|
|
const fileStat = await Deno.stat(join(path, file.name));
|
|
files.push({
|
|
...file,
|
|
lastModified: fileStat.mtime ? new Date(fileStat.mtime) : undefined,
|
|
size: fileStat.size
|
|
});
|
|
}
|
|
return await ctx.render({
|
|
type: "dir",
|
|
stat,
|
|
files
|
|
, path
|
|
})
|
|
}
|
|
else{
|
|
return await ctx.render({
|
|
type: "file",
|
|
stat, path
|
|
});
|
|
}
|
|
}
|
|
|
|
export const handler: Handlers = {
|
|
GET
|
|
}
|
|
|
|
export default function DirLists(props: PageProps<DirOrFileProps>) {
|
|
const data = props.data;
|
|
return (<>
|
|
<Head>
|
|
<title>Simple file server : {data.path}</title>
|
|
</Head>
|
|
<div class="p-4 mx-auto max-w-screen-md">
|
|
{data.type === "dir" ? (<DirList path={data.path} files={data.files}></DirList>) :
|
|
(<FileViewer path={data.path}></FileViewer>)}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|