Update site visuals and assets

This commit is contained in:
Raffael Sheikh committed 2026-05-24 04:21:24 +02:00
1 parent 41a5958184
commit 39faad9624
27 files changed
+2087 -610

No files matched your search

+54 -4
View File
@@ -16,6 +16,7 @@ const path = require("path");
const crypto = require("crypto");
const os = require("os");
const net = require("net");
const zlib = require("zlib");
const ROOT = __dirname;
const PUBLIC_DIR = path.join(ROOT, "public");
@@ -65,6 +66,7 @@ const MIME = {
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".webp": "image/webp",
".ico": "image/x-icon",
".json": "application/json; charset=utf-8",
".woff2": "font/woff2"
@@ -77,11 +79,35 @@ const CLEAN_ROUTES = {
"/datenschutz": "/datenschutz.html"
};
const IMMUTABLE_EXTS = new Set([".webp", ".svg", ".woff2", ".png", ".jpg", ".jpeg", ".ico"]);
const COMPRESSIBLE_EXTS = new Set([".html", ".css", ".js", ".svg", ".json", ".txt"]);
function redirect(res, location) {
res.writeHead(308, { Location: location });
res.end();
}
function cacheControlFor(urlPath, ext, cacheKey) {
if (urlPath.startsWith("/gamejam-games/")) return "public, max-age=60";
if (ext === ".html") return "no-cache";
if (ext === ".css" || ext === ".js") {
return cacheKey ? "public, max-age=31536000, immutable" : "no-cache";
}
if (IMMUTABLE_EXTS.has(ext)) return "public, max-age=31536000, immutable";
return "no-cache";
}
function etagFor(stat) {
return 'W/"' + stat.size.toString(16) + "-" + Math.floor(stat.mtimeMs).toString(16) + '"';
}
function preferredEncoding(req) {
const accepted = req.headers["accept-encoding"] || "";
if (/\bbr\b/.test(accepted)) return "br";
if (/\bgzip\b/.test(accepted)) return "gzip";
return null;
}
/* ---------- Lead-Speicher vorbereiten ---------- */
function ensureLeadStore() {
if (!fs.existsSync(LEADS_DIR)) fs.mkdirSync(LEADS_DIR, { recursive: true });
@@ -163,11 +189,35 @@ function serveStatic(req, res) {
return;
}
const ext = path.extname(filePath).toLowerCase();
res.writeHead(200, {
const etag = etagFor(stat);
const headers = {
"Content-Type": MIME[ext] || "application/octet-stream",
"Cache-Control": "no-cache"
});
fs.createReadStream(filePath).pipe(res);
"Cache-Control": cacheControlFor(urlPath, ext, parsedUrl.search),
"ETag": etag,
"Last-Modified": stat.mtime.toUTCString(),
"X-Content-Type-Options": "nosniff"
};
if (COMPRESSIBLE_EXTS.has(ext)) headers["Vary"] = "Accept-Encoding";
if ((req.headers["if-none-match"] || "").includes(etag)) {
res.writeHead(304, headers);
res.end();
return;
}
let stream = fs.createReadStream(filePath);
const encoding = COMPRESSIBLE_EXTS.has(ext) ? preferredEncoding(req) : null;
if (encoding === "br") {
headers["Content-Encoding"] = "br";
stream = stream.pipe(zlib.createBrotliCompress());
} else if (encoding === "gzip") {
headers["Content-Encoding"] = "gzip";
stream = stream.pipe(zlib.createGzip({ level: 6 }));
}
res.writeHead(200, headers);
stream.pipe(res);
});
}