support streaming and closes properly on site targets

This commit is contained in:
Owen
2026-08-06 17:15:11 -04:00
parent 6c28c5f383
commit 22f2990f56
4 changed files with 92 additions and 18 deletions
+4 -3
View File
@@ -62,9 +62,10 @@ export function joinUpstreamUrl(baseUrl: string, path: string): string {
}
function pathFromRequest(req: Request): string {
// Prefer originalUrl path (includes mounted path) over req.path when available.
const raw =
req.originalUrl?.split("?")[0] || req.url?.split("?")[0] || req.path;
// Prefer originalUrl (includes mounted path) over req.url when available.
// Query string is preserved - some providers use it to select the
// streaming response format (e.g. Gemini's `?alt=sse`).
const raw = req.originalUrl || req.url || req.path;
return raw.startsWith("/") ? raw : `/${raw}`;
}
+14
View File
@@ -7,6 +7,7 @@ type UpstreamFetchInit = {
headers: Record<string, string>;
body?: string;
skipTlsVerification?: boolean;
signal?: AbortSignal;
};
const insecureHttpsAgent = new https.Agent({
@@ -25,6 +26,11 @@ export function aiGatewayUpstreamFetch(
isHttps && init.skipTlsVerification ? insecureHttpsAgent : undefined;
return new Promise((resolve, reject) => {
if (init.signal?.aborted) {
reject(init.signal.reason ?? new Error("Request aborted"));
return;
}
const req = lib.request(
url,
{
@@ -60,6 +66,14 @@ export function aiGatewayUpstreamFetch(
req.on("error", reject);
if (init.signal) {
const onAbort = () => req.destroy(init.signal!.reason);
init.signal.addEventListener("abort", onAbort, { once: true });
req.on("close", () =>
init.signal!.removeEventListener("abort", onAbort)
);
}
if (init.body !== undefined) {
req.write(init.body);
}