import type { APIRoute } from "astro"; import { promises as fs, constants } from "fs"; import path from "path"; export const GET: APIRoute = async ({ params }) => { const filePathParam = params.path; if (!filePathParam) { return new Response("Not found", { status: 404 }); } const dataDir = process.env.DATA_DIR ? process.env.DATA_DIR : import.meta.env.DATA_DIR; if (!dataDir) { return new Response("DATA_DIR environment variable is not set", { status: 500, }); } const uploadDir = path.join(dataDir, "uploads"); const safePath = path.normalize(filePathParam).replace(/^(\.\.[\/\\])+/, ""); const fullPath = path.join(uploadDir, safePath); if (!fullPath.startsWith(uploadDir)) { return new Response("Forbidden", { status: 403 }); } try { await fs.access(fullPath, constants.R_OK); const fileStats = await fs.stat(fullPath); if (!fileStats.isFile()) { return new Response("Not found", { status: 404 }); } const fileContent = await fs.readFile(fullPath); const ext = path.extname(fullPath).toLowerCase(); let contentType = "application/octet-stream"; switch (ext) { case ".png": contentType = "image/png"; break; case ".jpg": case ".jpeg": contentType = "image/jpeg"; break; case ".gif": contentType = "image/gif"; break; } return new Response(fileContent, { headers: { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable", }, }); } catch (error) { return new Response("Not found", { status: 404 }); } };