mirror of
https://github.com/Yidadaa/ChatGPT-Next-Web.git
synced 2025-11-05 17:46:11 +08:00
.github
.husky
app
api
[provider]
artifacts
config
tencent
upstash
webdav
alibaba.ts
anthropic.ts
auth.ts
azure.ts
baidu.ts
bytedance.ts
common.ts
glm.ts
google.ts
iflytek.ts
moonshot.ts
openai.ts
proxy.ts
stability.ts
xai.ts
client
components
config
icons
lib
locales
masks
store
styles
utils
command.ts
constant.ts
global.d.ts
layout.tsx
page.tsx
polyfill.ts
typing.ts
utils.ts
docs
public
scripts
src-tauri
test
.babelrc
.dockerignore
.env.template
.eslintignore
.eslintrc.json
.gitignore
.gitpod.yml
.lintstagedrc.json
.prettierrc.js
CODE_OF_CONDUCT.md
Dockerfile
LICENSE
README.md
README_CN.md
README_JA.md
docker-compose.yml
jest.config.ts
jest.setup.ts
next.config.mjs
package.json
tsconfig.json
vercel.json
yarn.lock
76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
import { NextRequest, NextResponse } from "next/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 });
|
|
}
|
|
|
|
// 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;
|
|
}),
|
|
);
|
|
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);
|
|
}
|
|
}
|