tunnelfetch 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +617 -0
  3. package/README.zh-CN.md +470 -0
  4. package/package.json +74 -0
  5. package/src/client/cookies.js +429 -0
  6. package/src/client/decode.js +346 -0
  7. package/src/client/redirect.js +249 -0
  8. package/src/client.js +704 -0
  9. package/src/errors.js +181 -0
  10. package/src/http1/chunked.js +289 -0
  11. package/src/http1/index.js +10 -0
  12. package/src/http1/request.js +143 -0
  13. package/src/http1/response.js +493 -0
  14. package/src/http2/connection.js +1170 -0
  15. package/src/http2/constants.js +129 -0
  16. package/src/http2/frames.js +291 -0
  17. package/src/http2/hpack.js +420 -0
  18. package/src/http2/huffman.js +203 -0
  19. package/src/http2/index.js +21 -0
  20. package/src/index.js +46 -0
  21. package/src/pool.js +256 -0
  22. package/src/proxy/direct.js +62 -0
  23. package/src/proxy/http-connect.js +206 -0
  24. package/src/proxy/index.js +197 -0
  25. package/src/proxy/socks5.js +344 -0
  26. package/src/tls/aead.js +263 -0
  27. package/src/tls/connect.js +407 -0
  28. package/src/tls/constants.js +334 -0
  29. package/src/tls/extensions.js +376 -0
  30. package/src/tls/handshake-messages.js +901 -0
  31. package/src/tls/handshake.js +568 -0
  32. package/src/tls/handshake12.js +507 -0
  33. package/src/tls/index.js +44 -0
  34. package/src/tls/keyschedule.js +473 -0
  35. package/src/tls/record.js +872 -0
  36. package/src/tls/tickets.js +145 -0
  37. package/src/tls/transcript.js +101 -0
  38. package/src/tls/wire.js +224 -0
  39. package/src/transport.js +296 -0
  40. package/src/trust/der.js +551 -0
  41. package/src/trust/index.js +375 -0
  42. package/src/trust/name.js +235 -0
  43. package/src/trust/ocsp.js +759 -0
  44. package/src/trust/path.js +595 -0
  45. package/src/trust/roots.js +454 -0
  46. package/src/trust/x509.js +902 -0
  47. package/src/util/bytes.js +470 -0
  48. package/src/util/deadline.js +266 -0
  49. package/src/warmup-fixture.js +85 -0
  50. package/src/warmup.js +243 -0
  51. package/types/client/cookies.d.ts +159 -0
  52. package/types/client/decode.d.ts +54 -0
  53. package/types/client/redirect.d.ts +96 -0
  54. package/types/client.d.ts +323 -0
  55. package/types/errors.d.ts +141 -0
  56. package/types/http1/chunked.d.ts +48 -0
  57. package/types/http1/index.d.ts +3 -0
  58. package/types/http1/request.d.ts +44 -0
  59. package/types/http1/response.d.ts +183 -0
  60. package/types/http2/connection.d.ts +282 -0
  61. package/types/http2/constants.d.ts +95 -0
  62. package/types/http2/frames.d.ts +116 -0
  63. package/types/http2/hpack.d.ts +99 -0
  64. package/types/http2/huffman.d.ts +21 -0
  65. package/types/http2/index.d.ts +5 -0
  66. package/types/index.d.ts +17 -0
  67. package/types/pool.d.ts +135 -0
  68. package/types/proxy/direct.d.ts +26 -0
  69. package/types/proxy/http-connect.d.ts +37 -0
  70. package/types/proxy/index.d.ts +62 -0
  71. package/types/proxy/socks5.d.ts +47 -0
  72. package/types/tls/aead.d.ts +67 -0
  73. package/types/tls/connect.d.ts +280 -0
  74. package/types/tls/constants.d.ts +275 -0
  75. package/types/tls/extensions.d.ts +195 -0
  76. package/types/tls/handshake-messages.d.ts +430 -0
  77. package/types/tls/handshake.d.ts +90 -0
  78. package/types/tls/handshake12.d.ts +35 -0
  79. package/types/tls/index.d.ts +9 -0
  80. package/types/tls/keyschedule.d.ts +272 -0
  81. package/types/tls/record.d.ts +361 -0
  82. package/types/tls/tickets.d.ts +66 -0
  83. package/types/tls/transcript.d.ts +52 -0
  84. package/types/tls/wire.d.ts +106 -0
  85. package/types/transport.d.ts +222 -0
  86. package/types/trust/der.d.ts +239 -0
  87. package/types/trust/index.d.ts +194 -0
  88. package/types/trust/name.d.ts +33 -0
  89. package/types/trust/ocsp.d.ts +138 -0
  90. package/types/trust/path.d.ts +139 -0
  91. package/types/trust/roots.d.ts +36 -0
  92. package/types/trust/x509.d.ts +401 -0
  93. package/types/util/bytes.d.ts +183 -0
  94. package/types/util/deadline.d.ts +133 -0
  95. package/types/warmup-fixture.d.ts +11 -0
  96. package/types/warmup.d.ts +45 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Parse a cookie date per RFC 6265 s5.1.1 — NOT Date.parse. Date.parse accepts formats the
3
+ * RFC rejects, rejects formats the RFC accepts (two-digit years, odd delimiters), and differs
4
+ * between engines; cookies from 1990s-era servers still use every shape the RFC grandfathers.
5
+ *
6
+ * The algorithm: split into tokens on "delimiters", then find — in any order, first match per
7
+ * category wins — a time (hh:mm:ss), a day (1-2 digits), a month (3-letter name), and a year
8
+ * (2-4 digits). Each token may carry trailing non-digit junk after the match.
9
+ *
10
+ * @param {string} s
11
+ * @returns {number|null} epoch milliseconds UTC, or null if the string is not a cookie date.
12
+ */
13
+ export function parseCookieDate(s: string): number | null;
14
+ /**
15
+ * RFC 6265 s5.1.4: the default path is the request path up to (not including) its last '/'.
16
+ * @param {string} requestPath
17
+ * @returns {string}
18
+ */
19
+ export function defaultPath(requestPath: string): string;
20
+ /**
21
+ * RFC 6265 s5.1.4 path-match.
22
+ * @param {string} requestPath
23
+ * @param {string} cookiePath
24
+ * @returns {boolean}
25
+ */
26
+ export function pathMatches(requestPath: string, cookiePath: string): boolean;
27
+ /**
28
+ * RFC 6265 s5.1.3 domain-match: exact, or host ends with '.' + domain.
29
+ * @param {string} host
30
+ * @param {string} cookieDomain
31
+ * @returns {boolean}
32
+ */
33
+ export function domainMatches(host: string, cookieDomain: string): boolean;
34
+ /**
35
+ * A stored cookie, as entries() exposes it. Records are live jar state, not copies.
36
+ * @typedef {object} Cookie
37
+ * @property {string} name
38
+ * @property {string} value quotes already stripped
39
+ * @property {string} domain lowercased; the Domain attribute, or the request host
40
+ * @property {boolean} hostOnly true when no Domain attribute applied — exact-host match only
41
+ * @property {string} path
42
+ * @property {boolean} secure
43
+ * @property {boolean} httpOnly
44
+ * @property {string | null} sameSite lowercased attribute value, stored verbatim — servers send
45
+ * values outside strict/lax/none and this jar does not enforce SameSite anyway
46
+ * @property {number} expiry epoch ms; Infinity for a session cookie
47
+ * @property {number} creation epoch ms from the injected clock, kept across overwrites (s5.3)
48
+ * @property {number} seq creation-order tiebreak for the frozen-clock runtime
49
+ */
50
+ /**
51
+ * @typedef {object} CookieJarOptions
52
+ * @property {() => number} [now] injectable clock returning epoch ms. On the target runtime
53
+ * Date.now() freezes for a whole execution slice, so expiry must be testable via this knob.
54
+ * @property {number} [maxCookies] global cap, default 3000
55
+ * @property {number} [maxPerDomain] per-domain cap, default 50
56
+ */
57
+ export class CookieJar {
58
+ /**
59
+ * @param {CookieJarOptions} [options]
60
+ * The caps exist because this jar lives inside a long-lived Worker isolate: an unbounded
61
+ * jar fed by a hostile or merely enthusiastic server is a slow memory leak, so overflow
62
+ * evicts the oldest cookies instead of growing.
63
+ */
64
+ constructor({ now, maxCookies, maxPerDomain }?: CookieJarOptions);
65
+ _now: () => number;
66
+ _maxCookies: number;
67
+ _maxPerDomain: number;
68
+ /** @type {Map<string, Cookie>} key "domain|path|name" -> cookie record */
69
+ _cookies: Map<string, Cookie>;
70
+ _rejected: number;
71
+ /** Count of Set-Cookie values ignored per RFC rules — the observability hook. */
72
+ get rejected(): number;
73
+ get size(): number;
74
+ /**
75
+ * Ingest the Set-Cookie values of one response. Never throws on a bad cookie — rejection is
76
+ * silent per RFC 6265, counted in `rejected`.
77
+ * @param {string|URL} url the request URL the response belongs to
78
+ * @param {string[]} setCookieValues one array entry per Set-Cookie header
79
+ * @returns {void}
80
+ */
81
+ setFromResponse(url: string | URL, setCookieValues: string[]): void;
82
+ /**
83
+ * @param {string} host
84
+ * @param {boolean} requestSecure
85
+ * @param {string} requestPath
86
+ * @param {string} setCookie
87
+ * @returns {boolean} stored or deliberately deleted (true) vs ignored (false)
88
+ */
89
+ _setOne(host: string, requestSecure: boolean, requestPath: string, setCookie: string): boolean;
90
+ /**
91
+ * Evict expired cookies first, then the oldest by creation, per-domain then globally.
92
+ * @param {string} domain
93
+ */
94
+ _enforceCaps(domain: string): void;
95
+ /**
96
+ * The Cookie header value for a request, or null if no cookie matches.
97
+ * @param {string|URL} url
98
+ * @returns {string | null}
99
+ */
100
+ headerFor(url: string | URL): string | null;
101
+ /**
102
+ * Everything currently stored, for tests and debugging. Records are live; do not mutate.
103
+ * @returns {Cookie[]}
104
+ */
105
+ entries(): Cookie[];
106
+ }
107
+ /**
108
+ * A stored cookie, as entries() exposes it. Records are live jar state, not copies.
109
+ */
110
+ export type Cookie = {
111
+ name: string;
112
+ /**
113
+ * quotes already stripped
114
+ */
115
+ value: string;
116
+ /**
117
+ * lowercased; the Domain attribute, or the request host
118
+ */
119
+ domain: string;
120
+ /**
121
+ * true when no Domain attribute applied — exact-host match only
122
+ */
123
+ hostOnly: boolean;
124
+ path: string;
125
+ secure: boolean;
126
+ httpOnly: boolean;
127
+ /**
128
+ * lowercased attribute value, stored verbatim — servers send
129
+ * values outside strict/lax/none and this jar does not enforce SameSite anyway
130
+ */
131
+ sameSite: string | null;
132
+ /**
133
+ * epoch ms; Infinity for a session cookie
134
+ */
135
+ expiry: number;
136
+ /**
137
+ * epoch ms from the injected clock, kept across overwrites (s5.3)
138
+ */
139
+ creation: number;
140
+ /**
141
+ * creation-order tiebreak for the frozen-clock runtime
142
+ */
143
+ seq: number;
144
+ };
145
+ export type CookieJarOptions = {
146
+ /**
147
+ * injectable clock returning epoch ms. On the target runtime
148
+ * Date.now() freezes for a whole execution slice, so expiry must be testable via this knob.
149
+ */
150
+ now?: (() => number) | undefined;
151
+ /**
152
+ * global cap, default 3000
153
+ */
154
+ maxCookies?: number | undefined;
155
+ /**
156
+ * per-domain cap, default 50
157
+ */
158
+ maxPerDomain?: number | undefined;
159
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Undo the response's Content-Encoding.
3
+ *
4
+ * @param {ReadableStream<Uint8Array>} stream the raw body
5
+ * @param {string|null|undefined} contentEncoding the Content-Encoding header value; a
6
+ * comma-separated list names codings in the order the SERVER applied them, so decoding
7
+ * applies them in reverse.
8
+ * @returns {ReadableStream<Uint8Array>} decoded bytes
9
+ */
10
+ export function decodeBody(stream: ReadableStream<Uint8Array>, contentEncoding: string | null | undefined): ReadableStream<Uint8Array>;
11
+ /**
12
+ * Extract the charset parameter from a Content-Type value, handling quoting and other
13
+ * parameters: `text/html; boundary=x; charset="ISO-8859-4"` -> 'iso-8859-4'.
14
+ * @param {string | null | undefined} contentType
15
+ * @returns {string|null} lowercased charset label, or null when none is declared
16
+ */
17
+ export function charsetFromContentType(contentType: string | null | undefined): string | null;
18
+ /**
19
+ * Decide the charset for a response body.
20
+ *
21
+ * Precedence: BOM > Content-Type charset parameter > (text/html only) meta prescan > utf-8.
22
+ * The BOM outranks even an explicit header because it describes the actual bytes, and servers
23
+ * that recode content routinely forget to update the header; this is WHATWG "decode" order.
24
+ * The utf-8 default matches Response.text() in fetch — for a client whose callers are code,
25
+ * matching fetch is worth more than matching the legacy HTML default of windows-1252.
26
+ *
27
+ * @param {string|null|undefined} contentType
28
+ * @param {Uint8Array} [bodyPrefix] the first bytes of the body (>= 1024 to satisfy the prescan)
29
+ * @returns {string} a charset label for decodeText
30
+ */
31
+ export function charsetFor(contentType: string | null | undefined, bodyPrefix?: Uint8Array): string;
32
+ /**
33
+ * Decode bytes with a charset label.
34
+ *
35
+ * TextDecoder implements the WHATWG encoding registry, which is the alias table every browser
36
+ * uses. Note one alias that looks like a bug and is not: `iso-8859-1` (and `latin1`, `ascii`)
37
+ * maps to windows-1252, per WHATWG — the bytes 0x80-0x9F decode to the punctuation everyone
38
+ * actually means, not C1 controls. A BOM matching the charset is stripped (TextDecoder default),
39
+ * which is also what Response.text() does.
40
+ *
41
+ * Throws HttpError (HTTP_CHARSET) for a label outside the WHATWG encoding registry.
42
+ *
43
+ * @param {Uint8Array} bytes
44
+ * @param {string} [charset]
45
+ * @returns {string}
46
+ */
47
+ export function decodeText(bytes: Uint8Array, charset?: string): string;
48
+ /**
49
+ * The exact Accept-Encoding value the request layer must send. The target runtime's
50
+ * DecompressionStream supports ONLY gzip / deflate / deflate-raw (verified empirically);
51
+ * advertising `br` or `zstd` would invite bytes we can never decode, turning every response
52
+ * from a brotli-preferring CDN into garbage. Keep this list and decodeBody in lockstep.
53
+ */
54
+ export const ACCEPT_ENCODING: "gzip, deflate";
@@ -0,0 +1,96 @@
1
+ /**
2
+ * @param {number} status
3
+ * @param {string} [method] accepted for API symmetry; the status alone decides, because even a
4
+ * combination we will rewrite (303 + POST) is still a redirect — it just mutates the method.
5
+ * @returns {boolean}
6
+ */
7
+ export function shouldRedirect(status: number, method?: string): boolean;
8
+ /**
9
+ * Resolve a Location header against the current URL, enforcing the scheme allow-list.
10
+ * Throws HttpError for a missing/unparseable Location or a non-http(s) scheme.
11
+ * @param {URL} currentUrl
12
+ * @param {string|null|undefined} location
13
+ * @returns {URL}
14
+ */
15
+ export function resolveLocation(currentUrl: URL, location: string | null | undefined): URL;
16
+ /**
17
+ * A request as the redirect engine consumes it. Bodies stay in whatever form the caller holds
18
+ * them; this layer only decides whether they survive the hop, never reads them.
19
+ * @typedef {Uint8Array | string | ReadableStream<Uint8Array> | null} RedirectBody
20
+ * @typedef {object} RedirectableRequest
21
+ * @property {string} method
22
+ * @property {string | URL} url
23
+ * @property {Headers | Record<string, string>} [headers]
24
+ * @property {RedirectBody} [body]
25
+ */
26
+ /**
27
+ * The follow-up request. `url` and `headers` are always normalised instances; `body` is the
28
+ * caller's own value passed through, or null when the method rewrite dropped it.
29
+ * @typedef {object} NextRequest
30
+ * @property {string} method
31
+ * @property {URL} url
32
+ * @property {Headers} headers credential and body-describing headers already stripped per the
33
+ * rules above
34
+ * @property {RedirectBody} body
35
+ */
36
+ /**
37
+ * @typedef {object} NextRequestOptions
38
+ * @property {number} [maxRedirects] default 20
39
+ * @property {string[]} [history] pass the SAME array across every hop of one logical fetch; it
40
+ * is both the loop detector and the hop counter
41
+ */
42
+ /**
43
+ * Compute the follow-up request for a redirect response. Throws rather than returning a
44
+ * failure: LimitError past `maxRedirects`, HttpError for loops and bad Locations, ConfigError
45
+ * for a non-redirect status or an unreplayable stream body on 307/308.
46
+ *
47
+ * @param {RedirectableRequest} current
48
+ * @param {{ status: number, headers: Headers|Record<string,string> }} response
49
+ * @param {NextRequestOptions} [options]
50
+ * @returns {NextRequest}
51
+ */
52
+ export function nextRequest(current: RedirectableRequest, response: {
53
+ status: number;
54
+ headers: Headers | Record<string, string>;
55
+ }, options?: NextRequestOptions): NextRequest;
56
+ export const DEFAULT_MAX_REDIRECTS: 20;
57
+ /**
58
+ * A request as the redirect engine consumes it. Bodies stay in whatever form the caller holds
59
+ * them; this layer only decides whether they survive the hop, never reads them.
60
+ */
61
+ export type RedirectBody = Uint8Array | string | ReadableStream<Uint8Array> | null;
62
+ /**
63
+ * A request as the redirect engine consumes it. Bodies stay in whatever form the caller holds
64
+ * them; this layer only decides whether they survive the hop, never reads them.
65
+ */
66
+ export type RedirectableRequest = {
67
+ method: string;
68
+ url: string | URL;
69
+ headers?: Headers | Record<string, string> | undefined;
70
+ body?: RedirectBody | undefined;
71
+ };
72
+ /**
73
+ * The follow-up request. `url` and `headers` are always normalised instances; `body` is the
74
+ * caller's own value passed through, or null when the method rewrite dropped it.
75
+ */
76
+ export type NextRequest = {
77
+ method: string;
78
+ url: URL;
79
+ /**
80
+ * credential and body-describing headers already stripped per the
81
+ * rules above
82
+ */
83
+ headers: Headers;
84
+ body: RedirectBody;
85
+ };
86
+ export type NextRequestOptions = {
87
+ /**
88
+ * default 20
89
+ */
90
+ maxRedirects?: number | undefined;
91
+ /**
92
+ * pass the SAME array across every hop of one logical fetch; it
93
+ * is both the loop detector and the hop counter
94
+ */
95
+ history?: string[] | undefined;
96
+ };
@@ -0,0 +1,323 @@
1
+ /**
2
+ * A standalone fetch bound to a configuration, matching httpx's module-level helpers. Creates and
3
+ * closes a Client per call, so no connection is reused; use `new Client()` when reuse matters.
4
+ *
5
+ * @param {ClientOptions} [options]
6
+ * @returns {FetchLike}
7
+ */
8
+ export function createFetch(options?: ClientOptions): FetchLike;
9
+ /**
10
+ * Replace `globalThis.fetch`, for libraries that only accept the global. Returns the undo.
11
+ * Never called automatically, and never on import.
12
+ *
13
+ * @param {ClientOptions} [options]
14
+ * @returns {() => void} uninstall; idempotent, and a no-op if someone else has since taken the global
15
+ */
16
+ export function install(options?: ClientOptions): () => void;
17
+ /**
18
+ * A `fetch`-shaped function. Deliberately the platform's own signature: being assignable to
19
+ * `typeof fetch` is what lets an SDK accept this in place of the global without adapting.
20
+ * @typedef {(input: RequestInfo | URL, init?: RequestInit) => Promise<Response>} FetchLike
21
+ */
22
+ /**
23
+ * What a Response carries about the connection that produced it, under the non-standard
24
+ * `tunnelfetch` property.
25
+ * @typedef {object} ResponseDetail
26
+ * @property {string} url
27
+ * @property {boolean} proxied
28
+ * @property {string | null} proxy the proxy actually used, credentials omitted
29
+ * @property {import('./tls/connect.js').TlsSessionInfo | null} tls null for cleartext
30
+ * @property {'1.0' | '1.1' | '2'} httpVersion '2' when ALPN negotiated HTTP/2
31
+ * @property {'none' | 'content-length' | 'chunked' | 'until-close' | 'h2'} framing 'h2' when the
32
+ * body was delimited by an HTTP/2 END_STREAM rather than by any HTTP/1.1 framing rule
33
+ */
34
+ /**
35
+ * Limits on what a peer may make us buffer. Each is a fail-closed cap, not a hint.
36
+ * @typedef {object} Limits
37
+ * @property {number} [maxHeaderBytes] response head, default 65536
38
+ * @property {number} [maxProxyReplyBytes] proxy CONNECT reply head, default 32768
39
+ */
40
+ /**
41
+ * @typedef {object} ClientOptions
42
+ * @property {import('./proxy/index.js').ConnectFn} [connect] Socket factory. Required for any
43
+ * request the platform's own `fetch` cannot serve — which is every proxied request, and every
44
+ * request asking for a trust policy `fetch` cannot express.
45
+ * @property {string | import('./proxy/index.js').ProxyConfig | null} [proxy] URL string or
46
+ * config object; `http:`, `https:`, `socks5:` and `socks5h:`.
47
+ * @property {import('./trust/index.js').TrustConfig} [trust] certificate policy, httpx's
48
+ * `verify=`. Default `{ mode: 'system' }`.
49
+ * @property {import('./tls/connect.js').TlsOptions} [tls] handshake knobs.
50
+ * @property {import('./util/deadline.js').DeadlineOptions} [timeouts] connect / handshake /
51
+ * headers / idle / total, in ms. The idle gap is the control; total is a backstop.
52
+ * @property {boolean} [cookies] enable a per-Client cookie jar.
53
+ * @property {import('./client/cookies.js').CookieJar} [jar] supply a jar directly, e.g. to share
54
+ * one across Clients or to persist it.
55
+ * @property {number} [maxRedirects] default 20.
56
+ * @property {number} [maxBodyBytes] enforced from Content-Length before a byte is read.
57
+ * @property {boolean} [decompress] gzip/deflate. Default true. Never `br`; the runtime cannot
58
+ * decompress it, so it is never advertised either.
59
+ * @property {boolean} [keepAlive] default true.
60
+ * @property {boolean} [http2] offer HTTP/2 via ALPN and speak it when the server selects it.
61
+ * Default true. The goal is ACCESS, not speed — some sites treat HTTP/1.1 as a bot signal — and
62
+ * on a CPU-billed runtime h2 costs MORE than h1 (HPACK is extra work). Set false to offer only
63
+ * `http/1.1`. There is no fallback-and-retry either way: the server's ALPN pick is followed.
64
+ * @property {boolean} [forceTunnel] never delegate to the platform's fetch, even when it could
65
+ * serve the request. Mainly for exercising this stack against origins that do not need it.
66
+ * @property {FetchLike} [nativeFetch] delegation target; defaults to `globalThis.fetch`.
67
+ * @property {{ maxPerKey?: number, maxTotal?: number }} [pool] connection pool sizing.
68
+ * @property {Limits} [limits]
69
+ * @property {import('./tls/connect.js').TlsDeps} [deps] injectable randomness and key generation.
70
+ * @property {AbortSignal} [signal] aborts every request this Client makes.
71
+ * @property {number} [now] epoch ms override, for certificate validity in tests.
72
+ */
73
+ export class Client {
74
+ /**
75
+ * @param {ClientOptions} [options]
76
+ */
77
+ constructor(options?: ClientOptions);
78
+ options: {
79
+ /**
80
+ * Socket factory. Required for any
81
+ * request the platform's own `fetch` cannot serve — which is every proxied request, and every
82
+ * request asking for a trust policy `fetch` cannot express.
83
+ */
84
+ connect?: import("./proxy/index.js").ConnectFn | undefined;
85
+ /**
86
+ * URL string or
87
+ * config object; `http:`, `https:`, `socks5:` and `socks5h:`.
88
+ */
89
+ proxy?: string | import("./proxy/index.js").ProxyConfig | null | undefined;
90
+ /**
91
+ * certificate policy, httpx's
92
+ * `verify=`. Default `{ mode: 'system' }`.
93
+ */
94
+ trust?: import("./trust/index.js").TrustConfig | undefined;
95
+ /**
96
+ * handshake knobs.
97
+ */
98
+ tls?: import("./tls/connect.js").TlsOptions | undefined;
99
+ /**
100
+ * connect / handshake /
101
+ * headers / idle / total, in ms. The idle gap is the control; total is a backstop.
102
+ */
103
+ timeouts?: import("./util/deadline.js").DeadlineOptions | undefined;
104
+ /**
105
+ * enable a per-Client cookie jar.
106
+ */
107
+ cookies?: boolean | undefined;
108
+ /**
109
+ * supply a jar directly, e.g. to share
110
+ * one across Clients or to persist it.
111
+ */
112
+ jar?: CookieJar | undefined;
113
+ /**
114
+ * default 20.
115
+ */
116
+ maxRedirects?: number | undefined;
117
+ /**
118
+ * enforced from Content-Length before a byte is read.
119
+ */
120
+ maxBodyBytes?: number | undefined;
121
+ /**
122
+ * gzip/deflate. Default true. Never `br`; the runtime cannot
123
+ * decompress it, so it is never advertised either.
124
+ */
125
+ decompress?: boolean | undefined;
126
+ /**
127
+ * default true.
128
+ */
129
+ keepAlive?: boolean | undefined;
130
+ /**
131
+ * offer HTTP/2 via ALPN and speak it when the server selects it.
132
+ * Default true. The goal is ACCESS, not speed — some sites treat HTTP/1.1 as a bot signal — and
133
+ * on a CPU-billed runtime h2 costs MORE than h1 (HPACK is extra work). Set false to offer only
134
+ * `http/1.1`. There is no fallback-and-retry either way: the server's ALPN pick is followed.
135
+ */
136
+ http2?: boolean | undefined;
137
+ /**
138
+ * never delegate to the platform's fetch, even when it could
139
+ * serve the request. Mainly for exercising this stack against origins that do not need it.
140
+ */
141
+ forceTunnel?: boolean | undefined;
142
+ /**
143
+ * delegation target; defaults to `globalThis.fetch`.
144
+ */
145
+ nativeFetch?: FetchLike | undefined;
146
+ /**
147
+ * connection pool sizing.
148
+ */
149
+ pool?: {
150
+ maxPerKey?: number;
151
+ maxTotal?: number;
152
+ } | undefined;
153
+ limits?: Limits | undefined;
154
+ /**
155
+ * injectable randomness and key generation.
156
+ */
157
+ deps?: import("./tls/connect.js").TlsDeps | undefined;
158
+ /**
159
+ * aborts every request this Client makes.
160
+ */
161
+ signal?: AbortSignal | undefined;
162
+ /**
163
+ * epoch ms override, for certificate validity in tests.
164
+ */
165
+ now?: number | undefined;
166
+ };
167
+ pool: ConnectionPool;
168
+ /** @type {Map<string, import('./http2/connection.js').Http2Connection>} */
169
+ _h2: Map<string, import("./http2/connection.js").Http2Connection>;
170
+ /** @type {Set<import('./http2/connection.js').Http2Connection>} */
171
+ _h2conns: Set<import("./http2/connection.js").Http2Connection>;
172
+ jar: CookieJar | null;
173
+ tickets: TicketStore;
174
+ _closed: boolean;
175
+ /**
176
+ * @param {RequestInfo | URL} input
177
+ * @param {RequestInit} [init]
178
+ * @returns {Promise<Response & { tunnelfetch?: ResponseDetail }>}
179
+ */
180
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response & {
181
+ tunnelfetch?: ResponseDetail;
182
+ }>;
183
+ /** Release every pooled socket and shared HTTP/2 connection. A Client that is finished must be
184
+ * closed or sockets leak for the isolate's lifetime. */
185
+ close(): Promise<void>;
186
+ }
187
+ /**
188
+ * A `fetch`-shaped function. Deliberately the platform's own signature: being assignable to
189
+ * `typeof fetch` is what lets an SDK accept this in place of the global without adapting.
190
+ */
191
+ export type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
192
+ /**
193
+ * What a Response carries about the connection that produced it, under the non-standard
194
+ * `tunnelfetch` property.
195
+ */
196
+ export type ResponseDetail = {
197
+ url: string;
198
+ proxied: boolean;
199
+ /**
200
+ * the proxy actually used, credentials omitted
201
+ */
202
+ proxy: string | null;
203
+ /**
204
+ * null for cleartext
205
+ */
206
+ tls: import("./tls/connect.js").TlsSessionInfo | null;
207
+ /**
208
+ * '2' when ALPN negotiated HTTP/2
209
+ */
210
+ httpVersion: "1.0" | "1.1" | "2";
211
+ /**
212
+ * 'h2' when the
213
+ * body was delimited by an HTTP/2 END_STREAM rather than by any HTTP/1.1 framing rule
214
+ */
215
+ framing: "none" | "content-length" | "chunked" | "until-close" | "h2";
216
+ };
217
+ /**
218
+ * Limits on what a peer may make us buffer. Each is a fail-closed cap, not a hint.
219
+ */
220
+ export type Limits = {
221
+ /**
222
+ * response head, default 65536
223
+ */
224
+ maxHeaderBytes?: number | undefined;
225
+ /**
226
+ * proxy CONNECT reply head, default 32768
227
+ */
228
+ maxProxyReplyBytes?: number | undefined;
229
+ };
230
+ export type ClientOptions = {
231
+ /**
232
+ * Socket factory. Required for any
233
+ * request the platform's own `fetch` cannot serve — which is every proxied request, and every
234
+ * request asking for a trust policy `fetch` cannot express.
235
+ */
236
+ connect?: import("./proxy/index.js").ConnectFn | undefined;
237
+ /**
238
+ * URL string or
239
+ * config object; `http:`, `https:`, `socks5:` and `socks5h:`.
240
+ */
241
+ proxy?: string | import("./proxy/index.js").ProxyConfig | null | undefined;
242
+ /**
243
+ * certificate policy, httpx's
244
+ * `verify=`. Default `{ mode: 'system' }`.
245
+ */
246
+ trust?: import("./trust/index.js").TrustConfig | undefined;
247
+ /**
248
+ * handshake knobs.
249
+ */
250
+ tls?: import("./tls/connect.js").TlsOptions | undefined;
251
+ /**
252
+ * connect / handshake /
253
+ * headers / idle / total, in ms. The idle gap is the control; total is a backstop.
254
+ */
255
+ timeouts?: import("./util/deadline.js").DeadlineOptions | undefined;
256
+ /**
257
+ * enable a per-Client cookie jar.
258
+ */
259
+ cookies?: boolean | undefined;
260
+ /**
261
+ * supply a jar directly, e.g. to share
262
+ * one across Clients or to persist it.
263
+ */
264
+ jar?: CookieJar | undefined;
265
+ /**
266
+ * default 20.
267
+ */
268
+ maxRedirects?: number | undefined;
269
+ /**
270
+ * enforced from Content-Length before a byte is read.
271
+ */
272
+ maxBodyBytes?: number | undefined;
273
+ /**
274
+ * gzip/deflate. Default true. Never `br`; the runtime cannot
275
+ * decompress it, so it is never advertised either.
276
+ */
277
+ decompress?: boolean | undefined;
278
+ /**
279
+ * default true.
280
+ */
281
+ keepAlive?: boolean | undefined;
282
+ /**
283
+ * offer HTTP/2 via ALPN and speak it when the server selects it.
284
+ * Default true. The goal is ACCESS, not speed — some sites treat HTTP/1.1 as a bot signal — and
285
+ * on a CPU-billed runtime h2 costs MORE than h1 (HPACK is extra work). Set false to offer only
286
+ * `http/1.1`. There is no fallback-and-retry either way: the server's ALPN pick is followed.
287
+ */
288
+ http2?: boolean | undefined;
289
+ /**
290
+ * never delegate to the platform's fetch, even when it could
291
+ * serve the request. Mainly for exercising this stack against origins that do not need it.
292
+ */
293
+ forceTunnel?: boolean | undefined;
294
+ /**
295
+ * delegation target; defaults to `globalThis.fetch`.
296
+ */
297
+ nativeFetch?: FetchLike | undefined;
298
+ /**
299
+ * connection pool sizing.
300
+ */
301
+ pool?: {
302
+ maxPerKey?: number;
303
+ maxTotal?: number;
304
+ } | undefined;
305
+ limits?: Limits | undefined;
306
+ /**
307
+ * injectable randomness and key generation.
308
+ */
309
+ deps?: import("./tls/connect.js").TlsDeps | undefined;
310
+ /**
311
+ * aborts every request this Client makes.
312
+ */
313
+ signal?: AbortSignal | undefined;
314
+ /**
315
+ * epoch ms override, for certificate validity in tests.
316
+ */
317
+ now?: number | undefined;
318
+ };
319
+ import { CookieJar } from './client/cookies.js';
320
+ import { ConnectionPool } from './pool.js';
321
+ import { TicketStore } from './tls/tickets.js';
322
+ import { utf8 } from './util/bytes.js';
323
+ export { CookieJar, ConnectionPool, utf8 };