fix(site): stabilize media and notification runtime
This commit is contained in:
+71
-1
@@ -1,4 +1,5 @@
|
||||
import { createServer } from "node:http";
|
||||
import { createReadStream } from "node:fs";
|
||||
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
||||
import { extname, join, normalize } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
@@ -44,6 +45,30 @@ function send(res, status, body, contentType = "text/plain; charset=utf-8") {
|
||||
res.end(body);
|
||||
}
|
||||
|
||||
function sendStream(req, res, status, stream, headers) {
|
||||
res.writeHead(status, {
|
||||
"cache-control": "no-store",
|
||||
"accept-ranges": "bytes",
|
||||
...headers,
|
||||
});
|
||||
|
||||
if (req.method === "HEAD") {
|
||||
stream.destroy();
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
stream.on("error", () => {
|
||||
if (!res.headersSent) {
|
||||
send(res, 500, "Failed to read file");
|
||||
return;
|
||||
}
|
||||
|
||||
res.destroy();
|
||||
});
|
||||
stream.pipe(res);
|
||||
}
|
||||
|
||||
function sendJson(res, status, payload) {
|
||||
send(res, status, `${JSON.stringify(payload, null, 2)}\n`, "application/json; charset=utf-8");
|
||||
}
|
||||
@@ -314,7 +339,52 @@ async function serveStatic(req, res) {
|
||||
}
|
||||
|
||||
const ext = extname(filePath);
|
||||
send(res, 200, await readFile(filePath), MIME[ext] || "application/octet-stream");
|
||||
const contentType = MIME[ext] || "application/octet-stream";
|
||||
const range = req.headers.range;
|
||||
|
||||
if (range) {
|
||||
const match = /^bytes=(\d*)-(\d*)$/.exec(range);
|
||||
|
||||
if (!match) {
|
||||
res.writeHead(416, {
|
||||
"cache-control": "no-store",
|
||||
"content-range": `bytes */${fileStat.size}`,
|
||||
});
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const start = match[1] ? Number(match[1]) : 0;
|
||||
const end = match[2] ? Number(match[2]) : fileStat.size - 1;
|
||||
|
||||
if (
|
||||
!Number.isInteger(start) ||
|
||||
!Number.isInteger(end) ||
|
||||
start < 0 ||
|
||||
end < start ||
|
||||
start >= fileStat.size
|
||||
) {
|
||||
res.writeHead(416, {
|
||||
"cache-control": "no-store",
|
||||
"content-range": `bytes */${fileStat.size}`,
|
||||
});
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const cappedEnd = Math.min(end, fileStat.size - 1);
|
||||
sendStream(req, res, 206, createReadStream(filePath, { start, end: cappedEnd }), {
|
||||
"content-type": contentType,
|
||||
"content-length": cappedEnd - start + 1,
|
||||
"content-range": `bytes ${start}-${cappedEnd}/${fileStat.size}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
sendStream(req, res, 200, createReadStream(filePath), {
|
||||
"content-type": contentType,
|
||||
"content-length": fileStat.size,
|
||||
});
|
||||
} catch {
|
||||
send(res, 404, "Not found");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user