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,133 @@
1
+ /**
2
+ * Wrap a body stream so every chunk touches the idle deadline and an abort surfaces as the typed
3
+ * timeout error rather than a bare AbortError.
4
+ *
5
+ * The stream is consumed with a plain reader rather than piped through a TransformStream because
6
+ * a transform would buffer a chunk ahead, which is exactly the wrong behaviour for an idle
7
+ * deadline: the timer must be reset by data reaching the consumer, not by data reaching a queue.
8
+ *
9
+ * @param {ReadableStream<Uint8Array>} source
10
+ * @param {DeadlineController} deadlines
11
+ */
12
+ export function withIdleDeadline(source: ReadableStream<Uint8Array>, deadlines: DeadlineController): ReadableStream<any>;
13
+ /**
14
+ * One-shot deadline for a promise that has no stream behind it, e.g. a socket's `opened`.
15
+ * Prefer DeadlineController when several phases share a teardown.
16
+ */
17
+ export function withDeadline(promise: any, ms: any, code: any, what: any, env?: {}): any;
18
+ /**
19
+ * @typedef {object} DeadlineOptions
20
+ * @property {number} [connectMs] TCP connect (and proxy handshake) must complete within this
21
+ * @property {number} [handshakeMs] TLS handshake must complete within this
22
+ * @property {number} [headersMs] response status line + headers must arrive within this
23
+ * @property {number} [idleMs] maximum gap between body chunks
24
+ * @property {number} [totalMs] hard ceiling on the whole request; a backstop, not the control
25
+ */
26
+ export const DEFAULT_DEADLINES: Readonly<{
27
+ connectMs: 10000;
28
+ handshakeMs: 15000;
29
+ headersMs: 30000;
30
+ idleMs: 60000;
31
+ totalMs: 0;
32
+ }>;
33
+ /**
34
+ * Owns every timer for one request and exposes a single AbortSignal that fires when any of them
35
+ * elapses. Callers abort on the signal rather than each racing their own promise, so a timeout in
36
+ * one phase tears down the whole connection instead of leaking a socket into the background.
37
+ */
38
+ export class DeadlineController {
39
+ /**
40
+ * @param {DeadlineOptions} options
41
+ * @param {{ signal?: AbortSignal, setTimer?: typeof setTimeout, clearTimer?: typeof clearTimeout }} [env]
42
+ */
43
+ constructor(options?: DeadlineOptions, env?: {
44
+ signal?: AbortSignal;
45
+ setTimer?: typeof setTimeout;
46
+ clearTimer?: typeof clearTimeout;
47
+ });
48
+ options: {
49
+ /**
50
+ * TCP connect (and proxy handshake) must complete within this
51
+ */
52
+ connectMs: number;
53
+ /**
54
+ * TLS handshake must complete within this
55
+ */
56
+ handshakeMs: number;
57
+ /**
58
+ * response status line + headers must arrive within this
59
+ */
60
+ headersMs: number;
61
+ /**
62
+ * maximum gap between body chunks
63
+ */
64
+ idleMs: number;
65
+ /**
66
+ * hard ceiling on the whole request; a backstop, not the control
67
+ */
68
+ totalMs: number;
69
+ };
70
+ _setTimer: typeof setTimeout;
71
+ _clearTimer: typeof clearTimeout;
72
+ _controller: AbortController;
73
+ /** @type {any} */
74
+ _phaseTimer: any;
75
+ _phaseName: any;
76
+ /** @type {any} */
77
+ _idleTimer: any;
78
+ _totalTimer: number | null;
79
+ _settled: boolean;
80
+ /** @type {TimeoutError|null} */
81
+ error: TimeoutError | null;
82
+ _onOuterAbort: (() => void) | undefined;
83
+ _outer: AbortSignal | undefined;
84
+ get signal(): AbortSignal;
85
+ get aborted(): boolean;
86
+ _abortFromOuter(outer: any): void;
87
+ _fire(code: any, phase: any, ms: any): void;
88
+ _clearAll(): void;
89
+ /**
90
+ * Start a bounded phase. Returns a function that ends it. Only one phase runs at a time; a new
91
+ * phase implicitly ends the previous one, which matches the actual sequence
92
+ * connect -> handshake -> headers and keeps callers from having to unwind by hand.
93
+ */
94
+ beginPhase(name: any): () => void;
95
+ endPhase(): void;
96
+ /**
97
+ * Arm the idle deadline. Call `touch()` on every byte that arrives; each touch restarts the
98
+ * timer. Nothing here reads a clock, which is what makes it work on a runtime whose clock is
99
+ * frozen between I/O events.
100
+ */
101
+ beginIdle(): void;
102
+ touch(): void;
103
+ /** Release every timer. Safe to call more than once; must be called on every exit path. */
104
+ dispose(): void;
105
+ /**
106
+ * Reject as soon as the signal aborts, resolve when `promise` settles first.
107
+ * The abort reason is preserved so the caller sees the typed TimeoutError, not a generic abort.
108
+ */
109
+ race(promise: any): Promise<any>;
110
+ }
111
+ export type DeadlineOptions = {
112
+ /**
113
+ * TCP connect (and proxy handshake) must complete within this
114
+ */
115
+ connectMs?: number | undefined;
116
+ /**
117
+ * TLS handshake must complete within this
118
+ */
119
+ handshakeMs?: number | undefined;
120
+ /**
121
+ * response status line + headers must arrive within this
122
+ */
123
+ headersMs?: number | undefined;
124
+ /**
125
+ * maximum gap between body chunks
126
+ */
127
+ idleMs?: number | undefined;
128
+ /**
129
+ * hard ceiling on the whole request; a backstop, not the control
130
+ */
131
+ totalMs?: number | undefined;
132
+ };
133
+ import { TimeoutError } from '../errors.js';
@@ -0,0 +1,11 @@
1
+ export const WARMUP_HOSTNAME: "warmup.invalid";
2
+ export const WARMUP_NOW: 1893456000000;
3
+ export namespace WARMUP_FIXTURE {
4
+ function clientPrivPkcs8(): Uint8Array<ArrayBuffer>;
5
+ function clientPubRaw(): Uint8Array<ArrayBuffer>;
6
+ function clientRandom(): Uint8Array<ArrayBuffer>;
7
+ function legacySessionId(): Uint8Array<ArrayBuffer>;
8
+ function clientHello(): Uint8Array<ArrayBuffer>;
9
+ function serverBytes(): Uint8Array<ArrayBuffer>;
10
+ function rootDer(): Uint8Array<ArrayBuffer>;
11
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * What one warmup() call reports. `ok` is the only field a caller usually needs; the rest exists
3
+ * so a failure names the exact problem rather than being a silent no-op.
4
+ * @typedef {object} WarmupReport
5
+ * @property {boolean} ok every iteration completed
6
+ * @property {number} iterations how many replays ran to completion
7
+ * @property {string | null} error first failure, if any — warmup() itself never throws
8
+ */
9
+ /**
10
+ * Warm the hot path by replaying a recorded proxy + TLS + HTTP exchange through the real code.
11
+ * See the module comment for what this buys, what it costs, and when NOT to call it. Never
12
+ * called by the package itself; call it from module scope of your worker if — and only if —
13
+ * your deployment does not bill startup CPU.
14
+ *
15
+ * Safe by construction: no network, no randomness, no timers, nothing cached, and it never
16
+ * throws — a runtime that forbids more than expected yields `{ ok: false, error }` and the
17
+ * package behaves exactly as if warmup() had never been called.
18
+ *
19
+ * @param {{ iterations?: number }} [opts] replay count, default 5, clamped to 1..10. One pass
20
+ * moves the hot functions out of the interpreter; more passes push V8's tiering further down
21
+ * the ramp at proportionally more startup cost. Measured startup cost is roughly 10-20 ms per
22
+ * iteration on current edge hardware, against the 1 s startup budget.
23
+ * @returns {Promise<WarmupReport>}
24
+ */
25
+ export function warmup({ iterations }?: {
26
+ iterations?: number;
27
+ }): Promise<WarmupReport>;
28
+ /**
29
+ * What one warmup() call reports. `ok` is the only field a caller usually needs; the rest exists
30
+ * so a failure names the exact problem rather than being a silent no-op.
31
+ */
32
+ export type WarmupReport = {
33
+ /**
34
+ * every iteration completed
35
+ */
36
+ ok: boolean;
37
+ /**
38
+ * how many replays ran to completion
39
+ */
40
+ iterations: number;
41
+ /**
42
+ * first failure, if any — warmup() itself never throws
43
+ */
44
+ error: string | null;
45
+ };