@inkbox/sdk 0.2.16 → 0.3.1
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,488 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-tunnels/client/_h2_transcode.ts
|
|
3
|
+
*
|
|
4
|
+
* Server-side HTTP/2 fed by TLS plaintext via the WireDuplex pattern.
|
|
5
|
+
* Each h2 stream becomes a `DispatchRequest` handed to a `Dispatch`
|
|
6
|
+
* impl; the dispatcher's streamed response is encoded back into
|
|
7
|
+
* HEADERS+DATA+END_STREAM frames.
|
|
8
|
+
*
|
|
9
|
+
* Implements the Plaintext adapter contract used by the runtime in
|
|
10
|
+
* passthrough mode after the TLS terminator.
|
|
11
|
+
*
|
|
12
|
+
* WebSocket-over-h2 (RFC 8441 Extended CONNECT) is supported when the
|
|
13
|
+
* dispatcher exposes ``dispatchWebSocket``: the transcoder builds a
|
|
14
|
+
* byte-channel sink whose inbound DATA frames feed a frame decoder
|
|
15
|
+
* (unmasked per RFC 8441 §5.1) and whose outbound bytes ride h2 DATA
|
|
16
|
+
* frames. Dispatchers without that method respond ``:status 501``.
|
|
17
|
+
*/
|
|
18
|
+
import * as http2 from "node:http2";
|
|
19
|
+
import { Duplex } from "node:stream";
|
|
20
|
+
import { HOP_BY_HOP_RESPONSE } from "./_protocol.js";
|
|
21
|
+
import { ByteChannelWebSocketSink } from "./_ws_passthrough.js";
|
|
22
|
+
const OUTBOUND_END = Symbol("outbound-end");
|
|
23
|
+
/**
|
|
24
|
+
* Wire-bytes Duplex injected into `http2.createServer()` via
|
|
25
|
+
* `server.emit("connection", duplex)`. Node's h2 server probes a small
|
|
26
|
+
* Socket-like surface on its underlying transport — the methods listed
|
|
27
|
+
* below cover the contract.
|
|
28
|
+
*/
|
|
29
|
+
class H2WireDuplex extends Duplex {
|
|
30
|
+
inbound = [];
|
|
31
|
+
outboundQueue = [];
|
|
32
|
+
outboundResolvers = [];
|
|
33
|
+
constructor() {
|
|
34
|
+
super({ allowHalfOpen: true });
|
|
35
|
+
}
|
|
36
|
+
pushIncoming(buf) {
|
|
37
|
+
this.inbound.push(buf);
|
|
38
|
+
this._read(0);
|
|
39
|
+
}
|
|
40
|
+
takeOutbound() {
|
|
41
|
+
if (this.outboundQueue.length > 0) {
|
|
42
|
+
return Promise.resolve(this.outboundQueue.shift());
|
|
43
|
+
}
|
|
44
|
+
return new Promise((resolve) => this.outboundResolvers.push(resolve));
|
|
45
|
+
}
|
|
46
|
+
endOutbound() {
|
|
47
|
+
this._enqueueOutbound(OUTBOUND_END);
|
|
48
|
+
}
|
|
49
|
+
_read(_size) {
|
|
50
|
+
while (this.inbound.length > 0) {
|
|
51
|
+
const chunk = this.inbound.shift();
|
|
52
|
+
if (!this.push(chunk))
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
_write(chunk, _enc, cb) {
|
|
57
|
+
const buf = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
|
|
58
|
+
this._enqueueOutbound(buf);
|
|
59
|
+
cb();
|
|
60
|
+
}
|
|
61
|
+
_final(cb) {
|
|
62
|
+
cb();
|
|
63
|
+
}
|
|
64
|
+
setTimeout(_ms, _cb) { return this; }
|
|
65
|
+
setNoDelay(_b) { return this; }
|
|
66
|
+
setKeepAlive(_b, _ms) { return this; }
|
|
67
|
+
unref() { return this; }
|
|
68
|
+
ref() { return this; }
|
|
69
|
+
address() {
|
|
70
|
+
return { port: 0, family: "IPv4", address: "127.0.0.1" };
|
|
71
|
+
}
|
|
72
|
+
get remoteAddress() { return "127.0.0.1"; }
|
|
73
|
+
get remoteFamily() { return "IPv4"; }
|
|
74
|
+
get remotePort() { return 0; }
|
|
75
|
+
get localAddress() { return "127.0.0.1"; }
|
|
76
|
+
get localPort() { return 0; }
|
|
77
|
+
_enqueueOutbound(item) {
|
|
78
|
+
if (this.outboundResolvers.length > 0) {
|
|
79
|
+
this.outboundResolvers.shift()(item);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.outboundQueue.push(item);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Re-exported under the legacy local name; canonical source is
|
|
86
|
+
// ``_protocol.HOP_BY_HOP_RESPONSE``. Earlier copies drifted to the
|
|
87
|
+
// wrong "trailers" token (TE/Connection value) instead of the
|
|
88
|
+
// "trailer" header name.
|
|
89
|
+
const RESPONSE_HOP_BY_HOP = HOP_BY_HOP_RESPONSE;
|
|
90
|
+
/**
|
|
91
|
+
* h2 server fed by TLS plaintext; routes streams to a Dispatch impl.
|
|
92
|
+
* One instance per third-party TLS session.
|
|
93
|
+
*/
|
|
94
|
+
export class H2TranscoderPlaintext {
|
|
95
|
+
wire;
|
|
96
|
+
server;
|
|
97
|
+
maxInboundBodyBytes;
|
|
98
|
+
forwardedForIp;
|
|
99
|
+
sniHost;
|
|
100
|
+
closed = false;
|
|
101
|
+
constructor(opts) {
|
|
102
|
+
this.wire = new H2WireDuplex();
|
|
103
|
+
this.maxInboundBodyBytes = opts.maxInboundBodyBytes;
|
|
104
|
+
this.forwardedForIp = opts.forwardedForIp;
|
|
105
|
+
this.sniHost = opts.sniHost;
|
|
106
|
+
this.server = http2.createServer({
|
|
107
|
+
settings: {
|
|
108
|
+
enablePush: false,
|
|
109
|
+
maxConcurrentStreams: 100,
|
|
110
|
+
enableConnectProtocol: true,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
this.server.on("stream", (stream, headers) => {
|
|
114
|
+
void this.handleStream(opts.dispatch, stream, headers);
|
|
115
|
+
});
|
|
116
|
+
this.server.emit("connection", this.wire);
|
|
117
|
+
}
|
|
118
|
+
async feed(plaintext) {
|
|
119
|
+
if (this.closed)
|
|
120
|
+
return;
|
|
121
|
+
this.wire.pushIncoming(plaintext);
|
|
122
|
+
}
|
|
123
|
+
async pumpOutbound(send) {
|
|
124
|
+
while (true) {
|
|
125
|
+
const item = await this.wire.takeOutbound();
|
|
126
|
+
if (item === OUTBOUND_END)
|
|
127
|
+
return;
|
|
128
|
+
try {
|
|
129
|
+
await send(item);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async aclose() {
|
|
137
|
+
if (this.closed)
|
|
138
|
+
return;
|
|
139
|
+
this.closed = true;
|
|
140
|
+
try {
|
|
141
|
+
this.server.close();
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
/* swallow */
|
|
145
|
+
}
|
|
146
|
+
this.wire.endOutbound();
|
|
147
|
+
}
|
|
148
|
+
async handleStream(dispatch, stream, headers) {
|
|
149
|
+
const method = headers[":method"] ?? "GET";
|
|
150
|
+
const path = headers[":path"] ?? "/";
|
|
151
|
+
const protocol = headers[":protocol"];
|
|
152
|
+
const isWebSocket = method === "CONNECT" &&
|
|
153
|
+
typeof protocol === "string" &&
|
|
154
|
+
protocol.toLowerCase() === "websocket";
|
|
155
|
+
// WebSocket-over-h2 — if the dispatcher exposes
|
|
156
|
+
// ``dispatchWebSocket``, build a byte-channel sink whose inbound
|
|
157
|
+
// bytes come from the stream's DATA frames (unmasked per RFC 8441
|
|
158
|
+
// §5.1) and whose outbound bytes flow back as DATA frames. Falls
|
|
159
|
+
// back to 501 when the dispatcher can't service WS upgrades.
|
|
160
|
+
if (isWebSocket) {
|
|
161
|
+
if (typeof dispatch.dispatchWebSocket === "function") {
|
|
162
|
+
await this.handleWebSocketStream(dispatch, stream, headers, method, path);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
stream.respond({
|
|
167
|
+
":status": 501,
|
|
168
|
+
"content-type": "text/plain",
|
|
169
|
+
"inkbox-reason": "websocket-over-h2-not-implemented",
|
|
170
|
+
});
|
|
171
|
+
stream.end();
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
/* swallow */
|
|
175
|
+
}
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const flatHeaders = [];
|
|
179
|
+
let wsSubprotocol = null;
|
|
180
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
181
|
+
if (Array.isArray(v)) {
|
|
182
|
+
for (const item of v)
|
|
183
|
+
flatHeaders.push([k, item]);
|
|
184
|
+
}
|
|
185
|
+
else if (typeof v === "string") {
|
|
186
|
+
flatHeaders.push([k, v]);
|
|
187
|
+
}
|
|
188
|
+
if (k === "sec-websocket-protocol" && typeof v === "string") {
|
|
189
|
+
wsSubprotocol = v;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
let inboundCount = 0;
|
|
193
|
+
let oversize = false;
|
|
194
|
+
const bodyChunks = [];
|
|
195
|
+
const bodyResolvers = [];
|
|
196
|
+
const enqueue = (item) => {
|
|
197
|
+
if (bodyResolvers.length > 0) {
|
|
198
|
+
bodyResolvers.shift()(item);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
bodyChunks.push(item);
|
|
202
|
+
};
|
|
203
|
+
stream.on("data", (chunk) => {
|
|
204
|
+
if (oversize)
|
|
205
|
+
return;
|
|
206
|
+
const buf = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
|
|
207
|
+
inboundCount += buf.length;
|
|
208
|
+
if (inboundCount > this.maxInboundBodyBytes) {
|
|
209
|
+
oversize = true;
|
|
210
|
+
try {
|
|
211
|
+
stream.close(http2.constants.NGHTTP2_REFUSED_STREAM);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
/* swallow */
|
|
215
|
+
}
|
|
216
|
+
enqueue(null);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
enqueue(buf);
|
|
220
|
+
});
|
|
221
|
+
stream.on("end", () => enqueue(null));
|
|
222
|
+
stream.on("error", () => enqueue(null));
|
|
223
|
+
stream.on("close", () => enqueue(null));
|
|
224
|
+
async function* bodyIter() {
|
|
225
|
+
while (true) {
|
|
226
|
+
if (bodyChunks.length > 0) {
|
|
227
|
+
const item = bodyChunks.shift();
|
|
228
|
+
if (item === null)
|
|
229
|
+
return;
|
|
230
|
+
yield item;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const item = await new Promise((resolve) => bodyResolvers.push(resolve));
|
|
234
|
+
if (item === null)
|
|
235
|
+
return;
|
|
236
|
+
yield item;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const dispatchRequest = {
|
|
240
|
+
method,
|
|
241
|
+
path,
|
|
242
|
+
headers: flatHeaders,
|
|
243
|
+
body: bodyIter(),
|
|
244
|
+
forwardedForIp: this.forwardedForIp,
|
|
245
|
+
sniHost: this.sniHost,
|
|
246
|
+
isWebSocket: false,
|
|
247
|
+
wsSubprotocol,
|
|
248
|
+
transport: "h2",
|
|
249
|
+
};
|
|
250
|
+
const sink = makeSink(stream);
|
|
251
|
+
try {
|
|
252
|
+
await dispatch.dispatch(dispatchRequest, sink);
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
try {
|
|
256
|
+
if (!sink.headSent) {
|
|
257
|
+
stream.respond({ ":status": 502 });
|
|
258
|
+
stream.end("upstream error");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
/* swallow */
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
if (!stream.closed && !sink.bodyEnded)
|
|
267
|
+
stream.end();
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
/* swallow */
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
async handleWebSocketStream(dispatch, stream, headers, method, path) {
|
|
274
|
+
const flatHeaders = [];
|
|
275
|
+
let wsSubprotocol = null;
|
|
276
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
277
|
+
if (Array.isArray(v)) {
|
|
278
|
+
for (const item of v)
|
|
279
|
+
flatHeaders.push([k, item]);
|
|
280
|
+
}
|
|
281
|
+
else if (typeof v === "string") {
|
|
282
|
+
flatHeaders.push([k, v]);
|
|
283
|
+
}
|
|
284
|
+
if (k === "sec-websocket-protocol" && typeof v === "string") {
|
|
285
|
+
wsSubprotocol = v;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
let acceptInvoked = false;
|
|
289
|
+
const buildAccept = (subprotocol, extraHeaders) => {
|
|
290
|
+
acceptInvoked = true;
|
|
291
|
+
const out = { ":status": 200 };
|
|
292
|
+
if (subprotocol !== null) {
|
|
293
|
+
out["sec-websocket-protocol"] = subprotocol;
|
|
294
|
+
}
|
|
295
|
+
if (extraHeaders !== null) {
|
|
296
|
+
// Application-defined response headers — set-cookie, custom
|
|
297
|
+
// X-* flags, etc. Multi-value support via array, mirroring
|
|
298
|
+
// the h1 path. Caller has already filtered hop-by-hop /
|
|
299
|
+
// handshake-control headers.
|
|
300
|
+
for (const [hk, hv] of extraHeaders) {
|
|
301
|
+
const kl = hk.toLowerCase();
|
|
302
|
+
const existing = out[kl];
|
|
303
|
+
if (existing === undefined) {
|
|
304
|
+
out[kl] = hv;
|
|
305
|
+
}
|
|
306
|
+
else if (Array.isArray(existing)) {
|
|
307
|
+
existing.push(hv);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
out[kl] = [String(existing), hv];
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
try {
|
|
315
|
+
stream.respond(out);
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
/* swallow */
|
|
319
|
+
}
|
|
320
|
+
return Buffer.alloc(0);
|
|
321
|
+
};
|
|
322
|
+
const buildReject = (status) => {
|
|
323
|
+
try {
|
|
324
|
+
stream.respond({
|
|
325
|
+
":status": status,
|
|
326
|
+
"inkbox-reason": "websocket-rejected",
|
|
327
|
+
}, { endStream: true });
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
/* swallow */
|
|
331
|
+
}
|
|
332
|
+
return Buffer.alloc(0);
|
|
333
|
+
};
|
|
334
|
+
const sendPlaintext = async (data) => {
|
|
335
|
+
if (data.length === 0)
|
|
336
|
+
return;
|
|
337
|
+
await new Promise((resolve) => {
|
|
338
|
+
try {
|
|
339
|
+
if (stream.write(data)) {
|
|
340
|
+
resolve();
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
stream.once("drain", () => resolve());
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
resolve();
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
};
|
|
351
|
+
const sink = new ByteChannelWebSocketSink({
|
|
352
|
+
sendPlaintext,
|
|
353
|
+
buildAcceptResponse: buildAccept,
|
|
354
|
+
buildRejectResponse: buildReject,
|
|
355
|
+
requireClientMask: false, // RFC 8441 §5.1 — h2 WS frames unmasked
|
|
356
|
+
onClose: async () => {
|
|
357
|
+
try {
|
|
358
|
+
if (!stream.closed)
|
|
359
|
+
stream.end();
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
/* swallow */
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
const wsSink = sink;
|
|
367
|
+
stream.on("data", (chunk) => {
|
|
368
|
+
const buf = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
|
|
369
|
+
wsSink.feedInbound(buf);
|
|
370
|
+
});
|
|
371
|
+
stream.on("end", () => wsSink.signalInboundEof());
|
|
372
|
+
stream.on("close", () => wsSink.signalInboundEof());
|
|
373
|
+
stream.on("error", () => wsSink.signalInboundEof());
|
|
374
|
+
const dispatchRequest = {
|
|
375
|
+
method,
|
|
376
|
+
path,
|
|
377
|
+
headers: flatHeaders,
|
|
378
|
+
body: emptyAsyncIter(),
|
|
379
|
+
forwardedForIp: this.forwardedForIp,
|
|
380
|
+
sniHost: this.sniHost,
|
|
381
|
+
isWebSocket: true,
|
|
382
|
+
wsSubprotocol,
|
|
383
|
+
transport: "h2",
|
|
384
|
+
};
|
|
385
|
+
try {
|
|
386
|
+
await dispatch.dispatchWebSocket(dispatchRequest, wsSink);
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
if (!acceptInvoked) {
|
|
390
|
+
try {
|
|
391
|
+
await wsSink.reject({ status: 500 });
|
|
392
|
+
}
|
|
393
|
+
catch {
|
|
394
|
+
/* swallow */
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
finally {
|
|
399
|
+
try {
|
|
400
|
+
await wsSink.aclose();
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
/* swallow */
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
async function* emptyAsyncIter() {
|
|
409
|
+
if (false)
|
|
410
|
+
yield Buffer.alloc(0);
|
|
411
|
+
}
|
|
412
|
+
function makeSink(stream) {
|
|
413
|
+
const state = { headSent: false, bodyEnded: false };
|
|
414
|
+
return {
|
|
415
|
+
get headSent() { return state.headSent; },
|
|
416
|
+
get bodyEnded() { return state.bodyEnded; },
|
|
417
|
+
async sendHead(head) {
|
|
418
|
+
if (state.headSent)
|
|
419
|
+
return;
|
|
420
|
+
state.headSent = true;
|
|
421
|
+
const out = { ":status": head.status };
|
|
422
|
+
for (const [k, v] of head.headers) {
|
|
423
|
+
const kl = k.toLowerCase();
|
|
424
|
+
if (RESPONSE_HOP_BY_HOP.has(kl))
|
|
425
|
+
continue;
|
|
426
|
+
if (kl.startsWith(":"))
|
|
427
|
+
continue;
|
|
428
|
+
// Accumulate duplicates as arrays.
|
|
429
|
+
const existing = out[kl];
|
|
430
|
+
if (existing === undefined) {
|
|
431
|
+
out[kl] = v;
|
|
432
|
+
}
|
|
433
|
+
else if (Array.isArray(existing)) {
|
|
434
|
+
existing.push(v);
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
out[kl] = [String(existing), v];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
try {
|
|
441
|
+
stream.respond(out);
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
/* stream closed before respond — swallow */
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
async sendBody(chunk) {
|
|
448
|
+
if (state.bodyEnded || chunk.length === 0)
|
|
449
|
+
return;
|
|
450
|
+
await new Promise((resolve) => {
|
|
451
|
+
// stream.write may return false → wait for drain.
|
|
452
|
+
const ok = stream.write(chunk, (err) => {
|
|
453
|
+
if (err)
|
|
454
|
+
resolve(); // best effort; let the server drain naturally
|
|
455
|
+
else
|
|
456
|
+
resolve();
|
|
457
|
+
});
|
|
458
|
+
if (!ok) {
|
|
459
|
+
// Still resolved by the callback; nothing else to do here.
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
},
|
|
463
|
+
async endBody() {
|
|
464
|
+
if (state.bodyEnded)
|
|
465
|
+
return;
|
|
466
|
+
state.bodyEnded = true;
|
|
467
|
+
try {
|
|
468
|
+
await new Promise((resolve) => stream.end(resolve));
|
|
469
|
+
}
|
|
470
|
+
catch {
|
|
471
|
+
/* swallow */
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
async reset(reason) {
|
|
475
|
+
if (state.bodyEnded)
|
|
476
|
+
return;
|
|
477
|
+
state.bodyEnded = true;
|
|
478
|
+
try {
|
|
479
|
+
stream.close(http2.constants.NGHTTP2_INTERNAL_ERROR);
|
|
480
|
+
}
|
|
481
|
+
catch {
|
|
482
|
+
/* swallow */
|
|
483
|
+
}
|
|
484
|
+
void reason;
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
//# sourceMappingURL=_h2_transcode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_h2_transcode.js","sourceRoot":"","sources":["../../../src/tunnels/client/_h2_transcode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inkbox-tunnels/client/_handler.ts
|
|
3
|
+
*
|
|
4
|
+
* In-process Fetch-API HTTP handler. The user supplies a
|
|
5
|
+
* `(req: Request, ctx: InkboxRequestContext) => Response | Promise<Response>`
|
|
6
|
+
* function; the runtime synthesizes a `Request` from the envelope,
|
|
7
|
+
* invokes the handler, reads the response with the same per-chunk size
|
|
8
|
+
* cap as the URL-forward path, and returns a discriminated union the
|
|
9
|
+
* runtime maps onto fixed on-wire response shapes.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors Python `_asgi.py` semantics at the wire level. The TS-side
|
|
12
|
+
* shape is Web standards (Fetch API) instead of ASGI 3.0.
|
|
13
|
+
*/
|
|
14
|
+
import type { Envelope, ReadonlyEnvelope } from "./_envelope.js";
|
|
15
|
+
export interface InkboxRequestContext {
|
|
16
|
+
/**
|
|
17
|
+
* Tripped when the runtime's deadline expires. Plumbed through to
|
|
18
|
+
* the handler so user code can react cooperatively.
|
|
19
|
+
*/
|
|
20
|
+
signal: AbortSignal;
|
|
21
|
+
/**
|
|
22
|
+
* Best-effort original client IP (from the inkbox forwarded-for
|
|
23
|
+
* meta header). null when not advertised by the server.
|
|
24
|
+
*/
|
|
25
|
+
forwardedForIp: string | null;
|
|
26
|
+
/** SNI host as observed at the public ingress, when available. */
|
|
27
|
+
sniHost: string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Read-only access to the parsed envelope for callers that need
|
|
30
|
+
* metadata not exposed elsewhere on the context. Escape hatch only;
|
|
31
|
+
* prefer the typed fields above.
|
|
32
|
+
*/
|
|
33
|
+
envelope: ReadonlyEnvelope;
|
|
34
|
+
}
|
|
35
|
+
export type InkboxHandler = (req: Request, ctx: InkboxRequestContext) => Response | Promise<Response>;
|
|
36
|
+
export type InProcessHttpResult = {
|
|
37
|
+
kind: "ok";
|
|
38
|
+
status: number;
|
|
39
|
+
headers: Array<[string, string]>;
|
|
40
|
+
body: Buffer;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "too-large";
|
|
43
|
+
status: 502;
|
|
44
|
+
inkboxReason: "response-too-large";
|
|
45
|
+
} | {
|
|
46
|
+
kind: "handler-error";
|
|
47
|
+
status: 502;
|
|
48
|
+
inkboxReason: "handler-error";
|
|
49
|
+
};
|
|
50
|
+
export interface DispatchHttpInProcessOpts {
|
|
51
|
+
envelope: Envelope;
|
|
52
|
+
handler: InkboxHandler;
|
|
53
|
+
publicHost: string;
|
|
54
|
+
maxResponseBytes: number;
|
|
55
|
+
signal: AbortSignal;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Synthesize a `Request` from the envelope, invoke the handler, read
|
|
59
|
+
* back the response under the size cap.
|
|
60
|
+
*/
|
|
61
|
+
export declare function dispatchHttpInProcess(opts: DispatchHttpInProcessOpts): Promise<InProcessHttpResult>;
|
|
62
|
+
//# sourceMappingURL=_handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_handler.d.ts","sourceRoot":"","sources":["../../../src/tunnels/client/_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGjE,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,MAAM,EAAE,WAAW,CAAC;IACpB;;;OAGG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kEAAkE;IAClE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;OAIG;IACH,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,oBAAoB,KACtB,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAElC,MAAM,MAAM,mBAAmB,GAC3B;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,eAAe,CAAC;IACtB,MAAM,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,eAAe,CAAC;CAC/B,CAAC;AAEN,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAyG9B"}
|