Fix streaming auth locally (#2357)

This commit is contained in:
Chris Weaver 2024-09-08 14:01:26 -07:00 committed by GitHub
parent ace041415a
commit be4b6189d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 116 additions and 41 deletions

View File

@ -8,47 +8,6 @@ const version = env_version || package_version;
const nextConfig = {
output: "standalone",
swcMinify: true,
rewrites: async () => {
// In production, something else (nginx in the one box setup) should take
// care of this rewrite. TODO (chris): better support setups where
// web_server and api_server are on different machines.
if (process.env.NODE_ENV === "production") return [];
return [
{
source: "/api/:path*",
destination: "http://127.0.0.1:8080/:path*", // Proxy to Backend
},
];
},
redirects: async () => {
// In production, something else (nginx in the one box setup) should take
// care of this redirect. TODO (chris): better support setups where
// web_server and api_server are on different machines.
const defaultRedirects = [];
if (process.env.NODE_ENV === "production") return defaultRedirects;
return defaultRedirects.concat([
{
source: "/api/chat/send-message:params*",
destination: "http://127.0.0.1:8080/chat/send-message:params*", // Proxy to Backend
permanent: true,
},
{
source: "/api/query/stream-answer-with-quote:params*",
destination:
"http://127.0.0.1:8080/query/stream-answer-with-quote:params*", // Proxy to Backend
permanent: true,
},
{
source: "/api/query/stream-query-validation:params*",
destination:
"http://127.0.0.1:8080/query/stream-query-validation:params*", // Proxy to Backend
permanent: true,
},
]);
},
publicRuntimeConfig: {
version,
},

View File

@ -0,0 +1,116 @@
import { INTERNAL_URL } from "@/lib/constants";
import { NextRequest, NextResponse } from "next/server";
/* NextJS is annoying and makes use use a separate function for
each request type >:( */
export async function GET(
request: NextRequest,
{ params }: { params: { path: string[] } }
) {
return handleRequest(request, params.path);
}
export async function POST(
request: NextRequest,
{ params }: { params: { path: string[] } }
) {
return handleRequest(request, params.path);
}
export async function PUT(
request: NextRequest,
{ params }: { params: { path: string[] } }
) {
return handleRequest(request, params.path);
}
export async function PATCH(
request: NextRequest,
{ params }: { params: { path: string[] } }
) {
return handleRequest(request, params.path);
}
export async function DELETE(
request: NextRequest,
{ params }: { params: { path: string[] } }
) {
return handleRequest(request, params.path);
}
export async function HEAD(
request: NextRequest,
{ params }: { params: { path: string[] } }
) {
return handleRequest(request, params.path);
}
export async function OPTIONS(
request: NextRequest,
{ params }: { params: { path: string[] } }
) {
return handleRequest(request, params.path);
}
async function handleRequest(request: NextRequest, path: string[]) {
if (process.env.NODE_ENV !== "development") {
return NextResponse.json(
{
message:
"This API is only available in development mode. In production, something else (e.g. nginx) should handle this.",
},
{ status: 404 }
);
}
try {
const backendUrl = new URL(`${INTERNAL_URL}/${path.join("/")}`);
// Get the URL parameters from the request
const urlParams = new URLSearchParams(request.url.split("?")[1]);
// Append the URL parameters to the backend URL
urlParams.forEach((value, key) => {
backendUrl.searchParams.append(key, value);
});
const response = await fetch(backendUrl, {
method: request.method,
headers: request.headers,
body: request.body,
// @ts-ignore
duplex: "half",
});
// Check if the response is a stream
if (
response.headers.get("Transfer-Encoding") === "chunked" ||
response.headers.get("Content-Type")?.includes("stream")
) {
// If it's a stream, create a TransformStream to pass the data through
const { readable, writable } = new TransformStream();
response.body?.pipeTo(writable);
return new NextResponse(readable, {
status: response.status,
headers: response.headers,
});
} else {
return new NextResponse(response.body, {
status: response.status,
headers: response.headers,
});
}
} catch (error: unknown) {
console.error("Proxy error:", error);
return NextResponse.json(
{
message: "Proxy error",
error:
error instanceof Error ? error.message : "An unknown error occurred",
},
{ status: 500 }
);
}
}