import { type NextRequest, NextResponse } from "next/server"; import { lotteryApiOrigin } from "@/lib/lottery-api-base"; const HOP_BY_HOP = new Set([ "connection", "keep-alive", "proxy-authenticate", "proxy-authorization", "te", "trailers", "transfer-encoding", "upgrade", ]); /** fetch 会解压 gzip,须去掉这些头,否则浏览器 ERR_CONTENT_DECODING_FAILED */ const STRIP_RESPONSE_HEADERS = [ ...HOP_BY_HOP, "content-encoding", "content-length", ]; /** 浏览器请求同源 `/api/*`,Next 转发到 `LOTTERY_API_UPSTREAM`(本地/线上同一套)。 */ export async function proxyLotteryApi( request: NextRequest, pathSegments: string[], ): Promise { const path = pathSegments.join("/"); const target = `${lotteryApiOrigin()}/api/${path}${request.nextUrl.search}`; const headers = new Headers(request.headers); headers.delete("host"); headers.delete("connection"); headers.delete("accept-encoding"); const init: RequestInit = { method: request.method, headers, redirect: "manual", }; if (request.method !== "GET" && request.method !== "HEAD") { init.body = await request.arrayBuffer(); } let upstream: Response; try { upstream = await fetch(target, init); } catch (error: unknown) { return NextResponse.json( { msg: "Upstream Laravel unreachable", target, error: error instanceof Error ? error.message : "Unknown error", }, { status: 502 }, ); } const responseHeaders = new Headers(upstream.headers); for (const name of STRIP_RESPONSE_HEADERS) { responseHeaders.delete(name); } return new NextResponse(upstream.body, { status: upstream.status, statusText: upstream.statusText, headers: responseHeaders, }); }