28 lines
937 B
TypeScript
28 lines
937 B
TypeScript
import { createReadStream } from "fs";
|
|
import { resolve, normalize } from "path";
|
|
import { access } from "fs/promises";
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const pathParam = getRouterParam(event, "path") as string | string[];
|
|
const pathStr = Array.isArray(pathParam) ? pathParam.join("/") : pathParam;
|
|
|
|
// prevent path traversal
|
|
const baseDir = resolve(process.cwd(), "data/audio");
|
|
const filePath = normalize(resolve(baseDir, pathStr));
|
|
|
|
if (!filePath.startsWith(baseDir)) {
|
|
throw createError({ statusCode: 403, message: "Forbidden" });
|
|
}
|
|
|
|
try {
|
|
await access(filePath);
|
|
} catch {
|
|
throw createError({ statusCode: 404, message: "Audio not found" });
|
|
}
|
|
|
|
const ext = filePath.endsWith(".mp3") ? "audio/mpeg" : "audio/mpeg";
|
|
setHeader(event, "Content-Type", ext);
|
|
setHeader(event, "Cache-Control", "public, max-age=86400");
|
|
|
|
return sendStream(event, createReadStream(filePath));
|
|
});
|