// TLS-tolerant fetch for LAN calls to operator-managed services that // use StartOS Local Intermediate CA certs (or other self-signed certs) // the relay container doesn't trust by default. // // Scope: Spark Control discovery + diarize-chunk POST. Those are the // only HTTPS endpoints the relay talks to over the operator's own // LAN. Public-internet calls (Gemini, Keysat, BTCPay) keep going // through the normal global fetch with full cert validation — we // don't pipe those through this helper. // // Safety: the URL passed in came from the operator's own config // (Service Discovery URL field). The relay isn't auto-discovering or // following untrusted redirects to arbitrary hosts. // // Implementation: undici's Agent supports per-dispatcher // rejectUnauthorized control; Node's built-in fetch globally does // not. We construct one Agent at module init and pass it as the // dispatcher on every call. import { Agent, fetch as undiciFetch } from "undici"; const lanAgent = new Agent({ connect: { rejectUnauthorized: false }, // 5s for TCP+TLS handshake — long enough for cold StartOS sockets, // short enough to fail fast on a bad URL. connectTimeout: 5000, // Diarize-chunk and transcribe on the operator's GPU box are slow // (Sortformer + TitaNet on a 5-min chunk can run 30-120s before // SC sends back response headers). headersTimeout/bodyTimeout = 0 // disables undici's own watchdog — we rely entirely on the // AbortSignal.timeout the caller passes (900s by default for // hardware backend calls). Without this, lanFetch was killing the // connection at 10s with a bare "fetch failed" before SC had any // chance to respond. headersTimeout: 0, bodyTimeout: 0, }); export async function lanFetch(url, opts = {}) { return undiciFetch(url, { ...opts, dispatcher: lanAgent }); }