celery/static.js

96 lines
3.1 KiB
JavaScript
Raw Normal View History

2022-03-15 02:55:15 +00:00
const fs = require("fs");
const path = require("path");
2022-03-15 03:33:47 +00:00
const types = require("./types.js");
2022-03-17 01:34:09 +00:00
const log = require("./log.js");
2022-03-21 16:55:02 +00:00
const { version } = require("./modules/03-cache.js");
2022-03-15 02:55:15 +00:00
const mustache = require("mustache");
const LRU = require("lru-cache");
2022-03-17 01:34:09 +00:00
const cache = new LRU({ max: 100 });
const time = Date.now().toString(32).toString(36);
2022-03-15 02:55:15 +00:00
const template404 = fs.readFileSync("assets/404.html", "utf8");
2022-04-12 18:41:22 +00:00
module.exports = generate;
2022-03-15 02:55:15 +00:00
const handlers = {
directory: require("./handlers/directory.js"),
markdown: require("./handlers/markdown.js"),
2022-03-16 06:02:09 +00:00
gemini: require("./handlers/gemini.js"),
2022-03-15 02:55:15 +00:00
file: require("./handlers/file.js"),
};
2022-03-21 16:55:02 +00:00
function generate(file, raw = false) {
2022-03-17 01:34:09 +00:00
const where = path.resolve(__dirname + "/overlay/" + file);
2022-03-16 06:02:09 +00:00
2022-03-17 01:34:09 +00:00
if(!fs.existsSync(where)) {
2022-03-18 03:11:30 +00:00
return send("text/html", mustache.render(template404, { file, time, cache: { style: version("/assets/style.css") } }), 404);
2022-03-17 01:34:09 +00:00
}
2022-03-15 02:55:15 +00:00
2022-03-30 00:51:12 +00:00
try {
const stat = fs.statSync(where);
if(stat.isDirectory()) {
if(!file.endsWith("/")) return (req, res) => res.redirect(file + "/");
return send("text/html", run(handlers.directory));
} else if(path.extname(where) === ".md" && !raw) {
return send("text/html", run(handlers.markdown));
} else if(path.extname(where) === ".gmi" && !raw) {
return send("text/html", run(handlers.gemini));
2022-03-15 02:55:15 +00:00
} else {
2022-03-30 00:51:12 +00:00
const type = types.get(path.extname(where).slice(1));
2022-04-24 05:53:42 +00:00
if(stat.size < 1024 * 32) {
2022-03-30 00:51:12 +00:00
return send(type, run(handlers.file));
} else {
return (req, res) => {
const range = req.range(stat.size);
if(range === -2) return res.sendStatus(400);
if(range === -1) return res.sendStatus(416);
const headers = {
"Content-Type": type || "application/octet-stream",
"Content-Length": stat.size,
"Accept-Ranges": "bytes",
};
if(range) {
if(range.type !== "bytes") return res.sendStatus(400);
headers["Content-Range"] = `bytes ${range[0].start}-${range[0].end}/${stat.size}`;
headers["Content-Length"] = Math.abs(range[0].end - range[0].start) + 1;
res.writeHead(206, headers);
fs.createReadStream(where, range[0]).pipe(res);
} else {
res.writeHead(200, headers);
fs.createReadStream(where).pipe(res);
}
2022-03-19 06:27:32 +00:00
};
2022-03-30 00:51:12 +00:00
}
2022-03-15 02:55:15 +00:00
}
2022-03-30 00:51:12 +00:00
} catch {
return send("text/html", mustache.render(template404, { file, time, cache: { style: version("/assets/style.css") } }), 404);
2022-03-17 01:34:09 +00:00
}
2022-03-15 02:55:15 +00:00
2022-03-17 01:34:09 +00:00
function send(type, content, status = 200) {
2022-04-12 18:41:22 +00:00
if(typeof content === "function") return content;
2022-03-21 16:55:02 +00:00
content = Buffer.from(content);
2022-03-19 06:27:32 +00:00
const headers = { "Content-Type": type || "text/plain", "Content-Length": content.length };
2022-03-17 01:34:09 +00:00
return (req, res) => res.writeHead(status, headers).end(content);
}
2022-03-15 02:55:15 +00:00
2022-03-17 01:34:09 +00:00
function run(mod) {
const hash = mod.hash(where, file);
if(cache.has(where)) {
const [rendered, oldhash] = cache.get(where);
if(hash === oldhash) return rendered;
2022-03-15 02:55:15 +00:00
}
2022-03-17 01:34:09 +00:00
const rendered = mod.render(where, file);
cache.set(where, [rendered, hash]);
return rendered;
}
};
module.exports.handle = (req, res) => {
2022-03-21 16:55:02 +00:00
// stop sneaky people
2024-07-28 13:37:14 +00:00
if(req.path.includes("..")) return res.writeHead(403).end("nice try bud, but we don't do that here.");
2022-03-21 16:55:02 +00:00
2024-07-28 13:37:14 +00:00
generate(path.normalize(decodeURIComponent(req.path)), "raw" in req.query)(req, res);
2022-03-15 02:55:15 +00:00
};