Redirect large/non-inline lesson files to CDN instead of proxying
ZIP/DOCX etc. download natively — no need to force attachment; and the 157 MB Second Brain Vault archive must stream from Caddy with Range, not through the app. Proxy attachment stays for small inline types (PDF/images).
This commit is contained in:
@@ -29,6 +29,17 @@ function extFromUrl(url: string): string {
|
||||
return dot >= 0 ? clean.slice(dot + 1).toLowerCase() : "";
|
||||
}
|
||||
|
||||
// Types a browser renders inline (so the direct link "opens in a tab" instead of
|
||||
// downloading). Only these need proxying with a forced attachment header. ZIP,
|
||||
// DOCX, etc. already download natively → redirect straight to the CDN.
|
||||
const INLINE_EXT = new Set([
|
||||
"pdf", "png", "jpg", "jpeg", "webp", "gif", "svg", "avif",
|
||||
"txt", "htm", "html", "mp4", "mov", "webm", "mp3", "wav",
|
||||
]);
|
||||
// Above this, don't proxy through the app — redirect so the file streams from
|
||||
// the CDN/Caddy with Range support (e.g. the 157 MB Second Brain Vault archive).
|
||||
const PROXY_MAX_BYTES = 50 * 1024 * 1024;
|
||||
|
||||
export async function GET(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
@@ -59,12 +70,26 @@ export async function GET(
|
||||
}
|
||||
}
|
||||
|
||||
const ext = extFromUrl(file.url);
|
||||
|
||||
// Non-inline types download natively — send the browser straight to the CDN
|
||||
// (native download, Range/resume, no app load). Auth is already enforced above.
|
||||
if (!INLINE_EXT.has(ext)) {
|
||||
return NextResponse.redirect(file.url, 302);
|
||||
}
|
||||
|
||||
const upstream = await fetch(file.url);
|
||||
if (!upstream.ok || !upstream.body) {
|
||||
return NextResponse.json({ error: "file_unavailable" }, { status: 502 });
|
||||
}
|
||||
|
||||
const ext = extFromUrl(file.url);
|
||||
// Guard: a very large inline file still shouldn't stream through the app.
|
||||
const upstreamLen = Number(upstream.headers.get("content-length") ?? "0");
|
||||
if (upstreamLen > PROXY_MAX_BYTES) {
|
||||
await upstream.body.cancel();
|
||||
return NextResponse.redirect(file.url, 302);
|
||||
}
|
||||
|
||||
const contentType =
|
||||
upstream.headers.get("content-type") ??
|
||||
CONTENT_TYPES[ext] ??
|
||||
|
||||
Reference in New Issue
Block a user