/** * Dependency-free Node/Bun HTTP transport that connects only to DNS addresses * already validated by the host egress policy while preserving the original * Host header and TLS SNI name. */ /** * Client identity for guarded egress, standing in for the runtime-supplied * `user-agent` (`node`, `Deno/x.y.z`) that this transport cannot inherit. */ export declare const DEFAULT_OUTBOUND_USER_AGENT = "veryfront/0.1.1253"; export interface PinnedFetchTlsOptions { /** * Complete trusted CA set for this connection. Passing this replaces the * runtime default store, so callers that add a private CA must include the * runtime roots too. */ readonly trustedCaCertificates?: readonly string[]; } /** * Fill in the request headers a plain `fetch` attaches on its own, leaving any * the caller set untouched. This transport talks to `node:http` directly, so * nothing supplies them and requests leave measurably thinner than the same * call made through `fetch` — hosts behind a WAF reject user-agent-less * requests outright, and omitting `accept-encoding` silently gives up response * compression this transport already knows how to decode. * * Values mirror what Node's `fetch` sends, including the two that are derived * rather than fixed: `sec-fetch-mode` follows the request mode, and * `accept-encoding` becomes `identity` for range requests. Exact strings need * not track the runtime version by version — `pinned-fetch.test.ts` asserts * only that no header the runtime sends goes missing, so a runtime that adds * one fails loudly rather than drifting. * * `user-agent` is the deliberate exception: the runtime default (`node`, * `Deno/x.y.z`) cannot be inherited here and identifies nothing useful, so * guarded egress sends DEFAULT_OUTBOUND_USER_AGENT instead. Parity for that * header means "present", not "identical". * * Split out from the transport so that parity check can run on every runtime: * the transport itself is Node/Bun-only, and a test gated on that never * executes in the Deno-only CI lanes. * * @internal */ export declare function applyRuntimeDefaultRequestHeaders(headers: Headers, mode?: RequestMode): Headers; /** @internal Construct a Fetch response without violating null-body statuses. */ export declare function createPinnedFetchResponse(status: number, statusText: string, headers: Headers, body: BodyInit | null, requestMethod?: string): Response; /** * Order the validated addresses into connection attempts. * * Each attempt dials exactly one validated address, so the walk happens here * rather than depending on the runtime: Node honours `autoSelectFamily` and a * custom `lookup`, Bun honours neither. A different family is tried before a * sibling of the one that just failed, because a host with no IPv6 route fails * on every AAAA record its DNS carries. * * Every address is already validated by the egress policy, so trying them in * turn narrows nothing: the set is identical, only the order of use changes. */ export declare function planPinnedConnectAttempts(addresses: readonly string[]): readonly (readonly string[])[]; /** True when the request may be issued again against a different address. */ export declare function isRetriableConnectFailure(error: unknown): boolean; /** * A body may only be replayed when re-reading it yields the same bytes. A * ReadableStream does not qualify: the failed attempt already drained it, so a * retry would send nothing. */ export declare function isReplayableRequestBody(body: BodyInit | null): boolean; /** @internal Used by the central egress guard after DNS policy validation. */ export declare function fetchWithPinnedAddresses(url: URL, addresses: readonly string[], init: RequestInit, tls?: PinnedFetchTlsOptions): Promise; //# sourceMappingURL=pinned-fetch.d.ts.map