| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import { NextRequest, NextResponse } from "next/server";
- import { getServerSideConfig } from "@/app/config/server";
- export async function handle(
- req: NextRequest,
- { params }: { params: { path: string[] } },
- ) {
- console.log("[Proxy Route] params ", params);
- if (req.method === "OPTIONS") {
- return NextResponse.json({ body: "OK" }, { status: 200 });
- }
- const serverConfig = getServerSideConfig();
- // remove path params from searchParams
- req.nextUrl.searchParams.delete("path");
- req.nextUrl.searchParams.delete("provider");
- const subpath = params.path.join("/");
- const fetchUrl = `${req.headers.get(
- "x-base-url",
- )}/${subpath}?${req.nextUrl.searchParams.toString()}`;
- const skipHeaders = ["connection", "host", "origin", "referer", "cookie"];
- const headers = new Headers(
- Array.from(req.headers.entries()).filter((item) => {
- if (
- item[0].indexOf("x-") > -1 ||
- item[0].indexOf("sec-") > -1 ||
- skipHeaders.includes(item[0])
- ) {
- return false;
- }
- return true;
- }),
- );
- // if dalle3 use openai api key
- const baseUrl = req.headers.get("x-base-url");
- if (baseUrl?.includes("api.openai.com")) {
- if (!serverConfig.apiKey) {
- return NextResponse.json(
- { error: "OpenAI API key not configured" },
- { status: 500 },
- );
- }
- headers.set("Authorization", `Bearer ${serverConfig.apiKey}`);
- }
- const controller = new AbortController();
- const fetchOptions: RequestInit = {
- headers,
- method: req.method,
- body: req.body,
- // to fix #2485: https://stackoverflow.com/questions/55920957/cloudflare-worker-typeerror-one-time-use-body
- redirect: "manual",
- // @ts-ignore
- duplex: "half",
- signal: controller.signal,
- };
- const timeoutId = setTimeout(
- () => {
- controller.abort();
- },
- 10 * 60 * 1000,
- );
- try {
- const res = await fetch(fetchUrl, fetchOptions);
- // to prevent browser prompt for credentials
- const newHeaders = new Headers(res.headers);
- newHeaders.delete("www-authenticate");
- // to disable nginx buffering
- newHeaders.set("X-Accel-Buffering", "no");
- // The latest version of the OpenAI API forced the content-encoding to be "br" in json response
- // So if the streaming is disabled, we need to remove the content-encoding header
- // Because Vercel uses gzip to compress the response, if we don't remove the content-encoding header
- // The browser will try to decode the response with brotli and fail
- newHeaders.delete("content-encoding");
- return new Response(res.body, {
- status: res.status,
- statusText: res.statusText,
- headers: newHeaders,
- });
- } finally {
- clearTimeout(timeoutId);
- }
- }
|