mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-06 12:41:25 +02:00
support skip tls per request
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import http from "node:http";
|
||||
import https from "node:https";
|
||||
import { Readable } from "node:stream";
|
||||
|
||||
type UpstreamFetchInit = {
|
||||
method: string;
|
||||
headers: Record<string, string>;
|
||||
body?: string;
|
||||
skipTlsVerification?: boolean;
|
||||
};
|
||||
|
||||
const insecureHttpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false,
|
||||
keepAlive: true
|
||||
});
|
||||
|
||||
export function aiGatewayUpstreamFetch(
|
||||
url: string,
|
||||
init: UpstreamFetchInit
|
||||
): Promise<Response> {
|
||||
const parsed = new URL(url);
|
||||
const isHttps = parsed.protocol === "https:";
|
||||
const lib = isHttps ? https : http;
|
||||
const agent =
|
||||
isHttps && init.skipTlsVerification ? insecureHttpsAgent : undefined;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = lib.request(
|
||||
url,
|
||||
{
|
||||
method: init.method,
|
||||
headers: init.headers,
|
||||
agent
|
||||
},
|
||||
(res) => {
|
||||
const headers = new Headers();
|
||||
for (const [key, value] of Object.entries(res.headers)) {
|
||||
if (value === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
for (const entry of value) {
|
||||
headers.append(key, entry);
|
||||
}
|
||||
} else {
|
||||
headers.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
const body = Readable.toWeb(res) as ReadableStream<Uint8Array>;
|
||||
resolve(
|
||||
new Response(body, {
|
||||
status: res.statusCode ?? 502,
|
||||
statusText: res.statusMessage,
|
||||
headers
|
||||
})
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
req.on("error", reject);
|
||||
|
||||
if (init.body !== undefined) {
|
||||
req.write(init.body);
|
||||
}
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
@@ -38,6 +38,7 @@ import { localCache } from "@server/lib/cache";
|
||||
import logger from "@server/logger";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import type { ModelAccessMode } from "@server/lib/aiInferenceResource";
|
||||
import { aiGatewayUpstreamFetch } from "@server/lib/aiGatewayUpstreamFetch";
|
||||
|
||||
// Short-lived local caches so a burst of requests from the same IP/user
|
||||
// doesn't hit the database on every single request. None of this is
|
||||
@@ -544,15 +545,6 @@ export async function handleAiGatewayProxy(
|
||||
);
|
||||
applyAiProviderAuthHeaders(headers, authType, apiKey);
|
||||
|
||||
// No dedicated per-request TLS agent is wired up (no extra deps for
|
||||
// this v1 gateway) - toggle the process-wide Node TLS check instead.
|
||||
// Known limitation: this is not safe under concurrent requests mixing
|
||||
// skipTlsVerification providers with strict ones.
|
||||
const restoreTlsReject = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
||||
if (provider.skipTlsVerification) {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
}
|
||||
|
||||
const body = JSON.stringify(req.body);
|
||||
|
||||
logger.debug("AI gateway upstream request", {
|
||||
@@ -560,15 +552,17 @@ export async function handleAiGatewayProxy(
|
||||
url: targetUrl,
|
||||
method: "POST",
|
||||
headers,
|
||||
body: req.body
|
||||
body: req.body,
|
||||
skipTlsVerification: provider.skipTlsVerification
|
||||
});
|
||||
|
||||
let upstreamRes: globalThis.Response;
|
||||
try {
|
||||
upstreamRes = await fetch(targetUrl, {
|
||||
upstreamRes = await aiGatewayUpstreamFetch(targetUrl, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body
|
||||
body,
|
||||
skipTlsVerification: provider.skipTlsVerification
|
||||
});
|
||||
} catch (fetchError) {
|
||||
logger.error({
|
||||
@@ -581,14 +575,6 @@ export async function handleAiGatewayProxy(
|
||||
: undefined
|
||||
});
|
||||
throw fetchError;
|
||||
} finally {
|
||||
if (provider.skipTlsVerification) {
|
||||
if (restoreTlsReject === undefined) {
|
||||
delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
||||
} else {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = restoreTlsReject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const contentType = upstreamRes.headers.get("content-type") || "";
|
||||
|
||||
Reference in New Issue
Block a user