EUS/index.ts
Holly 5e271af9c9 print request info to console/log when it's an image request
As we take control of the request at this point and don't hand the control back, we never hit the logger line on the next hook.
2025-01-27 09:57:45 +00:00

149 lines
No EOL
4.3 KiB
TypeScript

import Fastify, { type FastifyReply, type FastifyRequest } from "fastify";
import FastifyFormBody from "@fastify/formbody";
import FastifyMultipart from "@fastify/multipart";
import FastifyCookie from "@fastify/cookie";
import FastifyView from "@fastify/view";
import FastifyStatic from "@fastify/static";
import Config from "./objects/Config";
import EJS from "ejs";
import { Console } from "hsconsole";
import Controller from "./controllers/Controller";
import HomeController from "./controllers/HomeController";
import Database from "./objects/Database";
import { join } from "path";
import AccountController from "./controllers/AccountController";
import { magenta, blue, cyan, green, red } from "dyetty";
import ConsoleUtility from "./utilities/ConsoleUtility";
import HashFS from "./objects/HashFS";
import FunkyArray from "funky-array";
import MediaService from "./services/MediaService";
import Media from "./entities/Media";
import HeaderUtility from "./utilities/HeaderUtility";
import { createReadStream } from "fs";
Console.customHeader(`EUS server started at ${new Date()}`);
const fastify = Fastify({
logger: false
});
fastify.register(FastifyView, {
engine: {
ejs: EJS
}
});
fastify.register(FastifyFormBody);
fastify.register(FastifyMultipart, {
limits: {
files: 1,
fileSize: 104857600
}
});
fastify.register(FastifyCookie, {
secret: Config.session.secret,
parseOptions: {
path: "/",
secure: true
}
});
fastify.register(FastifyStatic, {
root: join(__dirname, "wwwroot"),
preCompressed: true,
decorateReply: false,
redirect: false
});
function printReqInfo(req: FastifyRequest, res: FastifyReply) {
// @ts-ignore
Console.printInfo(`[ ${req.logType} ] [ ${req.method.toUpperCase()} ] [ ${ConsoleUtility.StatusColor(res.statusCode)} ] [ ${blue(`${Date.now() - req.startTime}ms`)} ] > ${req.url}`);
}
const hashLookupCache = new FunkyArray<string, Media>();
fastify.addHook("preHandler", (req, res, done) => {
(async () => {
// @ts-ignore
req.startTime = Date.now();
// * Take usual controller path if this path is registered.
if (Controller.RegisteredPaths.includes(req.url)) {
// @ts-ignore
req.logType = cyan("CONTROLLER");
HeaderUtility.AddBakedHeaders(res);
return done();
} else {
const urlParts = req.url.split("/");
if (urlParts.length === 2 && urlParts[1].length <= 16) {
let media = hashLookupCache.get(urlParts[1]) ?? null;
if (!media) {
media = await MediaService.GetByTag(urlParts[1]);
if (media) {
hashLookupCache.set(urlParts[1], media);
}
}
if (media) {
// @ts-ignore
req.logType = cyan("IMAGE");
const fileStore = HashFS.GetHashFSInstance("images");
const readStream = createReadStream(join(fileStore.path, fileStore.GetRelativePath(media.Hash)));
res.raw.writeHead(200, HeaderUtility.CombineHeaders({
"content-type": media.MediaType,
"content-length": media.FileSize,
}));
readStream.pipe(res.raw);
printReqInfo(req, res);
return;
}
} else {
HeaderUtility.AddBakedHeaders(res);
}
// @ts-ignore
req.logType = magenta("STATIC");
}
return done();
})();
});
fastify.addHook("onSend", (req, res, _payload, done) => {
printReqInfo(req, res);
done();
});
fastify.setNotFoundHandler(async (_req, res) => {
return res.status(404).view("views/404.ejs");
});
HashFS.STARTUP_DIR = __dirname;
new HashFS("images");
if (Config.database.enabled) {
new Database(Config.database.address, Config.database.port, Config.database.username, Config.database.password, Config.database.name);
} else {
Console.printInfo(`[ ${red("DATABASE")} ] Database is disabled.`);
}
if (Config.controllers.enabled && Config.database.enabled) {
Controller.FastifyInstance = fastify;
new AccountController();
new HomeController();
} else {
Console.printInfo(`[ ${red("CONTROLLER")} ] Controllers are disabled${Config.controllers.enabled && !Config.database.enabled ? " because the database is disabled but required by the controllers." : "."} Server will operate in static mode only.`);
}
fastify.listen({ port: Config.hosts.webPort, host: Config.hosts.webHost }, (err, address) => {
if (err) {
Console.printError(`Error occured while spinning up fastify:\n${err}`);
process.exit(1);
}
Console.printInfo(`[ ${green("MAIN")} ] Listening at ${address.replace("0.0.0.0", "localhost").replace("127.0.0.1", "localhost")}`);
});