@replit/river 0.18.5 → 0.19.2
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/dist/{chunk-VH3NGOXQ.js → chunk-D5PVGZPQ.js} +5 -3
- package/dist/{chunk-K7CUSLWL.js → chunk-JH275HID.js} +1 -1
- package/dist/{chunk-WER2DWCP.js → chunk-NBE3D667.js} +0 -4
- package/dist/{chunk-6Q3MSICL.js → chunk-SR4DBLJ6.js} +11 -3
- package/dist/{chunk-UABIFWM7.js → chunk-YFPVQTWL.js} +220 -105
- package/dist/{chunk-PUX3U2SZ.js → chunk-ZWPEZS27.js} +1 -1
- package/dist/{connection-893bd769.d.ts → connection-aa0ea000.d.ts} +1 -1
- package/dist/{connection-89918b74.d.ts → connection-cfec12e6.d.ts} +1 -1
- package/dist/index-e2513701.d.ts +342 -0
- package/dist/logging/index.cjs +0 -4
- package/dist/logging/index.d.cts +2 -1
- package/dist/logging/index.d.ts +2 -1
- package/dist/logging/index.js +1 -1
- package/dist/router/index.cjs +11 -2
- package/dist/router/index.d.cts +7 -383
- package/dist/router/index.d.ts +7 -383
- package/dist/router/index.js +3 -3
- package/dist/services-4bba42d8.d.ts +736 -0
- package/dist/services-5fc5712d.d.ts +736 -0
- package/dist/transport/impls/uds/client.cjs +80 -53
- package/dist/transport/impls/uds/client.d.cts +5 -5
- package/dist/transport/impls/uds/client.d.ts +5 -5
- package/dist/transport/impls/uds/client.js +4 -4
- package/dist/transport/impls/uds/server.cjs +151 -62
- package/dist/transport/impls/uds/server.d.cts +4 -4
- package/dist/transport/impls/uds/server.d.ts +4 -4
- package/dist/transport/impls/uds/server.js +4 -4
- package/dist/transport/impls/ws/client.cjs +80 -53
- package/dist/transport/impls/ws/client.d.cts +3 -3
- package/dist/transport/impls/ws/client.d.ts +3 -3
- package/dist/transport/impls/ws/client.js +4 -4
- package/dist/transport/impls/ws/server.cjs +151 -62
- package/dist/transport/impls/ws/server.d.cts +4 -4
- package/dist/transport/impls/ws/server.d.ts +4 -4
- package/dist/transport/impls/ws/server.js +4 -4
- package/dist/transport/index.cjs +188 -71
- package/dist/transport/index.d.cts +295 -3
- package/dist/transport/index.d.ts +295 -3
- package/dist/transport/index.js +3 -4
- package/dist/util/testHelpers.cjs +410 -401
- package/dist/util/testHelpers.d.cts +3 -3
- package/dist/util/testHelpers.d.ts +3 -3
- package/dist/util/testHelpers.js +4 -5
- package/package.json +1 -1
- package/dist/chunk-RPIDSIQG.js +0 -0
- package/dist/index-46ed19d8.d.ts +0 -111
- package/dist/index-d412ca83.d.ts +0 -420
- package/dist/procedures-bfffcb0b.d.ts +0 -324
|
@@ -23,7 +23,8 @@ var PROTOCOL_VERSION = "v1.1";
|
|
|
23
23
|
var ControlMessageHandshakeRequestSchema = Type.Object({
|
|
24
24
|
type: Type.Literal("HANDSHAKE_REQ"),
|
|
25
25
|
protocolVersion: Type.String(),
|
|
26
|
-
sessionId: Type.String()
|
|
26
|
+
sessionId: Type.String(),
|
|
27
|
+
metadata: Type.Optional(Type.Unknown())
|
|
27
28
|
});
|
|
28
29
|
var ControlMessageHandshakeResponseSchema = Type.Object({
|
|
29
30
|
type: Type.Literal("HANDSHAKE_RESP"),
|
|
@@ -47,7 +48,7 @@ var ControlMessagePayloadSchema = Type.Union([
|
|
|
47
48
|
var OpaqueTransportMessageSchema = TransportMessageSchema(
|
|
48
49
|
Type.Unknown()
|
|
49
50
|
);
|
|
50
|
-
function handshakeRequestMessage(from, to, sessionId) {
|
|
51
|
+
function handshakeRequestMessage(from, to, sessionId, metadata) {
|
|
51
52
|
return {
|
|
52
53
|
id: nanoid(),
|
|
53
54
|
from,
|
|
@@ -59,7 +60,8 @@ function handshakeRequestMessage(from, to, sessionId) {
|
|
|
59
60
|
payload: {
|
|
60
61
|
type: "HANDSHAKE_REQ",
|
|
61
62
|
protocolVersion: PROTOCOL_VERSION,
|
|
62
|
-
sessionId
|
|
63
|
+
sessionId,
|
|
64
|
+
metadata
|
|
63
65
|
}
|
|
64
66
|
};
|
|
65
67
|
}
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
coerceErrorString,
|
|
4
4
|
isStreamClose,
|
|
5
5
|
isStreamOpen
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-D5PVGZPQ.js";
|
|
7
7
|
import {
|
|
8
8
|
log
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-NBE3D667.js";
|
|
10
10
|
|
|
11
11
|
// router/services.ts
|
|
12
12
|
import { Type } from "@sinclair/typebox";
|
|
@@ -1065,6 +1065,13 @@ var RiverServer = class {
|
|
|
1065
1065
|
})
|
|
1066
1066
|
);
|
|
1067
1067
|
};
|
|
1068
|
+
if (session.metadata === void 0) {
|
|
1069
|
+
log?.error(
|
|
1070
|
+
`(invariant violation) session doesn't have handshake metadata`,
|
|
1071
|
+
session.loggingMetadata
|
|
1072
|
+
);
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1068
1075
|
let inputHandler;
|
|
1069
1076
|
const procHasInitMessage = "init" in procedure;
|
|
1070
1077
|
const serviceContextWithTransportInfo = {
|
|
@@ -1072,6 +1079,7 @@ var RiverServer = class {
|
|
|
1072
1079
|
to: message.to,
|
|
1073
1080
|
from: message.from,
|
|
1074
1081
|
streamId: message.streamId,
|
|
1082
|
+
// we've already validated that the session has handshake metadata
|
|
1075
1083
|
session
|
|
1076
1084
|
};
|
|
1077
1085
|
switch (procedure.type) {
|
|
@@ -1247,7 +1255,7 @@ function createServer(transport, services, extendedContext) {
|
|
|
1247
1255
|
}
|
|
1248
1256
|
|
|
1249
1257
|
// package.json
|
|
1250
|
-
var version = "0.
|
|
1258
|
+
var version = "0.19.2";
|
|
1251
1259
|
|
|
1252
1260
|
export {
|
|
1253
1261
|
serializeSchema,
|
|
@@ -7,48 +7,14 @@ import {
|
|
|
7
7
|
handshakeRequestMessage,
|
|
8
8
|
handshakeResponseMessage,
|
|
9
9
|
isAck
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-D5PVGZPQ.js";
|
|
11
11
|
import {
|
|
12
12
|
log
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NBE3D667.js";
|
|
14
14
|
import {
|
|
15
15
|
NaiveJsonCodec
|
|
16
16
|
} from "./chunk-GZ7HCLLM.js";
|
|
17
17
|
|
|
18
|
-
// transport/events.ts
|
|
19
|
-
var ProtocolError = {
|
|
20
|
-
RetriesExceeded: "conn_retry_exceeded",
|
|
21
|
-
HandshakeFailed: "handshake_failed",
|
|
22
|
-
UseAfterDestroy: "use_after_destroy",
|
|
23
|
-
MessageOrderingViolated: "message_ordering_violated"
|
|
24
|
-
};
|
|
25
|
-
var EventDispatcher = class {
|
|
26
|
-
eventListeners = {};
|
|
27
|
-
numberOfListeners(eventType) {
|
|
28
|
-
return this.eventListeners[eventType]?.size ?? 0;
|
|
29
|
-
}
|
|
30
|
-
addEventListener(eventType, handler) {
|
|
31
|
-
if (!this.eventListeners[eventType]) {
|
|
32
|
-
this.eventListeners[eventType] = /* @__PURE__ */ new Set();
|
|
33
|
-
}
|
|
34
|
-
this.eventListeners[eventType]?.add(handler);
|
|
35
|
-
}
|
|
36
|
-
removeEventListener(eventType, handler) {
|
|
37
|
-
const handlers = this.eventListeners[eventType];
|
|
38
|
-
if (handlers) {
|
|
39
|
-
this.eventListeners[eventType]?.delete(handler);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
dispatchEvent(eventType, event) {
|
|
43
|
-
const handlers = this.eventListeners[eventType];
|
|
44
|
-
if (handlers) {
|
|
45
|
-
for (const handler of handlers) {
|
|
46
|
-
handler(event);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
18
|
// transport/session.ts
|
|
53
19
|
import { customAlphabet } from "nanoid";
|
|
54
20
|
var nanoid = customAlphabet("1234567890abcdefghijklmnopqrstuvxyz", 6);
|
|
@@ -81,6 +47,12 @@ var Session = class {
|
|
|
81
47
|
* for this session.
|
|
82
48
|
*/
|
|
83
49
|
advertisedSessionId;
|
|
50
|
+
/**
|
|
51
|
+
* The metadata for this session, as parsed from the handshake.
|
|
52
|
+
*
|
|
53
|
+
* Will only ever be populated on the server side.
|
|
54
|
+
*/
|
|
55
|
+
metadata;
|
|
84
56
|
/**
|
|
85
57
|
* Number of messages we've sent along this session (excluding handshake and acks)
|
|
86
58
|
*/
|
|
@@ -183,27 +155,24 @@ var Session = class {
|
|
|
183
155
|
this.seq = 0;
|
|
184
156
|
this.ack = 0;
|
|
185
157
|
}
|
|
186
|
-
sendBufferedMessages() {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
log?.info(
|
|
193
|
-
`resending ${this.sendBuffer.length} buffered messages`,
|
|
194
|
-
this.loggingMetadata
|
|
195
|
-
);
|
|
158
|
+
sendBufferedMessages(conn) {
|
|
159
|
+
log?.info(`resending ${this.sendBuffer.length} buffered messages`, {
|
|
160
|
+
...this.loggingMetadata,
|
|
161
|
+
connId: conn.debugId
|
|
162
|
+
});
|
|
196
163
|
for (const msg of this.sendBuffer) {
|
|
197
164
|
log?.debug(`resending msg`, {
|
|
198
165
|
...this.loggingMetadata,
|
|
199
|
-
fullTransportMessage: msg
|
|
166
|
+
fullTransportMessage: msg,
|
|
167
|
+
connId: conn.debugId
|
|
200
168
|
});
|
|
201
|
-
const ok =
|
|
169
|
+
const ok = conn.send(this.codec.toBuffer(msg));
|
|
202
170
|
if (!ok) {
|
|
203
|
-
const errMsg = `failed to send buffered message to ${this.to} (
|
|
171
|
+
const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;
|
|
204
172
|
log?.error(errMsg, {
|
|
205
173
|
...this.loggingMetadata,
|
|
206
|
-
fullTransportMessage: msg
|
|
174
|
+
fullTransportMessage: msg,
|
|
175
|
+
connId: conn.debugId
|
|
207
176
|
});
|
|
208
177
|
throw new Error(errMsg);
|
|
209
178
|
}
|
|
@@ -234,6 +203,7 @@ var Session = class {
|
|
|
234
203
|
this.closeStaleConnection(newConn);
|
|
235
204
|
this.cancelGrace();
|
|
236
205
|
this.connection = newConn;
|
|
206
|
+
this.sendBufferedMessages(newConn);
|
|
237
207
|
}
|
|
238
208
|
beginGrace(cb) {
|
|
239
209
|
log?.info(
|
|
@@ -283,6 +253,40 @@ var Session = class {
|
|
|
283
253
|
}
|
|
284
254
|
};
|
|
285
255
|
|
|
256
|
+
// transport/events.ts
|
|
257
|
+
var ProtocolError = {
|
|
258
|
+
RetriesExceeded: "conn_retry_exceeded",
|
|
259
|
+
HandshakeFailed: "handshake_failed",
|
|
260
|
+
UseAfterDestroy: "use_after_destroy",
|
|
261
|
+
MessageOrderingViolated: "message_ordering_violated"
|
|
262
|
+
};
|
|
263
|
+
var EventDispatcher = class {
|
|
264
|
+
eventListeners = {};
|
|
265
|
+
numberOfListeners(eventType) {
|
|
266
|
+
return this.eventListeners[eventType]?.size ?? 0;
|
|
267
|
+
}
|
|
268
|
+
addEventListener(eventType, handler) {
|
|
269
|
+
if (!this.eventListeners[eventType]) {
|
|
270
|
+
this.eventListeners[eventType] = /* @__PURE__ */ new Set();
|
|
271
|
+
}
|
|
272
|
+
this.eventListeners[eventType]?.add(handler);
|
|
273
|
+
}
|
|
274
|
+
removeEventListener(eventType, handler) {
|
|
275
|
+
const handlers = this.eventListeners[eventType];
|
|
276
|
+
if (handlers) {
|
|
277
|
+
this.eventListeners[eventType]?.delete(handler);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
dispatchEvent(eventType, event) {
|
|
281
|
+
const handlers = this.eventListeners[eventType];
|
|
282
|
+
if (handlers) {
|
|
283
|
+
for (const handler of handlers) {
|
|
284
|
+
handler(event);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
|
|
286
290
|
// transport/transport.ts
|
|
287
291
|
import { Value } from "@sinclair/typebox/value";
|
|
288
292
|
|
|
@@ -375,6 +379,9 @@ var defaultClientTransportOptions = {
|
|
|
375
379
|
...defaultTransportOptions,
|
|
376
380
|
...defaultConnectionRetryOptions
|
|
377
381
|
};
|
|
382
|
+
var defaultServerTransportOptions = {
|
|
383
|
+
...defaultTransportOptions
|
|
384
|
+
};
|
|
378
385
|
var Transport = class {
|
|
379
386
|
/**
|
|
380
387
|
* A flag indicating whether the transport has been destroyed.
|
|
@@ -428,37 +435,15 @@ var Transport = class {
|
|
|
428
435
|
* and we know the identity of the connected client.
|
|
429
436
|
* @param conn The connection object.
|
|
430
437
|
*/
|
|
431
|
-
onConnect(conn, connectedTo,
|
|
438
|
+
onConnect(conn, connectedTo, session, isReconnect) {
|
|
432
439
|
this.eventDispatcher.dispatchEvent("connectionStatus", {
|
|
433
440
|
status: "connect",
|
|
434
441
|
conn
|
|
435
442
|
});
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
log?.
|
|
439
|
-
`connection from ${connectedTo} is a different session (id: ${advertisedSessionId}, last connected to: ${oldSession.advertisedSessionId}), killing old session and starting a new one`,
|
|
440
|
-
oldSession.loggingMetadata
|
|
441
|
-
);
|
|
442
|
-
this.deleteSession(oldSession);
|
|
443
|
-
oldSession = void 0;
|
|
444
|
-
}
|
|
445
|
-
if (oldSession === void 0) {
|
|
446
|
-
const newSession = this.createSession(connectedTo, conn);
|
|
447
|
-
newSession.advertisedSessionId = advertisedSessionId;
|
|
448
|
-
log?.info(
|
|
449
|
-
`new connection for new session to ${connectedTo}`,
|
|
450
|
-
newSession.loggingMetadata
|
|
451
|
-
);
|
|
452
|
-
return newSession;
|
|
443
|
+
if (isReconnect) {
|
|
444
|
+
session.replaceWithNewConnection(conn);
|
|
445
|
+
log?.info(`reconnected to ${connectedTo}`, session.loggingMetadata);
|
|
453
446
|
}
|
|
454
|
-
oldSession.replaceWithNewConnection(conn);
|
|
455
|
-
oldSession.sendBufferedMessages();
|
|
456
|
-
oldSession.advertisedSessionId = advertisedSessionId;
|
|
457
|
-
log?.info(
|
|
458
|
-
`new connection for existing session to ${connectedTo}`,
|
|
459
|
-
oldSession.loggingMetadata
|
|
460
|
-
);
|
|
461
|
-
return oldSession;
|
|
462
447
|
}
|
|
463
448
|
createSession(to, conn) {
|
|
464
449
|
const session = new Session(
|
|
@@ -474,8 +459,18 @@ var Transport = class {
|
|
|
474
459
|
});
|
|
475
460
|
return session;
|
|
476
461
|
}
|
|
477
|
-
getOrCreateSession(to, conn) {
|
|
462
|
+
getOrCreateSession(to, conn, sessionId) {
|
|
478
463
|
let session = this.sessions.get(to);
|
|
464
|
+
let isReconnect = session !== void 0;
|
|
465
|
+
if (session?.advertisedSessionId !== void 0 && sessionId !== void 0 && session.advertisedSessionId !== sessionId) {
|
|
466
|
+
log?.warn(
|
|
467
|
+
`session for ${to} already exists but has a different session id (expected: ${session.advertisedSessionId}, got: ${sessionId}), creating a new one`,
|
|
468
|
+
session.loggingMetadata
|
|
469
|
+
);
|
|
470
|
+
this.deleteSession(session);
|
|
471
|
+
isReconnect = false;
|
|
472
|
+
session = void 0;
|
|
473
|
+
}
|
|
479
474
|
if (!session) {
|
|
480
475
|
session = this.createSession(to, conn);
|
|
481
476
|
log?.info(
|
|
@@ -483,7 +478,10 @@ var Transport = class {
|
|
|
483
478
|
session.loggingMetadata
|
|
484
479
|
);
|
|
485
480
|
}
|
|
486
|
-
|
|
481
|
+
if (sessionId !== void 0) {
|
|
482
|
+
session.advertisedSessionId = sessionId;
|
|
483
|
+
}
|
|
484
|
+
return { session, isReconnect };
|
|
487
485
|
}
|
|
488
486
|
deleteSession(session) {
|
|
489
487
|
session.close();
|
|
@@ -618,7 +616,7 @@ var Transport = class {
|
|
|
618
616
|
});
|
|
619
617
|
return void 0;
|
|
620
618
|
}
|
|
621
|
-
return this.getOrCreateSession(to).send(msg);
|
|
619
|
+
return this.getOrCreateSession(to).session.send(msg);
|
|
622
620
|
}
|
|
623
621
|
// control helpers
|
|
624
622
|
sendCloseStream(to, streamId) {
|
|
@@ -777,11 +775,12 @@ var ClientTransport = class extends Transport {
|
|
|
777
775
|
connectedTo: parsed.from,
|
|
778
776
|
fullTransportMessage: parsed
|
|
779
777
|
});
|
|
780
|
-
const session = this.
|
|
781
|
-
conn,
|
|
778
|
+
const { session, isReconnect } = this.getOrCreateSession(
|
|
782
779
|
parsed.from,
|
|
780
|
+
conn,
|
|
783
781
|
parsed.payload.status.sessionId
|
|
784
782
|
);
|
|
783
|
+
this.onConnect(conn, parsed.from, session, isReconnect);
|
|
785
784
|
this.retryBudget.startRestoringBudget(parsed.from);
|
|
786
785
|
return session;
|
|
787
786
|
}
|
|
@@ -834,8 +833,13 @@ var ClientTransport = class extends Transport {
|
|
|
834
833
|
conn.close();
|
|
835
834
|
throw new Error("transport state is no longer open");
|
|
836
835
|
}
|
|
837
|
-
this.sendHandshake(to, conn)
|
|
838
|
-
|
|
836
|
+
return this.sendHandshake(to, conn).then((ok) => {
|
|
837
|
+
if (!ok) {
|
|
838
|
+
conn.close();
|
|
839
|
+
throw new Error("failed to send handshake");
|
|
840
|
+
}
|
|
841
|
+
return conn;
|
|
842
|
+
});
|
|
839
843
|
});
|
|
840
844
|
this.inflightConnectionPromises.set(to, reconnectPromise);
|
|
841
845
|
} else {
|
|
@@ -867,14 +871,35 @@ var ClientTransport = class extends Transport {
|
|
|
867
871
|
this.inflightConnectionPromises.delete(session.to);
|
|
868
872
|
super.deleteSession(session);
|
|
869
873
|
}
|
|
870
|
-
sendHandshake(to, conn) {
|
|
871
|
-
|
|
872
|
-
|
|
874
|
+
async sendHandshake(to, conn) {
|
|
875
|
+
let metadata;
|
|
876
|
+
if (this.options.handshake) {
|
|
877
|
+
metadata = await this.options.handshake.get();
|
|
878
|
+
if (!Value.Check(this.options.handshake.schema, metadata)) {
|
|
879
|
+
log?.error(`handshake metadata did not match schema`, {
|
|
880
|
+
clientId: this.clientId,
|
|
881
|
+
connectedTo: to
|
|
882
|
+
});
|
|
883
|
+
this.protocolError(
|
|
884
|
+
ProtocolError.HandshakeFailed,
|
|
885
|
+
"handshake metadata did not match schema"
|
|
886
|
+
);
|
|
887
|
+
return false;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
const { session } = this.getOrCreateSession(to, conn);
|
|
891
|
+
const requestMsg = handshakeRequestMessage(
|
|
892
|
+
this.clientId,
|
|
893
|
+
to,
|
|
894
|
+
session.id,
|
|
895
|
+
metadata
|
|
896
|
+
);
|
|
873
897
|
log?.debug(`sending handshake request to ${to}`, {
|
|
874
898
|
clientId: this.clientId,
|
|
875
899
|
connectedTo: to
|
|
876
900
|
});
|
|
877
901
|
conn.send(this.codec.toBuffer(requestMsg));
|
|
902
|
+
return true;
|
|
878
903
|
}
|
|
879
904
|
close() {
|
|
880
905
|
this.retryBudget.close();
|
|
@@ -882,8 +907,16 @@ var ClientTransport = class extends Transport {
|
|
|
882
907
|
}
|
|
883
908
|
};
|
|
884
909
|
var ServerTransport = class extends Transport {
|
|
910
|
+
/**
|
|
911
|
+
* The options for this transport.
|
|
912
|
+
*/
|
|
913
|
+
options;
|
|
885
914
|
constructor(clientId, providedOptions) {
|
|
886
915
|
super(clientId, providedOptions);
|
|
916
|
+
this.options = {
|
|
917
|
+
...defaultServerTransportOptions,
|
|
918
|
+
...providedOptions
|
|
919
|
+
};
|
|
887
920
|
log?.info(`initiated server transport`, {
|
|
888
921
|
clientId: this.clientId,
|
|
889
922
|
protocolVersion: PROTOCOL_VERSION
|
|
@@ -911,24 +944,38 @@ var ServerTransport = class extends Transport {
|
|
|
911
944
|
conn.close();
|
|
912
945
|
}
|
|
913
946
|
}, this.options.sessionDisconnectGraceMs);
|
|
947
|
+
const buffer = [];
|
|
948
|
+
let receivedHandshakeMessage = false;
|
|
914
949
|
const handshakeHandler = (data) => {
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
conn.close();
|
|
950
|
+
if (receivedHandshakeMessage) {
|
|
951
|
+
buffer.push(data);
|
|
918
952
|
return;
|
|
919
|
-
} else {
|
|
920
|
-
session = maybeSession;
|
|
921
|
-
clearTimeout(handshakeTimeout);
|
|
922
953
|
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
954
|
+
receivedHandshakeMessage = true;
|
|
955
|
+
clearTimeout(handshakeTimeout);
|
|
956
|
+
void this.receiveHandshakeRequestMessage(data, conn).then(
|
|
957
|
+
(maybeSession) => {
|
|
958
|
+
if (!maybeSession) {
|
|
959
|
+
conn.close();
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
session = maybeSession;
|
|
963
|
+
const dataHandler = (data2) => {
|
|
964
|
+
const parsed = this.parseMsg(data2);
|
|
965
|
+
if (!parsed) {
|
|
966
|
+
conn.close();
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
this.handleMsg(parsed);
|
|
970
|
+
};
|
|
971
|
+
conn.removeDataListener(handshakeHandler);
|
|
972
|
+
conn.addDataListener(dataHandler);
|
|
973
|
+
for (const data2 of buffer) {
|
|
974
|
+
dataHandler(data2);
|
|
975
|
+
}
|
|
976
|
+
buffer.length = 0;
|
|
929
977
|
}
|
|
930
|
-
|
|
931
|
-
});
|
|
978
|
+
);
|
|
932
979
|
};
|
|
933
980
|
conn.addDataListener(handshakeHandler);
|
|
934
981
|
conn.addCloseListener(() => {
|
|
@@ -949,7 +996,7 @@ var ServerTransport = class extends Transport {
|
|
|
949
996
|
);
|
|
950
997
|
});
|
|
951
998
|
}
|
|
952
|
-
receiveHandshakeRequestMessage(data, conn) {
|
|
999
|
+
async receiveHandshakeRequestMessage(data, conn) {
|
|
953
1000
|
const parsed = this.parseMsg(data);
|
|
954
1001
|
if (!parsed) {
|
|
955
1002
|
this.protocolError(
|
|
@@ -965,7 +1012,8 @@ var ServerTransport = class extends Transport {
|
|
|
965
1012
|
reason
|
|
966
1013
|
});
|
|
967
1014
|
conn.send(this.codec.toBuffer(responseMsg2));
|
|
968
|
-
|
|
1015
|
+
const logData = typeof parsed.payload === "object" ? { ...parsed, payload: { ...parsed.payload, metadata: "redacted" } } : { ...parsed };
|
|
1016
|
+
log?.warn(`${reason}: ${JSON.stringify(logData)}`, {
|
|
969
1017
|
clientId: this.clientId,
|
|
970
1018
|
connId: conn.debugId
|
|
971
1019
|
});
|
|
@@ -990,7 +1038,73 @@ var ServerTransport = class extends Transport {
|
|
|
990
1038
|
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
991
1039
|
return false;
|
|
992
1040
|
}
|
|
993
|
-
const session = this.getOrCreateSession(
|
|
1041
|
+
const { session, isReconnect } = this.getOrCreateSession(
|
|
1042
|
+
parsed.from,
|
|
1043
|
+
conn,
|
|
1044
|
+
parsed.payload.sessionId
|
|
1045
|
+
);
|
|
1046
|
+
let handshakeMetadata;
|
|
1047
|
+
if (this.options.handshake) {
|
|
1048
|
+
if (!Value.Check(
|
|
1049
|
+
this.options.handshake.requestSchema,
|
|
1050
|
+
parsed.payload.metadata
|
|
1051
|
+
)) {
|
|
1052
|
+
const reason = "received malformed handshake metadata";
|
|
1053
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1054
|
+
this.clientId,
|
|
1055
|
+
parsed.from,
|
|
1056
|
+
{ ok: false, reason }
|
|
1057
|
+
);
|
|
1058
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1059
|
+
log?.warn(`received malformed handshake metadata from ${parsed.from}`, {
|
|
1060
|
+
clientId: this.clientId,
|
|
1061
|
+
connId: conn.debugId
|
|
1062
|
+
});
|
|
1063
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1064
|
+
this.deleteSession(session);
|
|
1065
|
+
return false;
|
|
1066
|
+
}
|
|
1067
|
+
const parsedMetadata = await this.options.handshake.parse(
|
|
1068
|
+
parsed.payload.metadata,
|
|
1069
|
+
session,
|
|
1070
|
+
isReconnect
|
|
1071
|
+
);
|
|
1072
|
+
if (parsedMetadata === false) {
|
|
1073
|
+
const reason = "rejected by server";
|
|
1074
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1075
|
+
this.clientId,
|
|
1076
|
+
parsed.from,
|
|
1077
|
+
{ ok: false, reason }
|
|
1078
|
+
);
|
|
1079
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1080
|
+
log?.warn(`rejected handshake from ${parsed.from}`, {
|
|
1081
|
+
clientId: this.clientId,
|
|
1082
|
+
connId: conn.debugId
|
|
1083
|
+
});
|
|
1084
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1085
|
+
this.deleteSession(session);
|
|
1086
|
+
return false;
|
|
1087
|
+
}
|
|
1088
|
+
if (!Value.Check(this.options.handshake.parsedSchema, parsedMetadata)) {
|
|
1089
|
+
const reason = "failed to parse handshake metadata";
|
|
1090
|
+
const responseMsg2 = handshakeResponseMessage(
|
|
1091
|
+
this.clientId,
|
|
1092
|
+
parsed.from,
|
|
1093
|
+
{ ok: false, reason }
|
|
1094
|
+
);
|
|
1095
|
+
conn.send(this.codec.toBuffer(responseMsg2));
|
|
1096
|
+
log?.error(`failed to parse handshake metadata`, {
|
|
1097
|
+
clientId: this.clientId,
|
|
1098
|
+
connId: conn.debugId
|
|
1099
|
+
});
|
|
1100
|
+
this.protocolError(ProtocolError.HandshakeFailed, reason);
|
|
1101
|
+
this.deleteSession(session);
|
|
1102
|
+
return false;
|
|
1103
|
+
}
|
|
1104
|
+
handshakeMetadata = parsedMetadata;
|
|
1105
|
+
}
|
|
1106
|
+
handshakeMetadata ??= {};
|
|
1107
|
+
session.metadata = handshakeMetadata;
|
|
994
1108
|
log?.debug(
|
|
995
1109
|
`handshake from ${parsed.from} ok, responding with handshake success`,
|
|
996
1110
|
{ clientId: this.clientId, connId: conn.debugId }
|
|
@@ -1000,14 +1114,15 @@ var ServerTransport = class extends Transport {
|
|
|
1000
1114
|
sessionId: session.id
|
|
1001
1115
|
});
|
|
1002
1116
|
conn.send(this.codec.toBuffer(responseMsg));
|
|
1003
|
-
|
|
1117
|
+
this.onConnect(conn, parsed.from, session, isReconnect);
|
|
1118
|
+
return session;
|
|
1004
1119
|
}
|
|
1005
1120
|
};
|
|
1006
1121
|
|
|
1007
1122
|
export {
|
|
1008
|
-
ProtocolError,
|
|
1009
1123
|
Connection,
|
|
1010
1124
|
Session,
|
|
1125
|
+
ProtocolError,
|
|
1011
1126
|
defaultTransportOptions,
|
|
1012
1127
|
Transport,
|
|
1013
1128
|
ClientTransport,
|