@inkbox/sdk 0.2.16 → 0.3.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/README.md +10 -1
- package/dist/_http.d.ts +24 -5
- package/dist/_http.d.ts.map +1 -1
- package/dist/_http.js +21 -11
- package/dist/_http.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/inkbox.d.ts +4 -0
- package/dist/inkbox.d.ts.map +1 -1
- package/dist/inkbox.js +5 -0
- package/dist/inkbox.js.map +1 -1
- package/dist/tunnels/_validation.d.ts +7 -0
- package/dist/tunnels/_validation.d.ts.map +1 -0
- package/dist/tunnels/_validation.js +27 -0
- package/dist/tunnels/_validation.js.map +1 -0
- package/dist/tunnels/client/_bridge.d.ts +35 -0
- package/dist/tunnels/client/_bridge.d.ts.map +1 -0
- package/dist/tunnels/client/_bridge.js +52 -0
- package/dist/tunnels/client/_bridge.js.map +1 -0
- package/dist/tunnels/client/_callable_streaming.d.ts +25 -0
- package/dist/tunnels/client/_callable_streaming.d.ts.map +1 -0
- package/dist/tunnels/client/_callable_streaming.js +158 -0
- package/dist/tunnels/client/_callable_streaming.js.map +1 -0
- package/dist/tunnels/client/_cert.d.ts +45 -0
- package/dist/tunnels/client/_cert.d.ts.map +1 -0
- package/dist/tunnels/client/_cert.js +193 -0
- package/dist/tunnels/client/_cert.js.map +1 -0
- package/dist/tunnels/client/_dispatch.d.ts +109 -0
- package/dist/tunnels/client/_dispatch.d.ts.map +1 -0
- package/dist/tunnels/client/_dispatch.js +314 -0
- package/dist/tunnels/client/_dispatch.js.map +1 -0
- package/dist/tunnels/client/_envelope.d.ts +55 -0
- package/dist/tunnels/client/_envelope.d.ts.map +1 -0
- package/dist/tunnels/client/_envelope.js +97 -0
- package/dist/tunnels/client/_envelope.js.map +1 -0
- package/dist/tunnels/client/_h1_server.d.ts +37 -0
- package/dist/tunnels/client/_h1_server.d.ts.map +1 -0
- package/dist/tunnels/client/_h1_server.js +433 -0
- package/dist/tunnels/client/_h1_server.js.map +1 -0
- package/dist/tunnels/client/_h2_transcode.d.ts +43 -0
- package/dist/tunnels/client/_h2_transcode.d.ts.map +1 -0
- package/dist/tunnels/client/_h2_transcode.js +488 -0
- package/dist/tunnels/client/_h2_transcode.js.map +1 -0
- package/dist/tunnels/client/_handler.d.ts +62 -0
- package/dist/tunnels/client/_handler.d.ts.map +1 -0
- package/dist/tunnels/client/_handler.js +121 -0
- package/dist/tunnels/client/_handler.js.map +1 -0
- package/dist/tunnels/client/_listener.d.ts +64 -0
- package/dist/tunnels/client/_listener.d.ts.map +1 -0
- package/dist/tunnels/client/_listener.js +113 -0
- package/dist/tunnels/client/_listener.js.map +1 -0
- package/dist/tunnels/client/_protocol.d.ts +67 -0
- package/dist/tunnels/client/_protocol.d.ts.map +1 -0
- package/dist/tunnels/client/_protocol.js +86 -0
- package/dist/tunnels/client/_protocol.js.map +1 -0
- package/dist/tunnels/client/_runtime.d.ts +143 -0
- package/dist/tunnels/client/_runtime.d.ts.map +1 -0
- package/dist/tunnels/client/_runtime.js +1679 -0
- package/dist/tunnels/client/_runtime.js.map +1 -0
- package/dist/tunnels/client/_state.d.ts +45 -0
- package/dist/tunnels/client/_state.d.ts.map +1 -0
- package/dist/tunnels/client/_state.js +165 -0
- package/dist/tunnels/client/_state.js.map +1 -0
- package/dist/tunnels/client/_tls.d.ts +50 -0
- package/dist/tunnels/client/_tls.d.ts.map +1 -0
- package/dist/tunnels/client/_tls.js +139 -0
- package/dist/tunnels/client/_tls.js.map +1 -0
- package/dist/tunnels/client/_upstream_tls.d.ts +25 -0
- package/dist/tunnels/client/_upstream_tls.d.ts.map +1 -0
- package/dist/tunnels/client/_upstream_tls.js +24 -0
- package/dist/tunnels/client/_upstream_tls.js.map +1 -0
- package/dist/tunnels/client/_url_forward.d.ts +92 -0
- package/dist/tunnels/client/_url_forward.d.ts.map +1 -0
- package/dist/tunnels/client/_url_forward.js +255 -0
- package/dist/tunnels/client/_url_forward.js.map +1 -0
- package/dist/tunnels/client/_validation.d.ts +27 -0
- package/dist/tunnels/client/_validation.d.ts.map +1 -0
- package/dist/tunnels/client/_validation.js +96 -0
- package/dist/tunnels/client/_validation.js.map +1 -0
- package/dist/tunnels/client/_ws.d.ts +149 -0
- package/dist/tunnels/client/_ws.d.ts.map +1 -0
- package/dist/tunnels/client/_ws.js +351 -0
- package/dist/tunnels/client/_ws.js.map +1 -0
- package/dist/tunnels/client/_ws_passthrough.d.ts +129 -0
- package/dist/tunnels/client/_ws_passthrough.d.ts.map +1 -0
- package/dist/tunnels/client/_ws_passthrough.js +432 -0
- package/dist/tunnels/client/_ws_passthrough.js.map +1 -0
- package/dist/tunnels/client/_ws_url_bridge.d.ts +71 -0
- package/dist/tunnels/client/_ws_url_bridge.d.ts.map +1 -0
- package/dist/tunnels/client/_ws_url_bridge.js +474 -0
- package/dist/tunnels/client/_ws_url_bridge.js.map +1 -0
- package/dist/tunnels/client/_ws_url_edge_bridge.d.ts +26 -0
- package/dist/tunnels/client/_ws_url_edge_bridge.d.ts.map +1 -0
- package/dist/tunnels/client/_ws_url_edge_bridge.js +256 -0
- package/dist/tunnels/client/_ws_url_edge_bridge.js.map +1 -0
- package/dist/tunnels/client/_wsframe.d.ts +142 -0
- package/dist/tunnels/client/_wsframe.d.ts.map +1 -0
- package/dist/tunnels/client/_wsframe.js +282 -0
- package/dist/tunnels/client/_wsframe.js.map +1 -0
- package/dist/tunnels/client/index.d.ts +101 -0
- package/dist/tunnels/client/index.d.ts.map +1 -0
- package/dist/tunnels/client/index.js +242 -0
- package/dist/tunnels/client/index.js.map +1 -0
- package/dist/tunnels/exceptions.d.ts +31 -0
- package/dist/tunnels/exceptions.d.ts.map +1 -0
- package/dist/tunnels/exceptions.js +68 -0
- package/dist/tunnels/exceptions.js.map +1 -0
- package/dist/tunnels/resources/tunnels.d.ts +73 -0
- package/dist/tunnels/resources/tunnels.d.ts.map +1 -0
- package/dist/tunnels/resources/tunnels.js +173 -0
- package/dist/tunnels/resources/tunnels.js.map +1 -0
- package/dist/tunnels/types.d.ts +99 -0
- package/dist/tunnels/types.d.ts.map +1 -0
- package/dist/tunnels/types.js +76 -0
- package/dist/tunnels/types.js.map +1 -0
- package/package.json +14 -5
- package/protocol/tunnel_protocol_constants.json +65 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-tunnels/client/_url_forward.ts
|
|
3
|
+
*
|
|
4
|
+
* URL-forward HTTP proxy. Mirrors Python `_url_forward.py`.
|
|
5
|
+
*
|
|
6
|
+
* The discriminated-union return type is the type-system forcing
|
|
7
|
+
* function against materialize-then-check: a plain `{body: Buffer}`
|
|
8
|
+
* shape would push implementations toward buffering full responses
|
|
9
|
+
* before checking the cap, defeating the streaming guarantee. Both
|
|
10
|
+
* over-cap and upstream-error paths are values the runtime maps onto
|
|
11
|
+
* fixed on-wire response shapes — no exception-driven control flow.
|
|
12
|
+
*/
|
|
13
|
+
import type { Envelope } from "./_envelope.js";
|
|
14
|
+
export type ForwardResult = {
|
|
15
|
+
kind: "ok";
|
|
16
|
+
status: number;
|
|
17
|
+
headers: Array<[string, string]>;
|
|
18
|
+
body: Buffer;
|
|
19
|
+
} | {
|
|
20
|
+
kind: "too-large";
|
|
21
|
+
status: 502;
|
|
22
|
+
inkboxReason: "response-too-large";
|
|
23
|
+
} | {
|
|
24
|
+
kind: "upstream-unreachable";
|
|
25
|
+
status: 502;
|
|
26
|
+
inkboxReason: "upstream-unreachable";
|
|
27
|
+
};
|
|
28
|
+
export interface ForwardOpts {
|
|
29
|
+
envelope: Envelope;
|
|
30
|
+
forwardTo: string;
|
|
31
|
+
publicHost: string;
|
|
32
|
+
/** Injectable for tests; defaults to global `fetch`. */
|
|
33
|
+
fetcher?: typeof fetch;
|
|
34
|
+
/** Cap on materialized outbound bodies. */
|
|
35
|
+
maxResponseBytes: number;
|
|
36
|
+
/** Optional abort signal — runtime ties this to its deadline. */
|
|
37
|
+
signal?: AbortSignal;
|
|
38
|
+
/**
|
|
39
|
+
* Verify the upstream's TLS certificate when ``forwardTo`` is
|
|
40
|
+
* ``https://``. Default ``true``. Has no effect for ``http://``.
|
|
41
|
+
*/
|
|
42
|
+
verifyTls?: boolean;
|
|
43
|
+
/** Extra PEM CA bundle to trust for the upstream TLS connection. */
|
|
44
|
+
caBundle?: Buffer | string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Per-runtime cache of undici Agent dispatchers used when TLS
|
|
47
|
+
* overrides are configured. Reuses connection pools across requests
|
|
48
|
+
* with the same (verifyTls, caBundle) tuple instead of allocating a
|
|
49
|
+
* fresh Agent — and timer — per request.
|
|
50
|
+
*/
|
|
51
|
+
agentCache?: UndiciAgentCache;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Cache of undici ``Agent`` instances keyed by (verifyTls, caBundle).
|
|
55
|
+
* Returned dispatcher is opaque (`unknown`) so undici stays a
|
|
56
|
+
* type-only dependency at this surface — the runtime imports lazily.
|
|
57
|
+
*/
|
|
58
|
+
export interface UndiciAgentCache {
|
|
59
|
+
/**
|
|
60
|
+
* Return a cached Agent for these TLS settings, or create + cache one.
|
|
61
|
+
* Returns `null` if no override is needed (default trust + verify on).
|
|
62
|
+
*/
|
|
63
|
+
get(verifyTls: boolean | undefined, caBundle: Buffer | string | null | undefined): Promise<unknown>;
|
|
64
|
+
/** Close every cached Agent. Idempotent. */
|
|
65
|
+
close(): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Build a per-runtime undici Agent cache. Each unique
|
|
69
|
+
* (verifyTls, caBundle) combination gets one shared Agent. Closed in
|
|
70
|
+
* `TunnelRuntime.aclose()`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function createUndiciAgentCache(): UndiciAgentCache;
|
|
73
|
+
/**
|
|
74
|
+
* Prefix-join the envelope's path onto `forwardTo`'s base path.
|
|
75
|
+
* Mirrors Python `join_forward_path`.
|
|
76
|
+
*/
|
|
77
|
+
export declare function joinForwardPath(forwardTo: string, envelopePath: string): string;
|
|
78
|
+
/**
|
|
79
|
+
* Build the headers we send to `forwardTo`. Strips hop-by-hop and
|
|
80
|
+
* inbound forwarded-for headers; injects Host, X-Forwarded-Host,
|
|
81
|
+
* X-Forwarded-Proto, X-Forwarded-For, Forwarded.
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildForwardHeaders(envelope: Envelope, publicHost: string, targetHost: string): Array<[string, string]>;
|
|
84
|
+
/**
|
|
85
|
+
* Forward an envelope to `forwardTo`. Streams the upstream response;
|
|
86
|
+
* bails as soon as the accumulated body exceeds `maxResponseBytes`.
|
|
87
|
+
*
|
|
88
|
+
* Caller is expected to have already validated the forward target and
|
|
89
|
+
* the envelope path, and materialized the inbound body.
|
|
90
|
+
*/
|
|
91
|
+
export declare function forwardEnvelopeToUrl(opts: ForwardOpts): Promise<ForwardResult>;
|
|
92
|
+
//# sourceMappingURL=_url_forward.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_url_forward.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_url_forward.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,oBAAoB,CAAC;CACpC,GACD;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,sBAAsB,CAAC;CACtC,CAAC;AAEN,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,GAAG,CACD,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAC3C,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAmEzD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAU/E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAuBzB;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CAoHxB"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-tunnels/client/_url_forward.ts
|
|
3
|
+
*
|
|
4
|
+
* URL-forward HTTP proxy. Mirrors Python `_url_forward.py`.
|
|
5
|
+
*
|
|
6
|
+
* The discriminated-union return type is the type-system forcing
|
|
7
|
+
* function against materialize-then-check: a plain `{body: Buffer}`
|
|
8
|
+
* shape would push implementations toward buffering full responses
|
|
9
|
+
* before checking the cap, defeating the streaming guarantee. Both
|
|
10
|
+
* over-cap and upstream-error paths are values the runtime maps onto
|
|
11
|
+
* fixed on-wire response shapes — no exception-driven control flow.
|
|
12
|
+
*/
|
|
13
|
+
import { HOP_BY_HOP_REQUEST } from "./_protocol.js";
|
|
14
|
+
/**
|
|
15
|
+
* Build a per-runtime undici Agent cache. Each unique
|
|
16
|
+
* (verifyTls, caBundle) combination gets one shared Agent. Closed in
|
|
17
|
+
* `TunnelRuntime.aclose()`.
|
|
18
|
+
*/
|
|
19
|
+
export function createUndiciAgentCache() {
|
|
20
|
+
const agents = new Map();
|
|
21
|
+
let closed = false;
|
|
22
|
+
const keyFor = (verifyTls, caBundle) => {
|
|
23
|
+
const v = verifyTls === false ? "off" : "on";
|
|
24
|
+
let cb = "none";
|
|
25
|
+
if (caBundle !== null && caBundle !== undefined) {
|
|
26
|
+
const buf = typeof caBundle === "string"
|
|
27
|
+
? Buffer.from(caBundle, "utf-8")
|
|
28
|
+
: caBundle;
|
|
29
|
+
// crypto import is lazy below; do a coarse digest via length
|
|
30
|
+
// initially, then refine with real hash inside `get` after we've
|
|
31
|
+
// imported `node:crypto`.
|
|
32
|
+
cb = `len:${buf.length}`;
|
|
33
|
+
}
|
|
34
|
+
return `${v}|${cb}`;
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
async get(verifyTls, caBundle) {
|
|
38
|
+
if (closed)
|
|
39
|
+
return undefined;
|
|
40
|
+
const noOverride = verifyTls !== false &&
|
|
41
|
+
(caBundle === null || caBundle === undefined);
|
|
42
|
+
if (noOverride)
|
|
43
|
+
return undefined;
|
|
44
|
+
// Stable hash of caBundle so two distinct CAs of the same length
|
|
45
|
+
// don't alias.
|
|
46
|
+
const { createHash } = await import("node:crypto");
|
|
47
|
+
let cbHash = "none";
|
|
48
|
+
if (caBundle !== null && caBundle !== undefined) {
|
|
49
|
+
const buf = typeof caBundle === "string"
|
|
50
|
+
? Buffer.from(caBundle, "utf-8")
|
|
51
|
+
: caBundle;
|
|
52
|
+
cbHash = createHash("sha256").update(buf).digest("hex").slice(0, 16);
|
|
53
|
+
}
|
|
54
|
+
const key = `${verifyTls === false ? "off" : "on"}|${cbHash}`;
|
|
55
|
+
void keyFor;
|
|
56
|
+
const existing = agents.get(key);
|
|
57
|
+
if (existing !== undefined)
|
|
58
|
+
return existing;
|
|
59
|
+
const undici = await import("undici");
|
|
60
|
+
const { buildUpstreamTlsConnectOpts } = await import("./_upstream_tls.js");
|
|
61
|
+
const connect = buildUpstreamTlsConnectOpts({
|
|
62
|
+
verify: verifyTls,
|
|
63
|
+
caBundle: caBundle ?? null,
|
|
64
|
+
});
|
|
65
|
+
const agent = new undici.Agent({ connect });
|
|
66
|
+
agents.set(key, agent);
|
|
67
|
+
return agent;
|
|
68
|
+
},
|
|
69
|
+
async close() {
|
|
70
|
+
if (closed)
|
|
71
|
+
return;
|
|
72
|
+
closed = true;
|
|
73
|
+
const ps = [];
|
|
74
|
+
for (const a of agents.values()) {
|
|
75
|
+
const ag = a;
|
|
76
|
+
if (ag && typeof ag.close === "function") {
|
|
77
|
+
try {
|
|
78
|
+
ps.push(ag.close());
|
|
79
|
+
}
|
|
80
|
+
catch { /* swallow */ }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
agents.clear();
|
|
84
|
+
await Promise.allSettled(ps);
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Prefix-join the envelope's path onto `forwardTo`'s base path.
|
|
90
|
+
* Mirrors Python `join_forward_path`.
|
|
91
|
+
*/
|
|
92
|
+
export function joinForwardPath(forwardTo, envelopePath) {
|
|
93
|
+
const parsed = new URL(forwardTo);
|
|
94
|
+
let basePath = parsed.pathname;
|
|
95
|
+
if (basePath.endsWith("/"))
|
|
96
|
+
basePath = basePath.slice(0, -1);
|
|
97
|
+
const queryIdx = envelopePath.indexOf("?");
|
|
98
|
+
let rawPath = queryIdx >= 0 ? envelopePath.slice(0, queryIdx) : envelopePath;
|
|
99
|
+
const query = queryIdx >= 0 ? envelopePath.slice(queryIdx) : "";
|
|
100
|
+
if (!rawPath.startsWith("/"))
|
|
101
|
+
rawPath = "/" + rawPath;
|
|
102
|
+
const fullPath = basePath ? `${basePath}${rawPath}` : rawPath;
|
|
103
|
+
return `${parsed.protocol}//${parsed.host}${fullPath}${query}`;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Build the headers we send to `forwardTo`. Strips hop-by-hop and
|
|
107
|
+
* inbound forwarded-for headers; injects Host, X-Forwarded-Host,
|
|
108
|
+
* X-Forwarded-Proto, X-Forwarded-For, Forwarded.
|
|
109
|
+
*/
|
|
110
|
+
export function buildForwardHeaders(envelope, publicHost, targetHost) {
|
|
111
|
+
const out = [];
|
|
112
|
+
out.push(["host", targetHost]);
|
|
113
|
+
out.push(["x-forwarded-host", publicHost]);
|
|
114
|
+
out.push(["x-forwarded-proto", "https"]);
|
|
115
|
+
if (envelope.forwardedForIp) {
|
|
116
|
+
out.push(["x-forwarded-for", envelope.forwardedForIp]);
|
|
117
|
+
out.push(["forwarded", `for=${envelope.forwardedForIp}`]);
|
|
118
|
+
}
|
|
119
|
+
const seenSpecial = new Set([
|
|
120
|
+
"host",
|
|
121
|
+
"x-forwarded-host",
|
|
122
|
+
"x-forwarded-proto",
|
|
123
|
+
"x-forwarded-for",
|
|
124
|
+
"forwarded",
|
|
125
|
+
]);
|
|
126
|
+
for (const [k, v] of envelope.forwardedHeaders) {
|
|
127
|
+
const kl = k.toLowerCase();
|
|
128
|
+
if (HOP_BY_HOP_REQUEST.has(kl))
|
|
129
|
+
continue;
|
|
130
|
+
if (seenSpecial.has(kl))
|
|
131
|
+
continue;
|
|
132
|
+
out.push([k, v]);
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Forward an envelope to `forwardTo`. Streams the upstream response;
|
|
138
|
+
* bails as soon as the accumulated body exceeds `maxResponseBytes`.
|
|
139
|
+
*
|
|
140
|
+
* Caller is expected to have already validated the forward target and
|
|
141
|
+
* the envelope path, and materialized the inbound body.
|
|
142
|
+
*/
|
|
143
|
+
export async function forwardEnvelopeToUrl(opts) {
|
|
144
|
+
const targetUrl = joinForwardPath(opts.forwardTo, opts.envelope.path);
|
|
145
|
+
const parsedTarget = new URL(opts.forwardTo);
|
|
146
|
+
const targetHost = parsedTarget.host;
|
|
147
|
+
const headers = buildForwardHeaders(opts.envelope, opts.publicHost, targetHost);
|
|
148
|
+
// For https:// upstreams with TLS overrides, get a cached undici
|
|
149
|
+
// dispatcher (or build one ad-hoc if the runtime didn't supply a
|
|
150
|
+
// cache, e.g. legacy callers / direct unit tests). Lazy-loaded so
|
|
151
|
+
// the default http:// path stays out of undici and edge bundles
|
|
152
|
+
// don't pull undici in unconditionally.
|
|
153
|
+
const isHttps = parsedTarget.protocol === "https:";
|
|
154
|
+
const wantsTlsOverride = isHttps &&
|
|
155
|
+
(opts.verifyTls === false ||
|
|
156
|
+
(opts.caBundle !== null && opts.caBundle !== undefined));
|
|
157
|
+
let dispatcher = undefined;
|
|
158
|
+
if (wantsTlsOverride && opts.fetcher === undefined) {
|
|
159
|
+
if (opts.agentCache !== undefined) {
|
|
160
|
+
dispatcher = await opts.agentCache.get(opts.verifyTls, opts.caBundle ?? null);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
// No cache supplied — fall back to per-request Agent. Caller is
|
|
164
|
+
// responsible for closing if it cares; the runtime always passes
|
|
165
|
+
// a cache, so this branch is only hit by direct callers.
|
|
166
|
+
const undici = await import("undici");
|
|
167
|
+
const { buildUpstreamTlsConnectOpts } = await import("./_upstream_tls.js");
|
|
168
|
+
const connect = buildUpstreamTlsConnectOpts({
|
|
169
|
+
verify: opts.verifyTls,
|
|
170
|
+
caBundle: opts.caBundle ?? null,
|
|
171
|
+
});
|
|
172
|
+
dispatcher = new undici.Agent({ connect });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const fetcher = opts.fetcher ?? ((url, init) => {
|
|
176
|
+
// Node's fetch (undici-backed) honors `dispatcher` on the init.
|
|
177
|
+
const initWithDispatcher = dispatcher === undefined ? init ?? {} : { ...(init ?? {}), dispatcher };
|
|
178
|
+
return globalThis.fetch(url, initWithDispatcher);
|
|
179
|
+
});
|
|
180
|
+
const reqInit = {
|
|
181
|
+
method: opts.envelope.method,
|
|
182
|
+
headers,
|
|
183
|
+
// Empty bodies must not be passed for GET/HEAD.
|
|
184
|
+
body: opts.envelope.method === "GET" || opts.envelope.method === "HEAD"
|
|
185
|
+
? undefined
|
|
186
|
+
: opts.envelope.body.length > 0
|
|
187
|
+
? new Uint8Array(opts.envelope.body)
|
|
188
|
+
: undefined,
|
|
189
|
+
signal: opts.signal,
|
|
190
|
+
// Don't follow redirects automatically — let the user app's
|
|
191
|
+
// upstream decide. Matches the Python httpx behavior under stream().
|
|
192
|
+
redirect: "manual",
|
|
193
|
+
};
|
|
194
|
+
let response;
|
|
195
|
+
try {
|
|
196
|
+
response = await fetcher(targetUrl, reqInit);
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return { kind: "upstream-unreachable", status: 502, inkboxReason: "upstream-unreachable" };
|
|
200
|
+
}
|
|
201
|
+
const reader = response.body?.getReader();
|
|
202
|
+
if (!reader) {
|
|
203
|
+
// No body — emit empty response.
|
|
204
|
+
return {
|
|
205
|
+
kind: "ok",
|
|
206
|
+
status: response.status,
|
|
207
|
+
headers: collectResponseHeaders(response.headers),
|
|
208
|
+
body: Buffer.alloc(0),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const chunks = [];
|
|
212
|
+
let total = 0;
|
|
213
|
+
try {
|
|
214
|
+
while (true) {
|
|
215
|
+
const { value, done } = await reader.read();
|
|
216
|
+
if (done)
|
|
217
|
+
break;
|
|
218
|
+
const chunk = Buffer.from(value);
|
|
219
|
+
if (total + chunk.length > opts.maxResponseBytes) {
|
|
220
|
+
// Cap exceeded — cancel the upstream reader before any more
|
|
221
|
+
// bytes land in our buffer, matching Python's
|
|
222
|
+
// `oversize=True; break` shape.
|
|
223
|
+
await reader.cancel().catch(() => undefined);
|
|
224
|
+
return {
|
|
225
|
+
kind: "too-large",
|
|
226
|
+
status: 502,
|
|
227
|
+
inkboxReason: "response-too-large",
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
chunks.push(chunk);
|
|
231
|
+
total += chunk.length;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return {
|
|
236
|
+
kind: "upstream-unreachable",
|
|
237
|
+
status: 502,
|
|
238
|
+
inkboxReason: "upstream-unreachable",
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
kind: "ok",
|
|
243
|
+
status: response.status,
|
|
244
|
+
headers: collectResponseHeaders(response.headers),
|
|
245
|
+
body: chunks.length === 0 ? Buffer.alloc(0) : Buffer.concat(chunks, total),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function collectResponseHeaders(h) {
|
|
249
|
+
const out = [];
|
|
250
|
+
h.forEach((value, key) => {
|
|
251
|
+
out.push([key, value]);
|
|
252
|
+
});
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=_url_forward.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_url_forward.js","sourceRoot":"","sources":["../../../src/tunnels/client/_url_forward.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-tunnels/client/_validation.ts
|
|
3
|
+
*
|
|
4
|
+
* Path-traversal + forward-target validation for the data-plane runtime.
|
|
5
|
+
* Mirrors the Python ``_url_forward.py`` algorithms so the two SDKs
|
|
6
|
+
* accept and reject the same set of inputs.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ForwardTargetRefused extends Error {
|
|
9
|
+
constructor(message: string);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Validate `forward_to` against the loopback-only allowlist.
|
|
13
|
+
*
|
|
14
|
+
* Default refuses any host that isn't a literal loopback form. Hostnames
|
|
15
|
+
* that *would* resolve to loopback are also refused (no DNS resolution
|
|
16
|
+
* happens here — that lets a rebinding-prone hostname slip a sensitive
|
|
17
|
+
* target past the check).
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateForwardTarget(forwardTo: string, options?: {
|
|
20
|
+
allowRemoteForwarding?: boolean;
|
|
21
|
+
}): void;
|
|
22
|
+
/**
|
|
23
|
+
* Reject path-traversal evasion attempts. Returns `null` on success or
|
|
24
|
+
* the `inkbox-reason` string for the rejection.
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateEnvelopePath(path: string): string | null;
|
|
27
|
+
//# sourceMappingURL=_validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_validation.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_validation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,IAAI,CAiCN;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA6BhE"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-tunnels/client/_validation.ts
|
|
3
|
+
*
|
|
4
|
+
* Path-traversal + forward-target validation for the data-plane runtime.
|
|
5
|
+
* Mirrors the Python ``_url_forward.py`` algorithms so the two SDKs
|
|
6
|
+
* accept and reject the same set of inputs.
|
|
7
|
+
*/
|
|
8
|
+
const LOOPBACK_LITERALS = new Set(["localhost", "127.0.0.1", "::1"]);
|
|
9
|
+
export class ForwardTargetRefused extends Error {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "ForwardTargetRefused";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Validate `forward_to` against the loopback-only allowlist.
|
|
17
|
+
*
|
|
18
|
+
* Default refuses any host that isn't a literal loopback form. Hostnames
|
|
19
|
+
* that *would* resolve to loopback are also refused (no DNS resolution
|
|
20
|
+
* happens here — that lets a rebinding-prone hostname slip a sensitive
|
|
21
|
+
* target past the check).
|
|
22
|
+
*/
|
|
23
|
+
export function validateForwardTarget(forwardTo, options = {}) {
|
|
24
|
+
if (options.allowRemoteForwarding === true)
|
|
25
|
+
return;
|
|
26
|
+
let parsed;
|
|
27
|
+
try {
|
|
28
|
+
parsed = new URL(forwardTo);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
throw new ForwardTargetRefused(`forward_to is not a valid URL: ${forwardTo}`);
|
|
32
|
+
}
|
|
33
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
34
|
+
throw new ForwardTargetRefused(`forward_to scheme must be http or https; got ${parsed.protocol}`);
|
|
35
|
+
}
|
|
36
|
+
const host = parsed.hostname.toLowerCase().replace(/^\[/, "").replace(/\]$/, "");
|
|
37
|
+
if (!host) {
|
|
38
|
+
throw new ForwardTargetRefused(`forward_to has no host: ${forwardTo}`);
|
|
39
|
+
}
|
|
40
|
+
if (LOOPBACK_LITERALS.has(host))
|
|
41
|
+
return;
|
|
42
|
+
// IPv4 in 127.0.0.0/8?
|
|
43
|
+
const m = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
|
|
44
|
+
if (m) {
|
|
45
|
+
const a = Number(m[1]);
|
|
46
|
+
if (a === 127)
|
|
47
|
+
return;
|
|
48
|
+
throw new ForwardTargetRefused(`forward_to address ${host} is not loopback; pass ` +
|
|
49
|
+
"allowRemoteForwarding: true to bypass (review the SSRF tradeoff first)");
|
|
50
|
+
}
|
|
51
|
+
// ::1 already covered by the literals set; otherwise fall through.
|
|
52
|
+
throw new ForwardTargetRefused(`forward_to host ${host} is not a literal loopback address; pass ` +
|
|
53
|
+
"allowRemoteForwarding: true to bypass (review the SSRF tradeoff first)");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Reject path-traversal evasion attempts. Returns `null` on success or
|
|
57
|
+
* the `inkbox-reason` string for the rejection.
|
|
58
|
+
*/
|
|
59
|
+
export function validateEnvelopePath(path) {
|
|
60
|
+
const queryIdx = path.indexOf("?");
|
|
61
|
+
const rawPath = queryIdx >= 0 ? path.slice(0, queryIdx) : path;
|
|
62
|
+
const lowered = rawPath.toLowerCase();
|
|
63
|
+
if (lowered.includes("%2f") || lowered.includes("%5c"))
|
|
64
|
+
return "invalid-path";
|
|
65
|
+
let decoded;
|
|
66
|
+
try {
|
|
67
|
+
const pass1 = decodeURIComponent(rawPath);
|
|
68
|
+
if (pass1 !== rawPath) {
|
|
69
|
+
const pass2 = decodeURIComponent(pass1);
|
|
70
|
+
if (pass2 !== pass1)
|
|
71
|
+
return "invalid-path";
|
|
72
|
+
decoded = pass2;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
decoded = pass1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return "invalid-path";
|
|
80
|
+
}
|
|
81
|
+
for (const segment of decoded.split("/")) {
|
|
82
|
+
if (segment === "." || segment === "..")
|
|
83
|
+
return "invalid-path";
|
|
84
|
+
// Some upstream frameworks treat raw backslash as a path separator.
|
|
85
|
+
// Reject it so `/static\..\secret` can't slip past split-on-/.
|
|
86
|
+
if (segment.includes("\\"))
|
|
87
|
+
return "invalid-path";
|
|
88
|
+
for (const ch of segment) {
|
|
89
|
+
const o = ch.charCodeAt(0);
|
|
90
|
+
if (o < 0x20 || o === 0x7f)
|
|
91
|
+
return "invalid-path";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=_validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_validation.js","sourceRoot":"","sources":["../../../src/tunnels/client/_validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-tunnels/client/_ws.ts
|
|
3
|
+
*
|
|
4
|
+
* In-process WebSocket session driver.
|
|
5
|
+
*
|
|
6
|
+
* Public types: {@link InkboxWebSocket}, {@link InkboxWsHandler},
|
|
7
|
+
* {@link WsAcceptDeadlineExceeded}, {@link WsProtocolMismatch},
|
|
8
|
+
* {@link WsClosed}.
|
|
9
|
+
*
|
|
10
|
+
* Internal types: {@link buildAcceptReply}, the lifecycle driver
|
|
11
|
+
* {@link dispatchWsUpgradeInProcess}.
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
import type { Envelope } from "./_envelope.js";
|
|
15
|
+
export declare class WsAcceptDeadlineExceeded extends Error {
|
|
16
|
+
constructor(message?: string);
|
|
17
|
+
}
|
|
18
|
+
export declare class WsProtocolMismatch extends Error {
|
|
19
|
+
constructor(requested: string, offered: ReadonlyArray<string>);
|
|
20
|
+
}
|
|
21
|
+
export declare class WsClosed extends Error {
|
|
22
|
+
constructor(message?: string);
|
|
23
|
+
}
|
|
24
|
+
export interface InkboxWebSocketAcceptOpts {
|
|
25
|
+
/** Optional subprotocol; must be one of `offeredProtocols`. */
|
|
26
|
+
protocol?: string;
|
|
27
|
+
/** Additional response headers (excluding hop-by-hop). */
|
|
28
|
+
headers?: Array<[string, string]>;
|
|
29
|
+
}
|
|
30
|
+
export interface InkboxWebSocket {
|
|
31
|
+
readonly url: string;
|
|
32
|
+
readonly headers: ReadonlyMap<string, string>;
|
|
33
|
+
readonly offeredProtocols: ReadonlyArray<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Complete the upgrade handshake. If `protocol` is given, it MUST be
|
|
36
|
+
* one of `offeredProtocols` — otherwise rejects with
|
|
37
|
+
* `WsProtocolMismatch`. Resolves once the accept reply has been
|
|
38
|
+
* posted on the wire.
|
|
39
|
+
*/
|
|
40
|
+
accept(opts?: InkboxWebSocketAcceptOpts): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Send a message. Resolves when the outbound buffer drains. Rejects
|
|
43
|
+
* with `WsClosed` if `close()` has already been called.
|
|
44
|
+
*/
|
|
45
|
+
send(data: string | Buffer): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Send a CLOSE frame and tear down the bridge stream. Resolves once
|
|
48
|
+
* the CLOSE frame is on the wire. Subsequent `send()` calls reject
|
|
49
|
+
* with `WsClosed`.
|
|
50
|
+
*/
|
|
51
|
+
close(code?: number, reason?: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Inbound message stream. Completes cleanly (`done: true`) on a
|
|
54
|
+
* normal CLOSE frame from the peer. Throws on abnormal close.
|
|
55
|
+
*/
|
|
56
|
+
[Symbol.asyncIterator](): AsyncIterator<string | Buffer>;
|
|
57
|
+
}
|
|
58
|
+
export type InkboxWsHandler = (ws: InkboxWebSocket) => Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Parse a `Sec-WebSocket-Protocol` header into an ordered list of
|
|
61
|
+
* offered subprotocols. Comma-split, trimmed, empties dropped.
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseOfferedSubprotocols(forwardedHeaders: ReadonlyArray<readonly [string, string]>): string[];
|
|
64
|
+
/**
|
|
65
|
+
* Build the upgrade-reply headers the runtime posts back to
|
|
66
|
+
* `/_system/response/{requestId}` once the user's handler has called
|
|
67
|
+
* `accept()`.
|
|
68
|
+
*
|
|
69
|
+
* Hop-by-hop headers are stripped; an explicit `subprotocol` is added
|
|
70
|
+
* as `sec-websocket-protocol`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildAcceptReply(acceptOpts: InkboxWebSocketAcceptOpts | undefined): Array<[string, string]>;
|
|
73
|
+
/**
|
|
74
|
+
* Build the inbound headers map exposed to the user's handler. Strips
|
|
75
|
+
* hop-by-hop request headers; preserves the rest verbatim.
|
|
76
|
+
*/
|
|
77
|
+
export declare function buildInboundHeaders(envelope: Envelope): Map<string, string>;
|
|
78
|
+
/**
|
|
79
|
+
* Bridge primitives — supplied by the runtime so this module stays
|
|
80
|
+
* unit-testable in isolation.
|
|
81
|
+
*/
|
|
82
|
+
export interface WsBridgeIO {
|
|
83
|
+
/**
|
|
84
|
+
* Send a chunk of WS-frame bytes on the bridge stream. Resolves when
|
|
85
|
+
* the chunk is on the wire (post-flow-control).
|
|
86
|
+
*/
|
|
87
|
+
sendFrame(frame: Buffer): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Async-iterate inbound h2 DATA chunks from the bridge stream.
|
|
90
|
+
* Completes when the bridge stream's `end` event fires; throws on a
|
|
91
|
+
* `reset` event.
|
|
92
|
+
*/
|
|
93
|
+
recv(): AsyncIterableIterator<Buffer>;
|
|
94
|
+
/** Tear down the bridge stream cleanly. */
|
|
95
|
+
closeStream(): Promise<void>;
|
|
96
|
+
/** Post the upgrade reply (status + headers) to `/_system/response/{id}`. */
|
|
97
|
+
postUpgradeReply(headers: Array<[string, string]>): Promise<void>;
|
|
98
|
+
/** Reject the upgrade with a 4xx/5xx response. */
|
|
99
|
+
rejectUpgrade(status: number, reason: string): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
export interface DispatchWsOpts {
|
|
102
|
+
envelope: Envelope;
|
|
103
|
+
handler: InkboxWsHandler;
|
|
104
|
+
publicHost: string;
|
|
105
|
+
acceptDeadlineMs: number;
|
|
106
|
+
bridge: WsBridgeIO;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The full WS-upgrade lifecycle from envelope → handler → message
|
|
110
|
+
* pump → CLOSE. The runtime calls this from its dispatch loop after
|
|
111
|
+
* confirming the envelope is a `ws-upgrade` route kind.
|
|
112
|
+
*/
|
|
113
|
+
export declare function dispatchWsUpgradeInProcess(opts: DispatchWsOpts): Promise<void>;
|
|
114
|
+
interface WsSessionOpts {
|
|
115
|
+
url: string;
|
|
116
|
+
headers: ReadonlyMap<string, string>;
|
|
117
|
+
offeredProtocols: ReadonlyArray<string>;
|
|
118
|
+
acceptDeadlineMs: number;
|
|
119
|
+
bridge: WsBridgeIO;
|
|
120
|
+
}
|
|
121
|
+
declare class WsSession implements InkboxWebSocket {
|
|
122
|
+
readonly url: string;
|
|
123
|
+
readonly headers: ReadonlyMap<string, string>;
|
|
124
|
+
readonly offeredProtocols: ReadonlyArray<string>;
|
|
125
|
+
private readonly bridge;
|
|
126
|
+
private readonly acceptDeadlineMs;
|
|
127
|
+
private acceptCalled;
|
|
128
|
+
private acceptResolved;
|
|
129
|
+
private acceptReply;
|
|
130
|
+
private closeRequested;
|
|
131
|
+
private closeResolved;
|
|
132
|
+
private inboundQueue;
|
|
133
|
+
private inboundWaiter;
|
|
134
|
+
private envelopeDecoder;
|
|
135
|
+
private frameDecoder;
|
|
136
|
+
constructor(opts: WsSessionOpts);
|
|
137
|
+
accept(opts?: InkboxWebSocketAcceptOpts): Promise<void>;
|
|
138
|
+
send(data: string | Buffer): Promise<void>;
|
|
139
|
+
close(code?: number, reason?: string): Promise<void>;
|
|
140
|
+
[Symbol.asyncIterator](): AsyncIterator<string | Buffer>;
|
|
141
|
+
run(handler: InkboxWsHandler): Promise<void>;
|
|
142
|
+
private runInboundPump;
|
|
143
|
+
private pushInbound;
|
|
144
|
+
}
|
|
145
|
+
export declare const __testing: {
|
|
146
|
+
WsSession: typeof WsSession;
|
|
147
|
+
};
|
|
148
|
+
export {};
|
|
149
|
+
//# sourceMappingURL=_ws.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_ws.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_ws.ts"],"names":[],"mappings":"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"}
|