OBJ then local
Deploy / deploy (push) Successful in 2m53s

This commit is contained in:
twotalesanimation
2026-07-16 23:04:15 +02:00
parent 9375d5212c
commit e756eb9015
3 changed files with 47 additions and 14 deletions
+10 -11
View File
@@ -1,7 +1,7 @@
import { NextRequest, NextResponse } from "next/server";
import fs from "fs";
import path from "path";
import { generateHetznerStreamUrl } from "@/lib/storage";
import { generateHetznerStreamUrl, hetznerKeyExists } from "@/lib/storage";
// ── Tuning constants ──────────────────────────────────────────────────────────
//
@@ -45,21 +45,20 @@ export async function GET(
return new NextResponse("Forbidden", { status: 403 });
}
// Single stat() replaces the previous existsSync() + statSync() (2 → 1
// syscall). The try/catch also catches ENOENT, EACCES, ENAMETOOLONG, etc.
// ── Hetzner first, local disk fallback ───────────────────────────────────
// Check object storage first (all new uploads go there directly; migrated
// files live there too). Results are cached in process memory after the
// first check so subsequent range requests pay no extra latency.
// Fall back to local disk only for files that haven't been migrated yet.
let stat: fs.Stats;
try {
stat = fs.statSync(filePath);
} catch {
// File not on local disk — attempt a redirect to Hetzner object storage.
// This covers files uploaded after the migration and any migrated files
// whose local copies have been removed.
try {
if (await hetznerKeyExists(relativePath)) {
const hetznerUrl = await generateHetznerStreamUrl(relativePath, 3600);
return NextResponse.redirect(hetznerUrl, 302);
} catch {
return new NextResponse("Not found", { status: 404 });
}
stat = fs.statSync(filePath);
} catch {
return new NextResponse("Not found", { status: 404 });
}
// Guard against directory traversal that resolves to a directory