69 lines
1.7 KiB
JavaScript
69 lines
1.7 KiB
JavaScript
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
|
|
function sendJson(res, statusCode, body) {
|
|
res.writeHead(statusCode, {
|
|
"Content-Type": "application/json; charset=utf-8",
|
|
"Access-Control-Allow-Origin": "*",
|
|
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
"Cache-Control": "no-store",
|
|
});
|
|
res.end(JSON.stringify(body));
|
|
}
|
|
|
|
function sendText(res, statusCode, text, contentType = "text/plain; charset=utf-8") {
|
|
res.writeHead(statusCode, {
|
|
"Content-Type": contentType,
|
|
"Access-Control-Allow-Origin": "*",
|
|
"Cache-Control": "no-store",
|
|
});
|
|
res.end(text);
|
|
}
|
|
|
|
function redirect(res, location) {
|
|
res.writeHead(302, { Location: location });
|
|
res.end();
|
|
}
|
|
|
|
async function readBody(req) {
|
|
const chunks = [];
|
|
for await (const chunk of req) chunks.push(chunk);
|
|
const text = Buffer.concat(chunks).toString("utf8");
|
|
if (!text) return {};
|
|
|
|
try {
|
|
return JSON.parse(text);
|
|
} catch {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
function serveFile(res, filePath, contentType = "text/html; charset=utf-8") {
|
|
if (!fs.existsSync(filePath)) {
|
|
sendText(res, 404, "Not found");
|
|
return;
|
|
}
|
|
|
|
res.writeHead(200, {
|
|
"Content-Type": contentType,
|
|
"Cache-Control": "no-store",
|
|
});
|
|
fs.createReadStream(filePath).pipe(res);
|
|
}
|
|
|
|
function safeJoin(baseDir, requestPath) {
|
|
const resolved = path.resolve(baseDir, requestPath.replace(/^\/+/, ""));
|
|
if (!resolved.startsWith(path.resolve(baseDir))) return null;
|
|
return resolved;
|
|
}
|
|
|
|
module.exports = {
|
|
sendJson,
|
|
sendText,
|
|
redirect,
|
|
readBody,
|
|
serveFile,
|
|
safeJoin,
|
|
};
|