import { NextRequest } from "next/server"; export const runtime = "nodejs"; export const dynamic = "force-dynamic"; const HOP_BY_HOP_HEADERS = new Set([ "connection", "keep-alive", "proxy-authenticate", "proxy-authorization", "te", "trailer", "transfer-encoding", "upgrade", "host", ]); type RouteContext = { params: Promise<{ path: string[] }>; }; function getApiInternalUrl() { return (process.env.API_INTERNAL_URL || "http://127.0.0.1:8000").replace(/\/$/, ""); } function buildHeaders(request: NextRequest) { const headers = new Headers(); request.headers.forEach((value, key) => { if (!HOP_BY_HOP_HEADERS.has(key.toLowerCase())) { headers.set(key, value); } }); return headers; } async function proxy(request: NextRequest, context: RouteContext) { const { path } = await context.params; const apiPath = path.join("/"); const targetUrl = new URL(`/api/${apiPath}${request.nextUrl.search}`, getApiInternalUrl()); const method = request.method.toUpperCase(); const hasBody = !["GET", "HEAD"].includes(method); try { const upstream = await fetch(targetUrl, { method, headers: buildHeaders(request), body: hasBody ? await request.arrayBuffer() : undefined, cache: "no-store", }); const responseHeaders = new Headers(upstream.headers); responseHeaders.delete("content-encoding"); responseHeaders.delete("content-length"); return new Response(upstream.body, { status: upstream.status, statusText: upstream.statusText, headers: responseHeaders, }); } catch (error) { console.error("API proxy failed", { target: targetUrl.toString(), error: error instanceof Error ? error.message : String(error), }); return Response.json( { detail: "后端服务暂时不可用,请检查 API_INTERNAL_URL 或后端容器状态。", target: targetUrl.origin, }, { status: 502 }, ); } } export const GET = proxy; export const POST = proxy; export const PUT = proxy; export const PATCH = proxy; export const DELETE = proxy;