@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,351 @@
|
|
|
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 { HOP_BY_HOP_RESPONSE } from "./_protocol.js";
|
|
15
|
+
import { WS_OPCODE_BINARY, WS_OPCODE_CLOSE, WS_OPCODE_PING, WS_OPCODE_PONG, WS_OPCODE_TEXT, WsEnvelopeDecoder, WsFrameDecoder, encodeWsEnvelope, encodeWsFrame, } from "./_wsframe.js";
|
|
16
|
+
// --- Public exception types ----------------------------------------------
|
|
17
|
+
export class WsAcceptDeadlineExceeded extends Error {
|
|
18
|
+
constructor(message = "WebSocket accept deadline exceeded") {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "WsAcceptDeadlineExceeded";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class WsProtocolMismatch extends Error {
|
|
24
|
+
constructor(requested, offered) {
|
|
25
|
+
super(`requested subprotocol ${JSON.stringify(requested)} is not in the ` +
|
|
26
|
+
`peer's offered set ${JSON.stringify(offered)}`);
|
|
27
|
+
this.name = "WsProtocolMismatch";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class WsClosed extends Error {
|
|
31
|
+
constructor(message = "WebSocket is closed") {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "WsClosed";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// --- Pure helpers (M1 — unit-testable independent of the runtime) --------
|
|
37
|
+
/**
|
|
38
|
+
* Parse a `Sec-WebSocket-Protocol` header into an ordered list of
|
|
39
|
+
* offered subprotocols. Comma-split, trimmed, empties dropped.
|
|
40
|
+
*/
|
|
41
|
+
export function parseOfferedSubprotocols(forwardedHeaders) {
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const [k, v] of forwardedHeaders) {
|
|
44
|
+
if (k.toLowerCase() !== "sec-websocket-protocol")
|
|
45
|
+
continue;
|
|
46
|
+
for (const piece of v.split(",")) {
|
|
47
|
+
const trimmed = piece.trim();
|
|
48
|
+
if (trimmed)
|
|
49
|
+
out.push(trimmed);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build the upgrade-reply headers the runtime posts back to
|
|
56
|
+
* `/_system/response/{requestId}` once the user's handler has called
|
|
57
|
+
* `accept()`.
|
|
58
|
+
*
|
|
59
|
+
* Hop-by-hop headers are stripped; an explicit `subprotocol` is added
|
|
60
|
+
* as `sec-websocket-protocol`.
|
|
61
|
+
*/
|
|
62
|
+
export function buildAcceptReply(acceptOpts) {
|
|
63
|
+
const out = [];
|
|
64
|
+
if (acceptOpts?.protocol) {
|
|
65
|
+
out.push(["sec-websocket-protocol", acceptOpts.protocol]);
|
|
66
|
+
}
|
|
67
|
+
for (const [k, v] of acceptOpts?.headers ?? []) {
|
|
68
|
+
if (HOP_BY_HOP_RESPONSE.has(k.toLowerCase()))
|
|
69
|
+
continue;
|
|
70
|
+
out.push([k, v]);
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build the inbound headers map exposed to the user's handler. Strips
|
|
76
|
+
* hop-by-hop request headers; preserves the rest verbatim.
|
|
77
|
+
*/
|
|
78
|
+
export function buildInboundHeaders(envelope) {
|
|
79
|
+
const out = new Map();
|
|
80
|
+
for (const [k, v] of envelope.forwardedHeaders) {
|
|
81
|
+
out.set(k.toLowerCase(), v);
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The full WS-upgrade lifecycle from envelope → handler → message
|
|
87
|
+
* pump → CLOSE. The runtime calls this from its dispatch loop after
|
|
88
|
+
* confirming the envelope is a `ws-upgrade` route kind.
|
|
89
|
+
*/
|
|
90
|
+
export async function dispatchWsUpgradeInProcess(opts) {
|
|
91
|
+
const { envelope, handler, publicHost, acceptDeadlineMs, bridge } = opts;
|
|
92
|
+
const offered = parseOfferedSubprotocols(envelope.forwardedHeaders);
|
|
93
|
+
const url = `wss://${publicHost}${envelope.path}`;
|
|
94
|
+
const headers = buildInboundHeaders(envelope);
|
|
95
|
+
const session = new WsSession({
|
|
96
|
+
url,
|
|
97
|
+
headers,
|
|
98
|
+
offeredProtocols: offered,
|
|
99
|
+
acceptDeadlineMs,
|
|
100
|
+
bridge,
|
|
101
|
+
});
|
|
102
|
+
// Drive the user handler. The session manages accept-deadline,
|
|
103
|
+
// pumps, and shutdown internally.
|
|
104
|
+
await session.run(handler);
|
|
105
|
+
}
|
|
106
|
+
class WsSession {
|
|
107
|
+
url;
|
|
108
|
+
headers;
|
|
109
|
+
offeredProtocols;
|
|
110
|
+
bridge;
|
|
111
|
+
acceptDeadlineMs;
|
|
112
|
+
acceptCalled = false;
|
|
113
|
+
acceptResolved = false;
|
|
114
|
+
acceptReply = null;
|
|
115
|
+
closeRequested = false;
|
|
116
|
+
closeResolved = false;
|
|
117
|
+
inboundQueue = [];
|
|
118
|
+
inboundWaiter = null;
|
|
119
|
+
envelopeDecoder = new WsEnvelopeDecoder();
|
|
120
|
+
frameDecoder = new WsFrameDecoder();
|
|
121
|
+
constructor(opts) {
|
|
122
|
+
this.url = opts.url;
|
|
123
|
+
this.headers = opts.headers;
|
|
124
|
+
this.offeredProtocols = opts.offeredProtocols;
|
|
125
|
+
this.bridge = opts.bridge;
|
|
126
|
+
this.acceptDeadlineMs = opts.acceptDeadlineMs;
|
|
127
|
+
}
|
|
128
|
+
// --- public InkboxWebSocket surface ------------------------------------
|
|
129
|
+
async accept(opts) {
|
|
130
|
+
if (this.acceptCalled)
|
|
131
|
+
return;
|
|
132
|
+
if (opts?.protocol !== undefined) {
|
|
133
|
+
if (!this.offeredProtocols.includes(opts.protocol)) {
|
|
134
|
+
throw new WsProtocolMismatch(opts.protocol, this.offeredProtocols);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
this.acceptCalled = true;
|
|
138
|
+
this.acceptReply = buildAcceptReply(opts);
|
|
139
|
+
await this.bridge.postUpgradeReply(this.acceptReply);
|
|
140
|
+
this.acceptResolved = true;
|
|
141
|
+
}
|
|
142
|
+
async send(data) {
|
|
143
|
+
if (this.closeRequested)
|
|
144
|
+
throw new WsClosed();
|
|
145
|
+
if (!this.acceptResolved) {
|
|
146
|
+
throw new WsClosed("send() before accept()");
|
|
147
|
+
}
|
|
148
|
+
let envelope;
|
|
149
|
+
if (typeof data === "string") {
|
|
150
|
+
envelope = encodeWsEnvelope({ type: "websocket.send", text: data });
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
envelope = encodeWsEnvelope({ type: "websocket.send", bytes: data });
|
|
154
|
+
}
|
|
155
|
+
await this.bridge.sendFrame(encodeWsFrame(WS_OPCODE_BINARY, envelope, { mask: true }));
|
|
156
|
+
}
|
|
157
|
+
async close(code = 1000, reason = "") {
|
|
158
|
+
if (this.closeRequested)
|
|
159
|
+
return;
|
|
160
|
+
this.closeRequested = true;
|
|
161
|
+
if (!this.acceptResolved) {
|
|
162
|
+
// Handler called close before accept — reject the upgrade.
|
|
163
|
+
try {
|
|
164
|
+
await this.bridge.rejectUpgrade(403, "handler rejected upgrade");
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
/* swallow */
|
|
168
|
+
}
|
|
169
|
+
this.closeResolved = true;
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
// Send wire-envelope CLOSE and a real WS CLOSE frame.
|
|
173
|
+
const closeEnv = encodeWsEnvelope({ type: "websocket.close", code, reason });
|
|
174
|
+
try {
|
|
175
|
+
await this.bridge.sendFrame(encodeWsFrame(WS_OPCODE_BINARY, closeEnv, { mask: true }));
|
|
176
|
+
const closePayload = Buffer.alloc(2 + Buffer.byteLength(reason, "utf-8"));
|
|
177
|
+
closePayload.writeUInt16BE(code, 0);
|
|
178
|
+
Buffer.from(reason, "utf-8").copy(closePayload, 2);
|
|
179
|
+
await this.bridge.sendFrame(encodeWsFrame(WS_OPCODE_CLOSE, closePayload, { mask: true }));
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
/* swallow — bridge may already be torn down */
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
await this.bridge.closeStream();
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
/* swallow */
|
|
189
|
+
}
|
|
190
|
+
this.closeResolved = true;
|
|
191
|
+
this.pushInbound({ kind: "close" });
|
|
192
|
+
}
|
|
193
|
+
[Symbol.asyncIterator]() {
|
|
194
|
+
return {
|
|
195
|
+
next: async () => {
|
|
196
|
+
while (true) {
|
|
197
|
+
const item = this.inboundQueue.shift();
|
|
198
|
+
if (item !== undefined) {
|
|
199
|
+
if (item.kind === "msg") {
|
|
200
|
+
return { value: item.data, done: false };
|
|
201
|
+
}
|
|
202
|
+
if (item.kind === "close") {
|
|
203
|
+
return { value: undefined, done: true };
|
|
204
|
+
}
|
|
205
|
+
throw item.err;
|
|
206
|
+
}
|
|
207
|
+
await new Promise((resolve) => {
|
|
208
|
+
this.inboundWaiter = resolve;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
// --- runtime-facing driver --------------------------------------------
|
|
215
|
+
async run(handler) {
|
|
216
|
+
// Race the handler vs. the accept-deadline. Use a clearable timer
|
|
217
|
+
// and a manually-rejectable promise so we don't leak the timer
|
|
218
|
+
// after accept resolves.
|
|
219
|
+
let deadlineTimer = null;
|
|
220
|
+
const acceptDeadline = new Promise((_, reject) => {
|
|
221
|
+
deadlineTimer = setTimeout(() => {
|
|
222
|
+
if (!this.acceptCalled) {
|
|
223
|
+
reject(new WsAcceptDeadlineExceeded());
|
|
224
|
+
}
|
|
225
|
+
}, this.acceptDeadlineMs);
|
|
226
|
+
});
|
|
227
|
+
// Holder for the pump task; assigned by `pumpStarter` once accept
|
|
228
|
+
// resolves. Typed as a single-element record so the `null` case
|
|
229
|
+
// doesn't get narrowed to `never` by control-flow analysis.
|
|
230
|
+
const pumpHolder = { promise: null };
|
|
231
|
+
const handlerPromise = (async () => {
|
|
232
|
+
try {
|
|
233
|
+
await handler(this);
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
if (this.acceptResolved && !this.closeRequested) {
|
|
237
|
+
await this.close(1000, "");
|
|
238
|
+
}
|
|
239
|
+
else if (!this.acceptResolved && !this.closeRequested) {
|
|
240
|
+
await this.bridge.rejectUpgrade(500, "handler returned without accept");
|
|
241
|
+
this.closeResolved = true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
})();
|
|
245
|
+
// Start the inbound pump only AFTER accept resolves — otherwise
|
|
246
|
+
// `recv()` can see a still-null bridge-stream id and exit early
|
|
247
|
+
// before any data arrives. We start a watcher that observes
|
|
248
|
+
// `acceptResolved` and kicks off the pump exactly once.
|
|
249
|
+
const pumpStarter = (async () => {
|
|
250
|
+
while (!this.acceptResolved &&
|
|
251
|
+
!this.closeRequested) {
|
|
252
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
253
|
+
}
|
|
254
|
+
if (this.acceptResolved && !this.closeRequested) {
|
|
255
|
+
pumpHolder.promise = this.runInboundPump();
|
|
256
|
+
}
|
|
257
|
+
})();
|
|
258
|
+
try {
|
|
259
|
+
await Promise.race([handlerPromise, acceptDeadline]);
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
if (err instanceof WsAcceptDeadlineExceeded) {
|
|
263
|
+
try {
|
|
264
|
+
await this.bridge.rejectUpgrade(504, "ws upgrade timed out");
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
/* swallow */
|
|
268
|
+
}
|
|
269
|
+
// Mark the session terminal so ``pumpStarter``'s wait loop and
|
|
270
|
+
// ``recv()`` consumers exit promptly. Without this, a handler
|
|
271
|
+
// that ignores the deadline would keep ``acceptResolved`` and
|
|
272
|
+
// ``closeRequested`` both false, leaving ``pumpStarter``
|
|
273
|
+
// spinning until the runtime finally tore the bridge down.
|
|
274
|
+
this.closeRequested = true;
|
|
275
|
+
this.closeResolved = true;
|
|
276
|
+
this.pushInbound({ kind: "error", err });
|
|
277
|
+
// Surface the timeout to caller without blocking on the
|
|
278
|
+
// handler. Detach with a no-op catch so an unhandled-rejection
|
|
279
|
+
// doesn't fire if the handler eventually throws (handler is a
|
|
280
|
+
// user-supplied promise and may take arbitrarily long; we
|
|
281
|
+
// posted the 504 already, so further work is just observable
|
|
282
|
+
// bookkeeping).
|
|
283
|
+
handlerPromise.catch(() => undefined);
|
|
284
|
+
}
|
|
285
|
+
throw err;
|
|
286
|
+
}
|
|
287
|
+
finally {
|
|
288
|
+
if (deadlineTimer !== null)
|
|
289
|
+
clearTimeout(deadlineTimer);
|
|
290
|
+
await pumpStarter.catch(() => undefined);
|
|
291
|
+
if (pumpHolder.promise !== null) {
|
|
292
|
+
await pumpHolder.promise.catch(() => undefined);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
async runInboundPump() {
|
|
297
|
+
try {
|
|
298
|
+
for await (const chunk of this.bridge.recv()) {
|
|
299
|
+
const frames = this.frameDecoder.feed(chunk);
|
|
300
|
+
for (const frame of frames) {
|
|
301
|
+
if (frame.opcode === WS_OPCODE_PING) {
|
|
302
|
+
await this.bridge.sendFrame(encodeWsFrame(WS_OPCODE_PONG, frame.payload, { mask: true }));
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (frame.opcode === WS_OPCODE_PONG)
|
|
306
|
+
continue;
|
|
307
|
+
if (frame.opcode === WS_OPCODE_CLOSE) {
|
|
308
|
+
this.pushInbound({ kind: "close" });
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (frame.opcode === WS_OPCODE_BINARY ||
|
|
312
|
+
frame.opcode === WS_OPCODE_TEXT) {
|
|
313
|
+
const envs = this.envelopeDecoder.feed(frame.payload);
|
|
314
|
+
for (const env of envs) {
|
|
315
|
+
if (env.type === "text") {
|
|
316
|
+
this.pushInbound({ kind: "msg", data: env.data });
|
|
317
|
+
}
|
|
318
|
+
else if (env.type === "binary") {
|
|
319
|
+
this.pushInbound({ kind: "msg", data: env.data });
|
|
320
|
+
}
|
|
321
|
+
else if (env.type === "close") {
|
|
322
|
+
this.pushInbound({ kind: "close" });
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Stream ended without an explicit CLOSE envelope.
|
|
330
|
+
// Per partial-bytes-at-EOF policy: drop trailing buffer bytes
|
|
331
|
+
// silently and signal close to the iterator.
|
|
332
|
+
this.pushInbound({ kind: "close" });
|
|
333
|
+
}
|
|
334
|
+
catch (err) {
|
|
335
|
+
this.pushInbound({
|
|
336
|
+
kind: "error",
|
|
337
|
+
err: err instanceof Error ? err : new Error(String(err)),
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
pushInbound(item) {
|
|
342
|
+
this.inboundQueue.push(item);
|
|
343
|
+
const waiter = this.inboundWaiter;
|
|
344
|
+
if (waiter !== null) {
|
|
345
|
+
this.inboundWaiter = null;
|
|
346
|
+
waiter();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
export const __testing = { WsSession };
|
|
351
|
+
//# sourceMappingURL=_ws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_ws.js","sourceRoot":"","sources":["../../../src/tunnels/client/_ws.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-tunnels/client/_ws_passthrough.ts
|
|
3
|
+
*
|
|
4
|
+
* WebSocket support for passthrough mode.
|
|
5
|
+
*
|
|
6
|
+
* The h1 parser and h2 transcoder hand a {@link WebSocketSink} to the
|
|
7
|
+
* dispatcher when the inbound is a WS upgrade. The dispatcher completes
|
|
8
|
+
* the handshake via `accept` then bridges frames via `sendFrame` /
|
|
9
|
+
* `recvFrame`. The `bridgeWsHandlerOverSink` helper wires an
|
|
10
|
+
* `InkboxWsHandler` to one of those sinks so the same handler shape
|
|
11
|
+
* serves h1 `Upgrade: websocket` and h2 RFC 8441 Extended CONNECT.
|
|
12
|
+
*/
|
|
13
|
+
import type { InkboxWsHandler } from "./_ws.js";
|
|
14
|
+
export declare function computeWsAccept(key: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Encode an unmasked server-to-client frame. RFC 6455 §5.1 — server
|
|
17
|
+
* frames MUST NOT be masked. The shared `_wsframe.encodeWsFrame`
|
|
18
|
+
* defaults to client semantics (masked); this helper enforces unmasked.
|
|
19
|
+
*/
|
|
20
|
+
export declare function encodeServerFrame(opcode: number, payload: Buffer, fin?: boolean): Buffer;
|
|
21
|
+
/**
|
|
22
|
+
* Decode one complete client-to-server frame from `buf`.
|
|
23
|
+
*
|
|
24
|
+
* For h1 WebSockets (RFC 6455 §5.1) client frames MUST be masked;
|
|
25
|
+
* pass `requireMask=true` (default) and the decoder rejects unmasked
|
|
26
|
+
* frames. For h2 WebSockets (RFC 8441 §5.1) frames are NEVER masked —
|
|
27
|
+
* the transcoder passes `requireMask=false` so unmasked payloads are
|
|
28
|
+
* returned verbatim.
|
|
29
|
+
*/
|
|
30
|
+
export declare function decodeClientFrame(buf: Buffer[], opts?: {
|
|
31
|
+
requireMask?: boolean;
|
|
32
|
+
}): {
|
|
33
|
+
kind: "frame";
|
|
34
|
+
opcode: number;
|
|
35
|
+
payload: Buffer;
|
|
36
|
+
fin: boolean;
|
|
37
|
+
} | {
|
|
38
|
+
kind: "need-more";
|
|
39
|
+
} | {
|
|
40
|
+
kind: "rejected";
|
|
41
|
+
};
|
|
42
|
+
export interface WebSocketSink {
|
|
43
|
+
accept(opts?: {
|
|
44
|
+
subprotocol?: string;
|
|
45
|
+
extraHeaders?: Array<[string, string]>;
|
|
46
|
+
}): Promise<void>;
|
|
47
|
+
reject(opts?: {
|
|
48
|
+
status?: number;
|
|
49
|
+
reason?: string;
|
|
50
|
+
}): Promise<void>;
|
|
51
|
+
sendFrame(opcode: number, payload: Buffer, opts?: {
|
|
52
|
+
fin?: boolean;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
recvFrame(): Promise<{
|
|
55
|
+
opcode: number;
|
|
56
|
+
payload: Buffer;
|
|
57
|
+
fin: boolean;
|
|
58
|
+
} | null>;
|
|
59
|
+
aclose(): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
export interface WsPassthroughRequestMeta {
|
|
62
|
+
url: string;
|
|
63
|
+
headers: ReadonlyMap<string, string>;
|
|
64
|
+
offeredSubprotocols: string[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Drive an `InkboxWsHandler` against a `WebSocketSink`. Constructs an
|
|
68
|
+
* `InkboxWebSocket`-shaped object whose lifecycle (`accept`, `send`,
|
|
69
|
+
* `close`, async-iterator) maps onto the sink's frame I/O.
|
|
70
|
+
*/
|
|
71
|
+
export declare function bridgeWsHandlerOverSink(opts: {
|
|
72
|
+
handler: InkboxWsHandler;
|
|
73
|
+
sink: WebSocketSink;
|
|
74
|
+
meta: WsPassthroughRequestMeta;
|
|
75
|
+
}): Promise<void>;
|
|
76
|
+
export interface ByteChannelSinkOpts {
|
|
77
|
+
/** Plaintext bytes to write back on the wire. */
|
|
78
|
+
sendPlaintext: (data: Buffer) => Promise<void>;
|
|
79
|
+
/** Build the protocol-appropriate accept response (h1 = 101 head; h2 = :status 200). */
|
|
80
|
+
buildAcceptResponse: (subprotocol: string | null, extraHeaders: Array<[string, string]> | null) => Buffer;
|
|
81
|
+
/** Build the protocol-appropriate reject response. */
|
|
82
|
+
buildRejectResponse: (status: number) => Buffer;
|
|
83
|
+
/** Optional teardown callback. */
|
|
84
|
+
onClose?: () => Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* h1 transports require client-to-server frames to be masked
|
|
87
|
+
* (RFC 6455 §5.1); h2 transports require them to be unmasked
|
|
88
|
+
* (RFC 8441 §5.1). Default: true.
|
|
89
|
+
*/
|
|
90
|
+
requireClientMask?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Common `WebSocketSink` impl backed by an inbound byte queue + outbound
|
|
94
|
+
* send callback. The h1 parser drives this from a node:http upgrade
|
|
95
|
+
* socket; the h2 transcoder drives the same shape from Extended-CONNECT
|
|
96
|
+
* stream DATA frames.
|
|
97
|
+
*/
|
|
98
|
+
export declare class ByteChannelWebSocketSink implements WebSocketSink {
|
|
99
|
+
private readonly sendPlaintext;
|
|
100
|
+
private readonly buildAccept;
|
|
101
|
+
private readonly buildReject;
|
|
102
|
+
private readonly onCloseHook?;
|
|
103
|
+
private readonly requireClientMask;
|
|
104
|
+
private inboundChunks;
|
|
105
|
+
private inboundResolvers;
|
|
106
|
+
private inboundClosed;
|
|
107
|
+
private accepted;
|
|
108
|
+
private closed;
|
|
109
|
+
constructor(opts: ByteChannelSinkOpts);
|
|
110
|
+
feedInbound(data: Buffer): void;
|
|
111
|
+
signalInboundEof(): void;
|
|
112
|
+
accept(opts?: {
|
|
113
|
+
subprotocol?: string;
|
|
114
|
+
extraHeaders?: Array<[string, string]>;
|
|
115
|
+
}): Promise<void>;
|
|
116
|
+
reject(opts?: {
|
|
117
|
+
status?: number;
|
|
118
|
+
}): Promise<void>;
|
|
119
|
+
sendFrame(opcode: number, payload: Buffer, opts?: {
|
|
120
|
+
fin?: boolean;
|
|
121
|
+
}): Promise<void>;
|
|
122
|
+
recvFrame(): Promise<{
|
|
123
|
+
opcode: number;
|
|
124
|
+
payload: Buffer;
|
|
125
|
+
fin: boolean;
|
|
126
|
+
} | null>;
|
|
127
|
+
aclose(): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=_ws_passthrough.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_ws_passthrough.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_ws_passthrough.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,UAAU,CAAC;AAWjE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAInD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,GAAG,UAAO,GACT,MAAM,CAiBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAE9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAgEvB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,IAAI,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;KACxC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClB,MAAM,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,SAAS,CACP,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,SAAS,IAAI,OAAO,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,OAAO,CAAC;KACd,GAAG,IAAI,CAAC,CAAC;IACV,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,OAAO,EAAE,eAAe,CAAC;IACzB,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,wBAAwB,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAiMhB;AAID,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,wFAAwF;IACxF,mBAAmB,EAAE,CACnB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,YAAY,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,KACzC,MAAM,CAAC;IACZ,sDAAsD;IACtD,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,YAAW,aAAa;IAC5D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAChE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGhB;IACZ,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,IAAI,EAAE,mBAAmB;IAQrC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ/B,gBAAgB,IAAI,IAAI;IAOlB,MAAM,CAAC,IAAI,CAAC,EAAE;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;KACxC,GAAG,OAAO,CAAC,IAAI,CAAC;IAUX,MAAM,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjD,SAAS,CACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,GACvB,OAAO,CAAC,IAAI,CAAC;IAOV,SAAS,IAAI,OAAO,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,OAAO,CAAC;KACd,GAAG,IAAI,CAAC;IAqBH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAY9B"}
|