* reorganize folder structure * move folders from merge * fix import issue * run format * update configs
142 lines
4.2 KiB
TypeScript
142 lines
4.2 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
|
|
export async function GET(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ path: string[] }> },
|
|
) {
|
|
return proxyRequest(request, await params);
|
|
}
|
|
|
|
export async function POST(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ path: string[] }> },
|
|
) {
|
|
return proxyRequest(request, await params);
|
|
}
|
|
|
|
export async function PUT(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ path: string[] }> },
|
|
) {
|
|
return proxyRequest(request, await params);
|
|
}
|
|
|
|
export async function DELETE(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ path: string[] }> },
|
|
) {
|
|
return proxyRequest(request, await params);
|
|
}
|
|
|
|
export async function PATCH(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ path: string[] }> },
|
|
) {
|
|
return proxyRequest(request, await params);
|
|
}
|
|
|
|
async function proxyRequest(request: NextRequest, params: { path: string[] }) {
|
|
const backendHost = process.env.OPENRAG_BACKEND_HOST || "localhost";
|
|
const backendSSL = process.env.OPENRAG_BACKEND_SSL || false;
|
|
const path = params.path.join("/");
|
|
const searchParams = request.nextUrl.searchParams.toString();
|
|
let backendUrl = `http://${backendHost}:8000/${path}${searchParams ? `?${searchParams}` : ""}`;
|
|
if (backendSSL) {
|
|
backendUrl = `https://${backendHost}:8000/${path}${searchParams ? `?${searchParams}` : ""}`;
|
|
}
|
|
|
|
try {
|
|
let body: string | ArrayBuffer | undefined = undefined;
|
|
let willSendBody = false;
|
|
|
|
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
const contentType = request.headers.get("content-type") || "";
|
|
const contentLength = request.headers.get("content-length");
|
|
|
|
// For file uploads (multipart/form-data), preserve binary data
|
|
if (contentType.includes("multipart/form-data")) {
|
|
const buf = await request.arrayBuffer();
|
|
if (buf && buf.byteLength > 0) {
|
|
body = buf;
|
|
willSendBody = true;
|
|
}
|
|
} else {
|
|
// For JSON and other text-based content, use text
|
|
const text = await request.text();
|
|
if (text && text.length > 0) {
|
|
body = text;
|
|
willSendBody = true;
|
|
}
|
|
}
|
|
|
|
// Guard against incorrect non-zero content-length when there is no body
|
|
if (!willSendBody && contentLength) {
|
|
// We'll drop content-length/header below
|
|
}
|
|
}
|
|
|
|
const headers = new Headers();
|
|
|
|
// Copy relevant headers from the original request
|
|
for (const [key, value] of request.headers.entries()) {
|
|
const lower = key.toLowerCase();
|
|
if (
|
|
lower.startsWith("host") ||
|
|
lower.startsWith("x-forwarded") ||
|
|
lower.startsWith("x-real-ip") ||
|
|
lower === "content-length" ||
|
|
(!willSendBody && lower === "content-type")
|
|
) {
|
|
continue;
|
|
}
|
|
headers.set(key, value);
|
|
}
|
|
|
|
const init: RequestInit = {
|
|
method: request.method,
|
|
headers,
|
|
};
|
|
if (willSendBody) {
|
|
// Convert ArrayBuffer to Uint8Array to satisfy BodyInit in all environments
|
|
const bodyInit: BodyInit =
|
|
typeof body === "string" ? body : new Uint8Array(body as ArrayBuffer);
|
|
init.body = bodyInit;
|
|
}
|
|
const response = await fetch(backendUrl, init);
|
|
|
|
const responseHeaders = new Headers();
|
|
|
|
// Copy response headers
|
|
for (const [key, value] of response.headers.entries()) {
|
|
if (
|
|
!key.toLowerCase().startsWith("transfer-encoding") &&
|
|
!key.toLowerCase().startsWith("connection")
|
|
) {
|
|
responseHeaders.set(key, value);
|
|
}
|
|
}
|
|
|
|
// For streaming responses, pass the body directly without buffering
|
|
if (response.body) {
|
|
return new NextResponse(response.body, {
|
|
status: response.status,
|
|
statusText: response.statusText,
|
|
headers: responseHeaders,
|
|
});
|
|
} else {
|
|
// Fallback for non-streaming responses
|
|
const responseBody = await response.text();
|
|
return new NextResponse(responseBody, {
|
|
status: response.status,
|
|
statusText: response.statusText,
|
|
headers: responseHeaders,
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error("Proxy error:", error);
|
|
return NextResponse.json(
|
|
{ error: "Failed to proxy request" },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|