feat: new file

This commit is contained in:
Daniel
2026-03-18 18:57:58 +08:00
commit d0ff049899
31 changed files with 1507 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
import { NextRequest } from "next/server";
const BACKEND_URL = process.env.BACKEND_URL || "http://localhost:8000";
export async function GET(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {
const { path } = await ctx.params;
const url = new URL(req.url);
const upstream = `${BACKEND_URL}/api/${path.join("/")}${url.search}`;
return await safeUpstreamFetch(() => fetch(upstream, { headers: forwardHeaders(req) }));
}
export async function POST(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {
const { path } = await ctx.params;
const url = new URL(req.url);
const upstream = `${BACKEND_URL}/api/${path.join("/")}${url.search}`;
const body = await req.text();
return await safeUpstreamFetch(() =>
fetch(upstream, {
method: "POST",
headers: { ...forwardHeaders(req), "content-type": req.headers.get("content-type") || "application/json" },
body
})
);
}
function forwardHeaders(req: NextRequest) {
const h = new Headers();
const auth = req.headers.get("authorization");
if (auth) h.set("authorization", auth);
return h;
}
async function forwardResponse(r: Response) {
const headers = new Headers(r.headers);
headers.delete("access-control-allow-origin");
return new Response(await r.arrayBuffer(), { status: r.status, headers });
}
async function safeUpstreamFetch(doFetch: () => Promise<Response>) {
const maxAttempts = 3;
for (let i = 0; i < maxAttempts; i++) {
try {
const r = await doFetch();
return await forwardResponse(r);
} catch (e: any) {
const code = e?.cause?.code || e?.code;
const retryable = code === "ECONNREFUSED" || code === "ENOTFOUND" || code === "EAI_AGAIN";
if (!retryable || i === maxAttempts - 1) {
return new Response(
JSON.stringify({
detail: "上游后端不可达backend 容器可能正在重启或未就绪)。",
error: String(code || e?.message || e)
}),
{ status: 503, headers: { "content-type": "application/json; charset=utf-8" } }
);
}
await new Promise((r) => setTimeout(r, 200 * (i + 1)));
}
}
return new Response(JSON.stringify({ detail: "unknown" }), { status: 503 });
}