bgbye routing fix
This commit is contained in:
parent
3c76ab69e5
commit
c1fbdc843c
4 changed files with 56 additions and 50 deletions
|
|
@ -2,6 +2,7 @@
|
|||
# Public (used by client-side dropdown fetches)
|
||||
# ─────────────────────────────────────────────
|
||||
NEXT_PUBLIC_API_BASE_URL=https://forms.lasereverything.net
|
||||
BG_BYE_UPSTREAM=https://makearmy.io/bgbye/process
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Server-side Directus
|
||||
|
|
|
|||
47
app/api/bgbye/process/route.ts
Normal file
47
app/api/bgbye/process/route.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
export const runtime = "nodejs";
|
||||
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
/**
|
||||
* Proxies multipart POSTs (file + method) to the bgbye upstream.
|
||||
* Set BG_BYE_UPSTREAM to the FULL endpoint that accepts the form:
|
||||
* e.g. http://127.0.0.1:8010/process
|
||||
* http://localhost:8010/api/removebg
|
||||
*/
|
||||
export async function POST(req: Request) {
|
||||
const upstream = process.env.BG_BYE_UPSTREAM;
|
||||
if (!upstream) {
|
||||
return NextResponse.json(
|
||||
{ error: "BG_BYE_UPSTREAM is not configured on the server" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const form = await req.formData();
|
||||
|
||||
// Forward the form as-is to the upstream
|
||||
const ures = await fetch(upstream, {
|
||||
method: "POST",
|
||||
body: form,
|
||||
// Let undici set boundary; don't set Content-Type manually
|
||||
});
|
||||
|
||||
const contentType = ures.headers.get("content-type") || "application/octet-stream";
|
||||
const status = ures.status;
|
||||
|
||||
// Stream/buffer back to the client preserving content-type
|
||||
const ab = await ures.arrayBuffer();
|
||||
return new Response(Buffer.from(ab), {
|
||||
status,
|
||||
headers: {
|
||||
"content-type": contentType,
|
||||
// Allow the client to see error text if upstream returns text
|
||||
"cache-control": "no-store",
|
||||
},
|
||||
});
|
||||
} catch (err: any) {
|
||||
const msg = err?.message || String(err);
|
||||
return NextResponse.json({ error: `Proxy error: ${msg}` }, { status: 502 });
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
// /app/api/bgremove/route.ts
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const BGBYE_URL =
|
||||
process.env.BGBYE_URL ||
|
||||
process.env.BG_BYE_URL ||
|
||||
process.env.BGREMOVER_BASE_URL || // <-- support your existing env var
|
||||
"http://bgbye:7001";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const inForm = await req.formData();
|
||||
const method = String(inForm.get("method") || "");
|
||||
const file = inForm.get("file") as any;
|
||||
|
||||
// Loosen the guard: some Node/undici builds return a File-like Blob from a different realm
|
||||
if (!file || !method) {
|
||||
return NextResponse.json({ error: "file and method are required" }, { status: 400 });
|
||||
}
|
||||
|
||||
const outForm = new FormData();
|
||||
const filename = (file as any).name || "upload";
|
||||
outForm.set("method", method);
|
||||
outForm.set("file", file, filename);
|
||||
|
||||
const res = await fetch(`${BGBYE_URL}/remove_background/`, { method: "POST", body: outForm });
|
||||
|
||||
const buf = await res.arrayBuffer();
|
||||
return new NextResponse(buf, {
|
||||
status: res.status,
|
||||
headers: {
|
||||
"content-type": res.headers.get("content-type") || "application/octet-stream",
|
||||
"cache-control": "no-store",
|
||||
},
|
||||
});
|
||||
} catch (err: any) {
|
||||
return NextResponse.json({ error: String(err?.message || err) }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,7 +194,8 @@ export default function BackgroundRemoverPage() {
|
|||
fd.append("file", blobToSend);
|
||||
fd.append("method", key);
|
||||
|
||||
const res = await fetch("/api/bgremove", { method: "POST", body: fd });
|
||||
// CHANGED: call local proxy instead of a hardcoded service
|
||||
const res = await fetch("/api/bgbye/process", { method: "POST", body: fd });
|
||||
if (!res.ok) {
|
||||
const txt = await res.text().catch(() => "");
|
||||
const retryable = /out of memory|onnxruntime|cuda|allocate|500/i.test(txt);
|
||||
|
|
@ -320,7 +321,8 @@ export default function BackgroundRemoverPage() {
|
|||
const fd = new FormData();
|
||||
fd.append("file", file);
|
||||
fd.append("method", active);
|
||||
const res = await fetch("/api/bgremove", { method: "POST", body: fd });
|
||||
// CHANGED: call local proxy instead of a hardcoded service
|
||||
const res = await fetch("/api/bgbye/process", { method: "POST", body: fd });
|
||||
if (!res.ok) throw new Error(await res.text());
|
||||
const outBlob = await res.blob();
|
||||
const ms = performance.now() - t0;
|
||||
|
|
@ -373,10 +375,10 @@ export default function BackgroundRemoverPage() {
|
|||
{file?.name ?? <span className="italic">— none —</span>}
|
||||
</div>
|
||||
|
||||
{/* Preview frame */}
|
||||
{/* Preview frame (border removed per your note) */}
|
||||
<div
|
||||
ref={frameRef}
|
||||
className="app-frame checkerboard relative w-full rounded-2xl border border-zinc-800/80 shadow-inner"
|
||||
className="app-frame checkerboard relative w-full rounded-2xl shadow-inner"
|
||||
style={{ aspectRatio: `${aspect}`, maxWidth: "1200px", maxHeight: "80vh", marginInline: "auto" }}
|
||||
onDragOver={(e) => e.preventDefault()}
|
||||
onDrop={onDrop}
|
||||
|
|
@ -475,7 +477,7 @@ export default function BackgroundRemoverPage() {
|
|||
{pendingCount > 0 ? `Running… ${doneCount}/${METHODS.length}` : "Run all methods"}
|
||||
</button>
|
||||
|
||||
{/* GPU-safe toggle: sits next to Run All on mobile; keeps position naturally on larger screens */}
|
||||
{/* GPU-safe toggle */}
|
||||
<label className="flex items-center gap-2 text-sm text-zinc-300 cursor-pointer select-none order-1">
|
||||
<input type="checkbox" checked={gpuSafe} onChange={(e) => setGpuSafe(e.target.checked)} /> GPU-safe mode
|
||||
</label>
|
||||
|
|
@ -494,7 +496,7 @@ export default function BackgroundRemoverPage() {
|
|||
)}
|
||||
</div>
|
||||
|
||||
{/* Right-side controls collapse under on mobile */}
|
||||
{/* Right-side controls */}
|
||||
<div className="sm:ml-auto flex items-center gap-3 w-full sm:w-auto order-3">
|
||||
<input
|
||||
type="range"
|
||||
|
|
@ -536,4 +538,3 @@ export default function BackgroundRemoverPage() {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue