@kb-labs/gateway-app 2.118.0 → 2.118.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/dist/index.js +57 -5
- package/dist/index.js.map +1 -1
- package/package.json +19 -19
package/dist/index.js
CHANGED
|
@@ -2697,17 +2697,48 @@ function pumpBidirectional(client, upstream, logger) {
|
|
|
2697
2697
|
const pending = [];
|
|
2698
2698
|
let upstreamOpen = false;
|
|
2699
2699
|
let closed = false;
|
|
2700
|
-
const
|
|
2700
|
+
const startedAt = Date.now();
|
|
2701
|
+
let clientToUpstreamMessages = 0;
|
|
2702
|
+
let upstreamToClientMessages = 0;
|
|
2703
|
+
let clientToUpstreamBytes = 0;
|
|
2704
|
+
let upstreamToClientBytes = 0;
|
|
2705
|
+
let droppedMessages = 0;
|
|
2706
|
+
const byteLength = (data) => {
|
|
2707
|
+
if (typeof data === "string") {
|
|
2708
|
+
return Buffer.byteLength(data);
|
|
2709
|
+
}
|
|
2710
|
+
if (Buffer.isBuffer(data)) {
|
|
2711
|
+
return data.byteLength;
|
|
2712
|
+
}
|
|
2713
|
+
if (data instanceof ArrayBuffer) {
|
|
2714
|
+
return data.byteLength;
|
|
2715
|
+
}
|
|
2716
|
+
return data.reduce((total, chunk) => total + chunk.byteLength, 0);
|
|
2717
|
+
};
|
|
2718
|
+
const closeBoth = (code, reason, closeReason = "peer_closed") => {
|
|
2701
2719
|
if (closed) {
|
|
2702
2720
|
return;
|
|
2703
2721
|
}
|
|
2704
2722
|
closed = true;
|
|
2705
2723
|
safeClose(client, code, reason);
|
|
2706
2724
|
safeClose(upstream, code, reason);
|
|
2725
|
+
logger.info("Gateway WebSocket relay closed", {
|
|
2726
|
+
event: "websocket.relay.closed",
|
|
2727
|
+
closeReason,
|
|
2728
|
+
closeCode: code,
|
|
2729
|
+
durationMs: Date.now() - startedAt,
|
|
2730
|
+
clientToUpstreamMessages,
|
|
2731
|
+
upstreamToClientMessages,
|
|
2732
|
+
clientToUpstreamBytes,
|
|
2733
|
+
upstreamToClientBytes,
|
|
2734
|
+
droppedMessages
|
|
2735
|
+
});
|
|
2707
2736
|
};
|
|
2708
2737
|
client.on("message", (data, isBinary) => {
|
|
2709
2738
|
if (upstreamOpen && upstream.readyState === OPEN) {
|
|
2710
2739
|
upstream.send(data, { binary: isBinary });
|
|
2740
|
+
clientToUpstreamMessages += 1;
|
|
2741
|
+
clientToUpstreamBytes += byteLength(data);
|
|
2711
2742
|
} else {
|
|
2712
2743
|
pending.push({ data, binary: isBinary });
|
|
2713
2744
|
}
|
|
@@ -2717,6 +2748,10 @@ function pumpBidirectional(client, upstream, logger) {
|
|
|
2717
2748
|
for (const frame of pending) {
|
|
2718
2749
|
if (upstream.readyState === OPEN) {
|
|
2719
2750
|
upstream.send(frame.data, { binary: frame.binary });
|
|
2751
|
+
clientToUpstreamMessages += 1;
|
|
2752
|
+
clientToUpstreamBytes += byteLength(frame.data);
|
|
2753
|
+
} else {
|
|
2754
|
+
droppedMessages += 1;
|
|
2720
2755
|
}
|
|
2721
2756
|
}
|
|
2722
2757
|
pending.length = 0;
|
|
@@ -2724,6 +2759,10 @@ function pumpBidirectional(client, upstream, logger) {
|
|
|
2724
2759
|
upstream.on("message", (data, isBinary) => {
|
|
2725
2760
|
if (client.readyState === OPEN) {
|
|
2726
2761
|
client.send(data, { binary: isBinary });
|
|
2762
|
+
upstreamToClientMessages += 1;
|
|
2763
|
+
upstreamToClientBytes += byteLength(data);
|
|
2764
|
+
} else {
|
|
2765
|
+
droppedMessages += 1;
|
|
2727
2766
|
}
|
|
2728
2767
|
});
|
|
2729
2768
|
upstream.on("close", (code, reason) => {
|
|
@@ -2734,11 +2773,11 @@ function pumpBidirectional(client, upstream, logger) {
|
|
|
2734
2773
|
});
|
|
2735
2774
|
upstream.on("error", (err) => {
|
|
2736
2775
|
logger.warn("Upstream WS error", { error: err.message });
|
|
2737
|
-
closeBoth(1011);
|
|
2776
|
+
closeBoth(1011, void 0, "upstream_error");
|
|
2738
2777
|
});
|
|
2739
2778
|
client.on("error", (err) => {
|
|
2740
2779
|
logger.warn("Client WS error", { error: err.message });
|
|
2741
|
-
closeBoth(1011);
|
|
2780
|
+
closeBoth(1011, void 0, "client_error");
|
|
2742
2781
|
});
|
|
2743
2782
|
}
|
|
2744
2783
|
|
|
@@ -2796,8 +2835,21 @@ function attachGatewayWs(server, cache, jwtConfig, logger, hostRegistry, socketW
|
|
|
2796
2835
|
const { search } = new URL(req.url ?? "/", "http://localhost");
|
|
2797
2836
|
const upstreamUrl = buildUpstreamWsUrl(socketUpstream, pathname, search);
|
|
2798
2837
|
wss.handleUpgrade(req, socket, head, (clientWs) => {
|
|
2799
|
-
const
|
|
2800
|
-
|
|
2838
|
+
const requestId = typeof req.headers["x-request-id"] === "string" ? req.headers["x-request-id"] : randomUUID();
|
|
2839
|
+
const traceId = typeof req.headers["x-trace-id"] === "string" ? req.headers["x-trace-id"] : randomUUID();
|
|
2840
|
+
const connectionId = randomUUID();
|
|
2841
|
+
const connectionLogger = logger.child({
|
|
2842
|
+
requestId,
|
|
2843
|
+
traceId,
|
|
2844
|
+
"network.transport": "websocket",
|
|
2845
|
+
"network.connection_id": connectionId,
|
|
2846
|
+
"http.route": pathname
|
|
2847
|
+
}) ?? logger;
|
|
2848
|
+
connectionLogger.info("Gateway WebSocket relay opened", { event: "websocket.relay.opened" });
|
|
2849
|
+
const upstreamWs = new WebSocket(upstreamUrl, {
|
|
2850
|
+
headers: { ...forwardWsHeaders(req), "x-request-id": requestId, "x-trace-id": traceId }
|
|
2851
|
+
});
|
|
2852
|
+
pumpBidirectional(clientWs, upstreamWs, connectionLogger);
|
|
2801
2853
|
});
|
|
2802
2854
|
return;
|
|
2803
2855
|
}
|