@replit/river 0.21.1 → 0.22.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 +1 -1
- package/dist/{chunk-5WFL722S.js → chunk-3MFX6NXA.js} +94 -3
- package/dist/chunk-3MFX6NXA.js.map +1 -0
- package/dist/{chunk-NCXUFDVL.js → chunk-GCLEWC26.js} +328 -500
- package/dist/chunk-GCLEWC26.js.map +1 -0
- package/dist/chunk-HUBFYN37.js +60 -0
- package/dist/chunk-HUBFYN37.js.map +1 -0
- package/dist/{chunk-FDLAPYCK.js → chunk-S3YKQT4J.js} +2 -2
- package/dist/{chunk-JMXO5L2X.js → chunk-ZPBWKBM5.js} +344 -384
- package/dist/chunk-ZPBWKBM5.js.map +1 -0
- package/dist/{connection-76c5ed01.d.ts → connection-8b059ac4.d.ts} +6 -4
- package/dist/{connection-975b25c9.d.ts → connection-bbfe1147.d.ts} +1 -1
- package/dist/{index-dfad460e.d.ts → index-2ece5234.d.ts} +16 -7
- package/dist/logging/index.d.cts +2 -1
- package/dist/logging/index.d.ts +2 -1
- package/dist/router/index.cjs +373 -486
- package/dist/router/index.cjs.map +1 -1
- package/dist/router/index.d.cts +5 -4
- package/dist/router/index.d.ts +5 -4
- package/dist/router/index.js +4 -3
- package/dist/{services-7b716dcf.d.ts → services-acbcc441.d.ts} +1 -1
- package/dist/{services-9c496c6e.d.ts → services-cb01a7a8.d.ts} +1 -1
- package/dist/transport/impls/uds/client.cjs +186 -145
- package/dist/transport/impls/uds/client.cjs.map +1 -1
- package/dist/transport/impls/uds/client.d.cts +3 -2
- package/dist/transport/impls/uds/client.d.ts +3 -2
- package/dist/transport/impls/uds/client.js +3 -3
- package/dist/transport/impls/uds/server.cjs +281 -256
- package/dist/transport/impls/uds/server.cjs.map +1 -1
- package/dist/transport/impls/uds/server.d.cts +3 -2
- package/dist/transport/impls/uds/server.d.ts +3 -2
- package/dist/transport/impls/uds/server.js +3 -3
- package/dist/transport/impls/ws/client.cjs +240 -204
- package/dist/transport/impls/ws/client.cjs.map +1 -1
- package/dist/transport/impls/ws/client.d.cts +6 -6
- package/dist/transport/impls/ws/client.d.ts +6 -6
- package/dist/transport/impls/ws/client.js +33 -48
- package/dist/transport/impls/ws/client.js.map +1 -1
- package/dist/transport/impls/ws/server.cjs +303 -270
- package/dist/transport/impls/ws/server.cjs.map +1 -1
- package/dist/transport/impls/ws/server.d.cts +5 -4
- package/dist/transport/impls/ws/server.d.ts +5 -4
- package/dist/transport/impls/ws/server.js +3 -3
- package/dist/transport/impls/ws/server.js.map +1 -1
- package/dist/transport/index.cjs +390 -382
- package/dist/transport/index.cjs.map +1 -1
- package/dist/transport/index.d.cts +5 -5
- package/dist/transport/index.d.ts +5 -5
- package/dist/transport/index.js +2 -2
- package/dist/util/testHelpers.cjs +57 -7
- package/dist/util/testHelpers.cjs.map +1 -1
- package/dist/util/testHelpers.d.cts +14 -5
- package/dist/util/testHelpers.d.ts +14 -5
- package/dist/util/testHelpers.js +10 -4
- package/dist/util/testHelpers.js.map +1 -1
- package/dist/wslike-e0b32dd5.d.ts +40 -0
- package/package.json +4 -5
- package/dist/chunk-3Y7AB5EB.js +0 -42
- package/dist/chunk-3Y7AB5EB.js.map +0 -1
- package/dist/chunk-5WFL722S.js.map +0 -1
- package/dist/chunk-JMXO5L2X.js.map +0 -1
- package/dist/chunk-NCXUFDVL.js.map +0 -1
- /package/dist/{chunk-FDLAPYCK.js.map → chunk-S3YKQT4J.js.map} +0 -0
|
@@ -26,7 +26,6 @@ module.exports = __toCommonJS(server_exports);
|
|
|
26
26
|
|
|
27
27
|
// transport/transport.ts
|
|
28
28
|
var import_value = require("@sinclair/typebox/value");
|
|
29
|
-
var import_api2 = require("@opentelemetry/api");
|
|
30
29
|
|
|
31
30
|
// transport/message.ts
|
|
32
31
|
var import_typebox = require("@sinclair/typebox");
|
|
@@ -142,17 +141,62 @@ var EventDispatcher = class {
|
|
|
142
141
|
|
|
143
142
|
// transport/session.ts
|
|
144
143
|
var import_nanoid2 = require("nanoid");
|
|
144
|
+
|
|
145
|
+
// tracing/index.ts
|
|
146
|
+
var import_api = require("@opentelemetry/api");
|
|
147
|
+
|
|
148
|
+
// package.json
|
|
149
|
+
var version = "0.22.0";
|
|
150
|
+
|
|
151
|
+
// tracing/index.ts
|
|
152
|
+
function createSessionTelemetryInfo(session, propagationCtx) {
|
|
153
|
+
const ctx = propagationCtx ? import_api.propagation.extract(import_api.context.active(), propagationCtx) : import_api.context.active();
|
|
154
|
+
const span = tracer.startSpan(
|
|
155
|
+
`session ${session.id}`,
|
|
156
|
+
{
|
|
157
|
+
attributes: {
|
|
158
|
+
component: "river",
|
|
159
|
+
"river.session.id": session.id,
|
|
160
|
+
"river.session.to": session.to,
|
|
161
|
+
"river.session.from": session.from
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
ctx
|
|
165
|
+
);
|
|
166
|
+
return { span, ctx };
|
|
167
|
+
}
|
|
168
|
+
function createConnectionTelemetryInfo(connection, sessionSpan) {
|
|
169
|
+
const ctx = import_api.trace.setSpan(import_api.context.active(), sessionSpan);
|
|
170
|
+
const span = tracer.startSpan(
|
|
171
|
+
`connection ${connection.id}`,
|
|
172
|
+
{
|
|
173
|
+
attributes: {
|
|
174
|
+
component: "river",
|
|
175
|
+
"river.connection.id": connection.id
|
|
176
|
+
},
|
|
177
|
+
links: [{ context: sessionSpan.spanContext() }]
|
|
178
|
+
},
|
|
179
|
+
ctx
|
|
180
|
+
);
|
|
181
|
+
return { span, ctx };
|
|
182
|
+
}
|
|
183
|
+
var tracer = import_api.trace.getTracer("river", version);
|
|
184
|
+
|
|
185
|
+
// transport/session.ts
|
|
186
|
+
var import_api2 = require("@opentelemetry/api");
|
|
145
187
|
var nanoid2 = (0, import_nanoid2.customAlphabet)("1234567890abcdefghijklmnopqrstuvxyz", 6);
|
|
146
188
|
var unsafeId = () => nanoid2();
|
|
147
189
|
var Connection = class {
|
|
148
|
-
|
|
190
|
+
id;
|
|
191
|
+
telemetry;
|
|
149
192
|
constructor() {
|
|
150
|
-
this.
|
|
193
|
+
this.id = `conn-${nanoid2(12)}`;
|
|
151
194
|
}
|
|
152
195
|
};
|
|
153
196
|
var Session = class {
|
|
154
197
|
codec;
|
|
155
198
|
options;
|
|
199
|
+
telemetry;
|
|
156
200
|
/**
|
|
157
201
|
* The buffer of messages that have been sent but not yet acknowledged.
|
|
158
202
|
*/
|
|
@@ -199,7 +243,7 @@ var Session = class {
|
|
|
199
243
|
* The interval for sending heartbeats.
|
|
200
244
|
*/
|
|
201
245
|
heartbeat;
|
|
202
|
-
constructor(conn, from, to, options) {
|
|
246
|
+
constructor(conn, from, to, options, propagationCtx) {
|
|
203
247
|
this.id = `session-${nanoid2(12)}`;
|
|
204
248
|
this.options = options;
|
|
205
249
|
this.from = from;
|
|
@@ -211,13 +255,14 @@ var Session = class {
|
|
|
211
255
|
() => this.sendHeartbeat(),
|
|
212
256
|
options.heartbeatIntervalMs
|
|
213
257
|
);
|
|
258
|
+
this.telemetry = createSessionTelemetryInfo(this, propagationCtx);
|
|
214
259
|
}
|
|
215
260
|
get loggingMetadata() {
|
|
216
261
|
return {
|
|
217
262
|
clientId: this.from,
|
|
218
263
|
connectedTo: this.to,
|
|
219
264
|
sessionId: this.id,
|
|
220
|
-
connId: this.connection?.
|
|
265
|
+
connId: this.connection?.id
|
|
221
266
|
};
|
|
222
267
|
}
|
|
223
268
|
/**
|
|
@@ -262,6 +307,7 @@ var Session = class {
|
|
|
262
307
|
`closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
|
|
263
308
|
this.loggingMetadata
|
|
264
309
|
);
|
|
310
|
+
this.telemetry.span.addEvent("closing connection due to inactivity");
|
|
265
311
|
this.closeStaleConnection();
|
|
266
312
|
}
|
|
267
313
|
return;
|
|
@@ -283,21 +329,25 @@ var Session = class {
|
|
|
283
329
|
sendBufferedMessages(conn) {
|
|
284
330
|
log?.info(`resending ${this.sendBuffer.length} buffered messages`, {
|
|
285
331
|
...this.loggingMetadata,
|
|
286
|
-
connId: conn.
|
|
332
|
+
connId: conn.id
|
|
287
333
|
});
|
|
288
334
|
for (const msg of this.sendBuffer) {
|
|
289
335
|
log?.debug(`resending msg`, {
|
|
290
336
|
...this.loggingMetadata,
|
|
291
337
|
fullTransportMessage: msg,
|
|
292
|
-
connId: conn.
|
|
338
|
+
connId: conn.id
|
|
293
339
|
});
|
|
294
340
|
const ok = conn.send(this.codec.toBuffer(msg));
|
|
295
341
|
if (!ok) {
|
|
296
342
|
const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;
|
|
343
|
+
conn.telemetry?.span.setStatus({
|
|
344
|
+
code: import_api2.SpanStatusCode.ERROR,
|
|
345
|
+
message: errMsg
|
|
346
|
+
});
|
|
297
347
|
log?.error(errMsg, {
|
|
298
348
|
...this.loggingMetadata,
|
|
299
349
|
fullTransportMessage: msg,
|
|
300
|
-
connId: conn.
|
|
350
|
+
connId: conn.id,
|
|
301
351
|
tags: ["invariant-violation"]
|
|
302
352
|
});
|
|
303
353
|
conn.close();
|
|
@@ -380,11 +430,6 @@ var Session = class {
|
|
|
380
430
|
}
|
|
381
431
|
};
|
|
382
432
|
|
|
383
|
-
// tracing/index.ts
|
|
384
|
-
var import_api = require("@opentelemetry/api");
|
|
385
|
-
var tracer = import_api.trace.getTracer("river");
|
|
386
|
-
var tracing_default = tracer;
|
|
387
|
-
|
|
388
433
|
// util/stringify.ts
|
|
389
434
|
function coerceErrorString(err) {
|
|
390
435
|
if (err instanceof Error) {
|
|
@@ -446,6 +491,7 @@ var NaiveJsonCodec = {
|
|
|
446
491
|
};
|
|
447
492
|
|
|
448
493
|
// transport/transport.ts
|
|
494
|
+
var import_api3 = require("@opentelemetry/api");
|
|
449
495
|
var defaultTransportOptions = {
|
|
450
496
|
heartbeatIntervalMs: 1e3,
|
|
451
497
|
heartbeatsUntilDead: 2,
|
|
@@ -524,17 +570,22 @@ var Transport = class {
|
|
|
524
570
|
status: "connect",
|
|
525
571
|
conn
|
|
526
572
|
});
|
|
573
|
+
conn.telemetry = createConnectionTelemetryInfo(
|
|
574
|
+
conn,
|
|
575
|
+
session.telemetry.span
|
|
576
|
+
);
|
|
527
577
|
if (isReconnect) {
|
|
528
578
|
session.replaceWithNewConnection(conn);
|
|
529
579
|
log?.info(`reconnected to ${connectedTo}`, session.loggingMetadata);
|
|
530
580
|
}
|
|
531
581
|
}
|
|
532
|
-
createSession(to, conn) {
|
|
582
|
+
createSession(to, conn, propagationCtx) {
|
|
533
583
|
const session = new Session(
|
|
534
584
|
conn,
|
|
535
585
|
this.clientId,
|
|
536
586
|
to,
|
|
537
|
-
this.options
|
|
587
|
+
this.options,
|
|
588
|
+
propagationCtx
|
|
538
589
|
);
|
|
539
590
|
this.sessions.set(session.to, session);
|
|
540
591
|
this.eventDispatcher.dispatchEvent("sessionStatus", {
|
|
@@ -543,11 +594,11 @@ var Transport = class {
|
|
|
543
594
|
});
|
|
544
595
|
return session;
|
|
545
596
|
}
|
|
546
|
-
getOrCreateSession(to, conn, sessionId) {
|
|
597
|
+
getOrCreateSession(to, conn, sessionId, propagationCtx) {
|
|
547
598
|
let session = this.sessions.get(to);
|
|
548
599
|
let isReconnect = session !== void 0;
|
|
549
600
|
if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
|
|
550
|
-
log?.
|
|
601
|
+
log?.info(
|
|
551
602
|
`session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
|
|
552
603
|
session.loggingMetadata
|
|
553
604
|
);
|
|
@@ -556,7 +607,7 @@ var Transport = class {
|
|
|
556
607
|
session = void 0;
|
|
557
608
|
}
|
|
558
609
|
if (!session) {
|
|
559
|
-
session = this.createSession(to, conn);
|
|
610
|
+
session = this.createSession(to, conn, propagationCtx);
|
|
560
611
|
log?.info(
|
|
561
612
|
`no session for ${to}, created a new one`,
|
|
562
613
|
session.loggingMetadata
|
|
@@ -569,6 +620,7 @@ var Transport = class {
|
|
|
569
620
|
}
|
|
570
621
|
deleteSession(session) {
|
|
571
622
|
session.close();
|
|
623
|
+
session.telemetry.span.end();
|
|
572
624
|
this.sessions.delete(session.to);
|
|
573
625
|
log?.info(
|
|
574
626
|
`session ${session.id} disconnect from ${session.to}`,
|
|
@@ -585,12 +637,16 @@ var Transport = class {
|
|
|
585
637
|
* @param connectedTo The peer we are connected to.
|
|
586
638
|
*/
|
|
587
639
|
onDisconnect(conn, session) {
|
|
640
|
+
conn.telemetry?.span.end();
|
|
588
641
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
589
642
|
status: "disconnect",
|
|
590
643
|
conn
|
|
591
644
|
});
|
|
592
645
|
session.connection = void 0;
|
|
593
|
-
session.beginGrace(() =>
|
|
646
|
+
session.beginGrace(() => {
|
|
647
|
+
session.telemetry.span.addEvent("session grace period expired");
|
|
648
|
+
this.deleteSession(session);
|
|
649
|
+
});
|
|
594
650
|
}
|
|
595
651
|
/**
|
|
596
652
|
* Parses a message from a Uint8Array into a {@link OpaqueTransportMessage}.
|
|
@@ -650,6 +706,10 @@ var Transport = class {
|
|
|
650
706
|
tags: ["invariant-violation"]
|
|
651
707
|
});
|
|
652
708
|
this.protocolError(ProtocolError.MessageOrderingViolated, errMsg);
|
|
709
|
+
session.telemetry.span.setStatus({
|
|
710
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
711
|
+
message: "message order violated"
|
|
712
|
+
});
|
|
653
713
|
session.close();
|
|
654
714
|
}
|
|
655
715
|
return;
|
|
@@ -760,268 +820,233 @@ var ServerTransport = class extends Transport {
|
|
|
760
820
|
});
|
|
761
821
|
}
|
|
762
822
|
handleConnection(conn) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
(
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
823
|
+
if (this.state !== "open")
|
|
824
|
+
return;
|
|
825
|
+
log?.info(`new incoming connection`, {
|
|
826
|
+
clientId: this.clientId,
|
|
827
|
+
connId: conn.id
|
|
828
|
+
});
|
|
829
|
+
let session = void 0;
|
|
830
|
+
const client = () => session?.to ?? "unknown";
|
|
831
|
+
const handshakeTimeout = setTimeout(() => {
|
|
832
|
+
if (!session) {
|
|
833
|
+
log?.warn(
|
|
834
|
+
`connection to ${client()} timed out waiting for handshake, closing`,
|
|
835
|
+
{
|
|
836
|
+
clientId: this.clientId,
|
|
837
|
+
connectedTo: client(),
|
|
838
|
+
connId: conn.id
|
|
839
|
+
}
|
|
840
|
+
);
|
|
841
|
+
conn.telemetry?.span.setStatus({
|
|
842
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
843
|
+
message: "handshake timeout"
|
|
778
844
|
});
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
845
|
+
conn.close();
|
|
846
|
+
}
|
|
847
|
+
}, this.options.sessionDisconnectGraceMs);
|
|
848
|
+
const buffer = [];
|
|
849
|
+
let receivedHandshakeMessage = false;
|
|
850
|
+
const handshakeHandler = (data) => {
|
|
851
|
+
if (receivedHandshakeMessage) {
|
|
852
|
+
buffer.push(data);
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
receivedHandshakeMessage = true;
|
|
856
|
+
clearTimeout(handshakeTimeout);
|
|
857
|
+
void this.receiveHandshakeRequestMessage(data, conn).then(
|
|
858
|
+
(maybeSession) => {
|
|
859
|
+
if (!maybeSession) {
|
|
793
860
|
conn.close();
|
|
794
|
-
}
|
|
795
|
-
}, this.options.sessionDisconnectGraceMs);
|
|
796
|
-
const buffer = [];
|
|
797
|
-
let receivedHandshakeMessage = false;
|
|
798
|
-
const handshakeHandler = (data) => {
|
|
799
|
-
if (receivedHandshakeMessage) {
|
|
800
|
-
buffer.push(data);
|
|
801
861
|
return;
|
|
802
862
|
}
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
(
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
span.end();
|
|
810
|
-
conn.close();
|
|
811
|
-
return;
|
|
812
|
-
}
|
|
813
|
-
session = maybeSession;
|
|
814
|
-
const dataHandler = (data2) => {
|
|
815
|
-
const parsed = this.parseMsg(data2);
|
|
816
|
-
if (!parsed) {
|
|
817
|
-
conn.close();
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
this.handleMsg(parsed);
|
|
821
|
-
};
|
|
822
|
-
conn.removeDataListener(handshakeHandler);
|
|
823
|
-
conn.addDataListener(dataHandler);
|
|
824
|
-
for (const data2 of buffer) {
|
|
825
|
-
dataHandler(data2);
|
|
826
|
-
}
|
|
827
|
-
buffer.length = 0;
|
|
863
|
+
session = maybeSession;
|
|
864
|
+
const dataHandler = (data2) => {
|
|
865
|
+
const parsed = this.parseMsg(data2);
|
|
866
|
+
if (!parsed) {
|
|
867
|
+
conn.close();
|
|
868
|
+
return;
|
|
828
869
|
}
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
if (session) {
|
|
834
|
-
log?.info(`connection to ${client()} disconnected`, {
|
|
835
|
-
clientId: this.clientId,
|
|
836
|
-
connId: conn.debugId
|
|
837
|
-
});
|
|
838
|
-
this.onDisconnect(conn, session);
|
|
839
|
-
}
|
|
840
|
-
span.setStatus({ code: import_api2.SpanStatusCode.OK });
|
|
841
|
-
span.end();
|
|
842
|
-
});
|
|
843
|
-
conn.addErrorListener((err) => {
|
|
844
|
-
if (session) {
|
|
845
|
-
log?.warn(
|
|
846
|
-
`connection to ${client()} got an error: ${coerceErrorString(
|
|
847
|
-
err
|
|
848
|
-
)}`,
|
|
849
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
850
|
-
);
|
|
870
|
+
this.handleMsg(parsed);
|
|
871
|
+
};
|
|
872
|
+
for (const data2 of buffer) {
|
|
873
|
+
dataHandler(data2);
|
|
851
874
|
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
875
|
+
conn.removeDataListener(handshakeHandler);
|
|
876
|
+
conn.addDataListener(dataHandler);
|
|
877
|
+
buffer.length = 0;
|
|
878
|
+
}
|
|
879
|
+
);
|
|
880
|
+
};
|
|
881
|
+
conn.addDataListener(handshakeHandler);
|
|
882
|
+
conn.addCloseListener(() => {
|
|
883
|
+
if (!session)
|
|
884
|
+
return;
|
|
885
|
+
log?.info(`connection to ${client()} disconnected`, {
|
|
886
|
+
clientId: this.clientId,
|
|
887
|
+
connId: conn.id
|
|
888
|
+
});
|
|
889
|
+
this.onDisconnect(conn, session);
|
|
890
|
+
});
|
|
891
|
+
conn.addErrorListener((err) => {
|
|
892
|
+
conn.telemetry?.span.setStatus({
|
|
893
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
894
|
+
message: "connection error"
|
|
895
|
+
});
|
|
896
|
+
if (!session)
|
|
897
|
+
return;
|
|
898
|
+
log?.warn(
|
|
899
|
+
`connection to ${client()} got an error: ${coerceErrorString(err)}`,
|
|
900
|
+
{ clientId: this.clientId, connId: conn.id }
|
|
901
|
+
);
|
|
902
|
+
});
|
|
857
903
|
}
|
|
858
904
|
async receiveHandshakeRequestMessage(data, conn) {
|
|
859
905
|
const parsed = this.parseMsg(data);
|
|
860
906
|
if (!parsed) {
|
|
907
|
+
conn.telemetry?.span.setStatus({
|
|
908
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
909
|
+
message: "non-transport message"
|
|
910
|
+
});
|
|
861
911
|
this.protocolError(
|
|
862
912
|
ProtocolError.HandshakeFailed,
|
|
863
913
|
"received non-transport message"
|
|
864
914
|
);
|
|
865
915
|
return false;
|
|
866
916
|
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
917
|
+
if (!import_value.Value.Check(ControlMessageHandshakeRequestSchema, parsed.payload)) {
|
|
918
|
+
conn.telemetry?.span.setStatus({
|
|
919
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
920
|
+
message: "invalid handshake request"
|
|
921
|
+
});
|
|
922
|
+
const reason = "received invalid handshake msg";
|
|
923
|
+
const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
|
|
924
|
+
ok: false,
|
|
925
|
+
reason
|
|
926
|
+
});
|
|
927
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
928
|
+
const logData = { ...parsed.payload ?? {}, metadata: "redacted" };
|
|
929
|
+
log?.warn(reason, {
|
|
930
|
+
clientId: this.clientId,
|
|
931
|
+
connId: conn.id,
|
|
932
|
+
partialTransportMessage: { ...parsed, payload: logData }
|
|
933
|
+
});
|
|
934
|
+
this.protocolError(
|
|
935
|
+
ProtocolError.HandshakeFailed,
|
|
936
|
+
"invalid handshake request"
|
|
937
|
+
);
|
|
938
|
+
return false;
|
|
870
939
|
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
{
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
const gotVersion = parsed.payload.protocolVersion;
|
|
910
|
-
if (gotVersion !== PROTOCOL_VERSION) {
|
|
911
|
-
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
912
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
913
|
-
this.clientId,
|
|
914
|
-
parsed.from,
|
|
915
|
-
{
|
|
916
|
-
ok: false,
|
|
917
|
-
reason
|
|
918
|
-
}
|
|
919
|
-
);
|
|
920
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
921
|
-
log?.warn(
|
|
922
|
-
`received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`,
|
|
923
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
924
|
-
);
|
|
925
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
926
|
-
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
927
|
-
span.end();
|
|
928
|
-
return false;
|
|
929
|
-
}
|
|
930
|
-
const { session, isReconnect } = this.getOrCreateSession(
|
|
940
|
+
const gotVersion = parsed.payload.protocolVersion;
|
|
941
|
+
if (gotVersion !== PROTOCOL_VERSION) {
|
|
942
|
+
conn.telemetry?.span.setStatus({
|
|
943
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
944
|
+
message: "incorrect protocol version"
|
|
945
|
+
});
|
|
946
|
+
const reason = `incorrect version (got: ${gotVersion} wanted ${PROTOCOL_VERSION})`;
|
|
947
|
+
const responseMsg2 = handshakeResponseMessage(this.clientId, parsed.from, {
|
|
948
|
+
ok: false,
|
|
949
|
+
reason
|
|
950
|
+
});
|
|
951
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
952
|
+
log?.warn(
|
|
953
|
+
`received handshake msg with incompatible protocol version (got: ${gotVersion}, expected: ${PROTOCOL_VERSION})`,
|
|
954
|
+
{ clientId: this.clientId, connId: conn.id }
|
|
955
|
+
);
|
|
956
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
957
|
+
return false;
|
|
958
|
+
}
|
|
959
|
+
const { session, isReconnect } = this.getOrCreateSession(
|
|
960
|
+
parsed.from,
|
|
961
|
+
conn,
|
|
962
|
+
parsed.payload.sessionId,
|
|
963
|
+
parsed.tracing
|
|
964
|
+
);
|
|
965
|
+
let handshakeMetadata;
|
|
966
|
+
if (this.options.handshake) {
|
|
967
|
+
if (!import_value.Value.Check(
|
|
968
|
+
this.options.handshake.requestSchema,
|
|
969
|
+
parsed.payload.metadata
|
|
970
|
+
)) {
|
|
971
|
+
conn.telemetry?.span.setStatus({
|
|
972
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
973
|
+
message: "malformed handshake meta"
|
|
974
|
+
});
|
|
975
|
+
const reason = "received malformed handshake metadata";
|
|
976
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
977
|
+
this.clientId,
|
|
931
978
|
parsed.from,
|
|
932
|
-
|
|
933
|
-
parsed.payload.sessionId
|
|
979
|
+
{ ok: false, reason }
|
|
934
980
|
);
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
return false;
|
|
960
|
-
}
|
|
961
|
-
const parsedMetadata = await this.options.handshake.parse(
|
|
962
|
-
parsed.payload.metadata,
|
|
963
|
-
session,
|
|
964
|
-
isReconnect
|
|
965
|
-
);
|
|
966
|
-
if (parsedMetadata === false) {
|
|
967
|
-
const reason = "rejected by server";
|
|
968
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
969
|
-
this.clientId,
|
|
970
|
-
parsed.from,
|
|
971
|
-
{ ok: false, reason }
|
|
972
|
-
);
|
|
973
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
974
|
-
log?.warn(`rejected handshake from ${parsed.from}`, {
|
|
975
|
-
clientId: this.clientId,
|
|
976
|
-
connId: conn.debugId
|
|
977
|
-
});
|
|
978
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
979
|
-
this.deleteSession(session);
|
|
980
|
-
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
981
|
-
span.end();
|
|
982
|
-
return false;
|
|
983
|
-
}
|
|
984
|
-
if (!import_value.Value.Check(this.options.handshake.parsedSchema, parsedMetadata)) {
|
|
985
|
-
const reason = "failed to parse handshake metadata";
|
|
986
|
-
const responseMsg2 = handshakeResponseMessage(
|
|
987
|
-
this.clientId,
|
|
988
|
-
parsed.from,
|
|
989
|
-
{ ok: false, reason }
|
|
990
|
-
);
|
|
991
|
-
conn.send(this.codec.toBuffer(responseMsg2));
|
|
992
|
-
log?.error(`failed to parse handshake metadata`, {
|
|
993
|
-
clientId: this.clientId,
|
|
994
|
-
connId: conn.debugId,
|
|
995
|
-
tags: ["invariant-violation"]
|
|
996
|
-
});
|
|
997
|
-
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
998
|
-
this.deleteSession(session);
|
|
999
|
-
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
1000
|
-
span.end();
|
|
1001
|
-
return false;
|
|
1002
|
-
}
|
|
1003
|
-
handshakeMetadata = parsedMetadata;
|
|
1004
|
-
}
|
|
1005
|
-
handshakeMetadata ??= {};
|
|
1006
|
-
session.metadata = handshakeMetadata;
|
|
1007
|
-
log?.debug(
|
|
1008
|
-
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
1009
|
-
{ clientId: this.clientId, connId: conn.debugId }
|
|
981
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
982
|
+
log?.warn(`received malformed handshake metadata from ${parsed.from}`, {
|
|
983
|
+
clientId: this.clientId,
|
|
984
|
+
connId: conn.id
|
|
985
|
+
});
|
|
986
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
987
|
+
this.deleteSession(session);
|
|
988
|
+
return false;
|
|
989
|
+
}
|
|
990
|
+
const parsedMetadata = await this.options.handshake.parse(
|
|
991
|
+
parsed.payload.metadata,
|
|
992
|
+
session,
|
|
993
|
+
isReconnect
|
|
994
|
+
);
|
|
995
|
+
if (parsedMetadata === false) {
|
|
996
|
+
conn.telemetry?.span.setStatus({
|
|
997
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
998
|
+
message: "rejected by handshake handler"
|
|
999
|
+
});
|
|
1000
|
+
const reason = "rejected by handshake handler";
|
|
1001
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1002
|
+
this.clientId,
|
|
1003
|
+
parsed.from,
|
|
1004
|
+
{ ok: false, reason }
|
|
1010
1005
|
);
|
|
1011
|
-
|
|
1006
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1007
|
+
log?.warn(`rejected handshake from ${parsed.from}`, {
|
|
1008
|
+
clientId: this.clientId,
|
|
1009
|
+
connId: conn.id
|
|
1010
|
+
});
|
|
1011
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1012
|
+
this.deleteSession(session);
|
|
1013
|
+
return false;
|
|
1014
|
+
}
|
|
1015
|
+
if (!import_value.Value.Check(this.options.handshake.parsedSchema, parsedMetadata)) {
|
|
1016
|
+
conn.telemetry?.span.setStatus({
|
|
1017
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
1018
|
+
message: "malformed handshake meta"
|
|
1019
|
+
});
|
|
1020
|
+
const reason = "failed to parse handshake metadata";
|
|
1021
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1012
1022
|
this.clientId,
|
|
1013
1023
|
parsed.from,
|
|
1014
|
-
{
|
|
1015
|
-
ok: true,
|
|
1016
|
-
sessionId: session.id
|
|
1017
|
-
}
|
|
1024
|
+
{ ok: false, reason }
|
|
1018
1025
|
);
|
|
1019
|
-
conn.send(this.codec.toBuffer(
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1026
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1027
|
+
log?.error(`failed to parse handshake metadata`, {
|
|
1028
|
+
clientId: this.clientId,
|
|
1029
|
+
connId: conn.id
|
|
1030
|
+
});
|
|
1031
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1032
|
+
this.deleteSession(session);
|
|
1033
|
+
return false;
|
|
1023
1034
|
}
|
|
1035
|
+
handshakeMetadata = parsedMetadata;
|
|
1036
|
+
}
|
|
1037
|
+
handshakeMetadata ??= {};
|
|
1038
|
+
session.metadata = handshakeMetadata;
|
|
1039
|
+
log?.debug(
|
|
1040
|
+
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
1041
|
+
{ clientId: this.clientId, connId: conn.id }
|
|
1024
1042
|
);
|
|
1043
|
+
const responseMsg = handshakeResponseMessage(this.clientId, parsed.from, {
|
|
1044
|
+
ok: true,
|
|
1045
|
+
sessionId: session.id
|
|
1046
|
+
});
|
|
1047
|
+
conn.send(this.codec.toBuffer(responseMsg));
|
|
1048
|
+
this.onConnect(conn, parsed.from, session, isReconnect);
|
|
1049
|
+
return session;
|
|
1025
1050
|
}
|
|
1026
1051
|
};
|
|
1027
1052
|
|