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.
- package/LICENSE +28 -0
- package/README.md +617 -0
- package/README.zh-CN.md +470 -0
- package/package.json +74 -0
- package/src/client/cookies.js +429 -0
- package/src/client/decode.js +346 -0
- package/src/client/redirect.js +249 -0
- package/src/client.js +704 -0
- package/src/errors.js +181 -0
- package/src/http1/chunked.js +289 -0
- package/src/http1/index.js +10 -0
- package/src/http1/request.js +143 -0
- package/src/http1/response.js +493 -0
- package/src/http2/connection.js +1170 -0
- package/src/http2/constants.js +129 -0
- package/src/http2/frames.js +291 -0
- package/src/http2/hpack.js +420 -0
- package/src/http2/huffman.js +203 -0
- package/src/http2/index.js +21 -0
- package/src/index.js +46 -0
- package/src/pool.js +256 -0
- package/src/proxy/direct.js +62 -0
- package/src/proxy/http-connect.js +206 -0
- package/src/proxy/index.js +197 -0
- package/src/proxy/socks5.js +344 -0
- package/src/tls/aead.js +263 -0
- package/src/tls/connect.js +407 -0
- package/src/tls/constants.js +334 -0
- package/src/tls/extensions.js +376 -0
- package/src/tls/handshake-messages.js +901 -0
- package/src/tls/handshake.js +568 -0
- package/src/tls/handshake12.js +507 -0
- package/src/tls/index.js +44 -0
- package/src/tls/keyschedule.js +473 -0
- package/src/tls/record.js +872 -0
- package/src/tls/tickets.js +145 -0
- package/src/tls/transcript.js +101 -0
- package/src/tls/wire.js +224 -0
- package/src/transport.js +296 -0
- package/src/trust/der.js +551 -0
- package/src/trust/index.js +375 -0
- package/src/trust/name.js +235 -0
- package/src/trust/ocsp.js +759 -0
- package/src/trust/path.js +595 -0
- package/src/trust/roots.js +454 -0
- package/src/trust/x509.js +902 -0
- package/src/util/bytes.js +470 -0
- package/src/util/deadline.js +266 -0
- package/src/warmup-fixture.js +85 -0
- package/src/warmup.js +243 -0
- package/types/client/cookies.d.ts +159 -0
- package/types/client/decode.d.ts +54 -0
- package/types/client/redirect.d.ts +96 -0
- package/types/client.d.ts +323 -0
- package/types/errors.d.ts +141 -0
- package/types/http1/chunked.d.ts +48 -0
- package/types/http1/index.d.ts +3 -0
- package/types/http1/request.d.ts +44 -0
- package/types/http1/response.d.ts +183 -0
- package/types/http2/connection.d.ts +282 -0
- package/types/http2/constants.d.ts +95 -0
- package/types/http2/frames.d.ts +116 -0
- package/types/http2/hpack.d.ts +99 -0
- package/types/http2/huffman.d.ts +21 -0
- package/types/http2/index.d.ts +5 -0
- package/types/index.d.ts +17 -0
- package/types/pool.d.ts +135 -0
- package/types/proxy/direct.d.ts +26 -0
- package/types/proxy/http-connect.d.ts +37 -0
- package/types/proxy/index.d.ts +62 -0
- package/types/proxy/socks5.d.ts +47 -0
- package/types/tls/aead.d.ts +67 -0
- package/types/tls/connect.d.ts +280 -0
- package/types/tls/constants.d.ts +275 -0
- package/types/tls/extensions.d.ts +195 -0
- package/types/tls/handshake-messages.d.ts +430 -0
- package/types/tls/handshake.d.ts +90 -0
- package/types/tls/handshake12.d.ts +35 -0
- package/types/tls/index.d.ts +9 -0
- package/types/tls/keyschedule.d.ts +272 -0
- package/types/tls/record.d.ts +361 -0
- package/types/tls/tickets.d.ts +66 -0
- package/types/tls/transcript.d.ts +52 -0
- package/types/tls/wire.d.ts +106 -0
- package/types/transport.d.ts +222 -0
- package/types/trust/der.d.ts +239 -0
- package/types/trust/index.d.ts +194 -0
- package/types/trust/name.d.ts +33 -0
- package/types/trust/ocsp.d.ts +138 -0
- package/types/trust/path.d.ts +139 -0
- package/types/trust/roots.d.ts +36 -0
- package/types/trust/x509.d.ts +401 -0
- package/types/util/bytes.d.ts +183 -0
- package/types/util/deadline.d.ts +133 -0
- package/types/warmup-fixture.d.ts +11 -0
- 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
|
+
};
|