import type { NextApiRequest, NextApiResponse } from "next";
const HOP_BY_HOP_HEADERS = new Set([
"connection",
"keep-alive",
"proxy-authenticate",
"proxy-authorization",
"te",
"trailer",
"transfer-encoding",
"upgrade",
]);
const CDN_BASE = "https://static-cdn.publive.online";
const ALLOWED_FILE_EXTENSIONS = new Set(["pdf", "doc", "docx", "xls", "xlsx", "csv", "txt", "zip"]);
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const pathPart = req.query.path;
const cdnPath = Array.isArray(pathPart) ? pathPart.join("/") : pathPart;
if (!cdnPath) {
res.status(404).send("Not Found");
return;
}
const extension = cdnPath.split(".").pop()?.toLowerCase() || "";
if (!ALLOWED_FILE_EXTENSIONS.has(extension)) {
res.status(400).send("Only document/file routes are supported");
return;
}
if (req.method !== "GET" && req.method !== "HEAD") {
res.setHeader("Allow", "GET, HEAD");
res.status(405).send("Method Not Allowed");
return;
}
const upstreamUrl = new URL(`/${cdnPath}`, CDN_BASE);
const queryString = req.url?.split("?")[1];
if (queryString) upstreamUrl.search = queryString;
const proxyHeaders = new Headers();
for (const [key, rawValue] of Object.entries(req.headers)) {
if (!rawValue) continue;
const lowerKey = key.toLowerCase();
if (HOP_BY_HOP_HEADERS.has(lowerKey)) continue;
if (lowerKey === "host") continue;
const value = Array.isArray(rawValue) ? rawValue.join(",") : rawValue;
proxyHeaders.set(key, value);
}
proxyHeaders.set("host", upstreamUrl.host);
const upstream = await fetch(upstreamUrl.toString(), {
method: req.method,
headers: proxyHeaders,
});
if (!upstream.ok && upstream.status >= 400) {
res.status(upstream.status).send("Not Found");
return;
}
upstream.headers.forEach((value, key) => {
const lowerKey = key.toLowerCase();
if (HOP_BY_HOP_HEADERS.has(lowerKey)) return;
if (lowerKey === "content-length") return;
res.setHeader(key, value);
});
res.setHeader("accept-ranges", "bytes");
res.status(upstream.status);
if (req.method === "HEAD") {
res.end();
return;
}
const body = await upstream.arrayBuffer();
res.send(Buffer.from(body));
}