This commit is contained in:
eric
2026-06-07 23:57:52 -05:00
parent 6d479c9f94
commit 47b1ae8514
56 changed files with 4163 additions and 874 deletions

View File

@@ -58,29 +58,22 @@ async function objectExists(client: ReturnType<typeof getMinioClient>, bucket: s
}
}
function passthroughResponse(buffer: Buffer, contentType: string): NextResponse {
return new NextResponse(buffer, {
status: 200,
headers: {
"Content-Type": contentType,
"Cache-Control": "public, max-age=86400",
},
});
}
export async function GET(request: NextRequest) {
const source = safeSource(request.nextUrl.searchParams.get("src"));
if (!source) {
return NextResponse.json({ ok: false, error: "Invalid media source" }, { status: 400 });
}
const cfg = getMinioConfig();
if (!cfg.enabled) {
return NextResponse.json({ ok: false, error: "MinIO is disabled" }, { status: 503 });
}
const client = getMinioClient(cfg);
await ensurePublicBucket(client, cfg.bucket);
const prefix = `${cfg.uploadPrefix.replace(/\/$/, "")}/remote`;
const hash = createHash("sha256").update(source.toString()).digest("hex").slice(0, 32);
const guessedExt = extensionFromSource(source);
let objectKey = `${prefix}/${hash}.${guessedExt}`;
if (await objectExists(client, cfg.bucket, objectKey)) {
return NextResponse.redirect(publicObjectUrl(cfg.publicUrl, objectKey), 307);
}
let remote: Response;
try {
remote = await fetch(source, { redirect: "follow" });
@@ -97,22 +90,36 @@ export async function GET(request: NextRequest) {
}
const contentType = remote.headers.get("content-type") || "application/octet-stream";
const ext = extensionFromSource(source, contentType);
objectKey = `${prefix}/${hash}.${ext}`;
if (await objectExists(client, cfg.bucket, objectKey)) {
return NextResponse.redirect(publicObjectUrl(cfg.publicUrl, objectKey), 307);
}
const buffer = Buffer.from(await remote.arrayBuffer());
if (buffer.length > MAX_BYTES) {
return NextResponse.json({ ok: false, error: "Media is too large" }, { status: 413 });
}
await client.putObject(cfg.bucket, objectKey, buffer, buffer.length, {
"Content-Type": contentType,
"Cache-Control": "public, max-age=31536000, immutable",
});
const cfg = getMinioConfig();
if (!cfg.enabled) {
return passthroughResponse(buffer, contentType);
}
return NextResponse.redirect(publicObjectUrl(cfg.publicUrl, objectKey), 307);
try {
const client = getMinioClient(cfg);
await ensurePublicBucket(client, cfg.bucket);
const prefix = `${cfg.uploadPrefix.replace(/\/$/, "")}/remote`;
const hash = createHash("sha256").update(source.toString()).digest("hex").slice(0, 32);
const ext = extensionFromSource(source, contentType);
const objectKey = `${prefix}/${hash}.${ext}`;
if (await objectExists(client, cfg.bucket, objectKey)) {
return NextResponse.redirect(publicObjectUrl(cfg.publicUrl, objectKey), 307);
}
await client.putObject(cfg.bucket, objectKey, buffer, buffer.length, {
"Content-Type": contentType,
"Cache-Control": "public, max-age=31536000, immutable",
});
return NextResponse.redirect(publicObjectUrl(cfg.publicUrl, objectKey), 307);
} catch {
return passthroughResponse(buffer, contentType);
}
}