livedesk 0.1.123 → 0.1.125

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.
@@ -1024,6 +1024,59 @@ function startsWithTcpBinaryFrameMagic(buffer) {
1024
1024
  && buffer.subarray(0, TCP_BINARY_FRAME_MAGIC.length).equals(TCP_BINARY_FRAME_MAGIC);
1025
1025
  }
1026
1026
 
1027
+ function isJsonObjectStartByte(value) {
1028
+ return value === 0x7b;
1029
+ }
1030
+
1031
+ function isWhitespaceByte(value) {
1032
+ return value === 0x20 || value === 0x09 || value === 0x0d || value === 0x0a;
1033
+ }
1034
+
1035
+ function findFirstNonWhitespaceByte(buffer) {
1036
+ if (!Buffer.isBuffer(buffer)) {
1037
+ return -1;
1038
+ }
1039
+
1040
+ for (let index = 0; index < buffer.length; index += 1) {
1041
+ if (!isWhitespaceByte(buffer[index])) {
1042
+ return index;
1043
+ }
1044
+ }
1045
+ return -1;
1046
+ }
1047
+
1048
+ function findTcpFrameOnlySyncIndex(buffer, startIndex = 0) {
1049
+ if (!Buffer.isBuffer(buffer) || buffer.length <= 0) {
1050
+ return -1;
1051
+ }
1052
+
1053
+ const safeStart = Math.max(0, Math.min(buffer.length, Math.floor(Number(startIndex) || 0)));
1054
+ const magicIndex = buffer.indexOf(TCP_BINARY_FRAME_MAGIC, safeStart);
1055
+ const jsonIndex = buffer.indexOf(0x7b, safeStart);
1056
+ if (magicIndex < 0) {
1057
+ return jsonIndex;
1058
+ }
1059
+ if (jsonIndex < 0) {
1060
+ return magicIndex;
1061
+ }
1062
+ return Math.min(magicIndex, jsonIndex);
1063
+ }
1064
+
1065
+ function keepTcpFrameOnlySyncTail(buffer) {
1066
+ if (!Buffer.isBuffer(buffer) || buffer.length <= 0) {
1067
+ return Buffer.alloc(0);
1068
+ }
1069
+
1070
+ const maxTailLength = Math.min(buffer.length, TCP_BINARY_FRAME_MAGIC.length - 1);
1071
+ for (let tailLength = maxTailLength; tailLength > 0; tailLength -= 1) {
1072
+ const tail = buffer.subarray(buffer.length - tailLength);
1073
+ if (hasTcpBinaryFrameMagicPrefix(tail)) {
1074
+ return tail;
1075
+ }
1076
+ }
1077
+ return Buffer.alloc(0);
1078
+ }
1079
+
1027
1080
  function parseTcpBinaryFramePacket(buffer) {
1028
1081
  if (!Buffer.isBuffer(buffer) || buffer.length < TCP_BINARY_FRAME_HEADER_BYTES) {
1029
1082
  return { incomplete: true };
@@ -3605,7 +3658,29 @@ export function createRemoteHub(options = {}) {
3605
3658
  : incoming;
3606
3659
 
3607
3660
  while (!socket.destroyed) {
3661
+ if (state.pendingBinaryFrame) {
3662
+ const { header, byteLength } = state.pendingBinaryFrame;
3663
+ if (state.buffer.length < byteLength) {
3664
+ return;
3665
+ }
3666
+
3667
+ const framePayload = state.buffer.subarray(0, byteLength);
3668
+ state.buffer = state.buffer.subarray(byteLength);
3669
+ state.pendingBinaryFrame = null;
3670
+ enqueueAgentBinaryFrame(socket, state, header, framePayload);
3671
+ continue;
3672
+ }
3673
+
3608
3674
  if (state.authenticated && state.frameOnly && state.buffer.length > 0) {
3675
+ const firstNonWhitespaceIndex = findFirstNonWhitespaceByte(state.buffer);
3676
+ if (firstNonWhitespaceIndex < 0) {
3677
+ state.buffer = Buffer.alloc(0);
3678
+ return;
3679
+ }
3680
+ if (firstNonWhitespaceIndex > 0) {
3681
+ state.buffer = state.buffer.subarray(firstNonWhitespaceIndex);
3682
+ }
3683
+
3609
3684
  if (state.buffer.length < TCP_BINARY_FRAME_MAGIC.length && hasTcpBinaryFrameMagicPrefix(state.buffer)) {
3610
3685
  return;
3611
3686
  }
@@ -3616,9 +3691,13 @@ export function createRemoteHub(options = {}) {
3616
3691
  return;
3617
3692
  }
3618
3693
  if (!packet || packet.invalid) {
3619
- writeJsonLine(socket, { type: 'error', error: 'invalid-tcp-binary-frame' });
3620
- logWarn('remote', `invalid tcp binary frame from agent: ${packet?.reason || 'bad-magic'}`);
3621
- socket.destroy();
3694
+ const syncIndex = findTcpFrameOnlySyncIndex(state.buffer, 1);
3695
+ if (syncIndex > 0) {
3696
+ state.buffer = state.buffer.subarray(syncIndex);
3697
+ continue;
3698
+ }
3699
+
3700
+ state.buffer = keepTcpFrameOnlySyncTail(state.buffer);
3622
3701
  return;
3623
3702
  }
3624
3703
 
@@ -3626,19 +3705,17 @@ export function createRemoteHub(options = {}) {
3626
3705
  enqueueAgentBinaryFrame(socket, state, packet.header, packet.payload);
3627
3706
  continue;
3628
3707
  }
3629
- }
3630
3708
 
3631
- if (state.pendingBinaryFrame) {
3632
- const { header, byteLength } = state.pendingBinaryFrame;
3633
- if (state.buffer.length < byteLength) {
3709
+ if (!isJsonObjectStartByte(state.buffer[0])) {
3710
+ const syncIndex = findTcpFrameOnlySyncIndex(state.buffer, 1);
3711
+ if (syncIndex > 0) {
3712
+ state.buffer = state.buffer.subarray(syncIndex);
3713
+ continue;
3714
+ }
3715
+
3716
+ state.buffer = keepTcpFrameOnlySyncTail(state.buffer);
3634
3717
  return;
3635
3718
  }
3636
-
3637
- const framePayload = state.buffer.subarray(0, byteLength);
3638
- state.buffer = state.buffer.subarray(byteLength);
3639
- state.pendingBinaryFrame = null;
3640
- enqueueAgentBinaryFrame(socket, state, header, framePayload);
3641
- continue;
3642
3719
  }
3643
3720
 
3644
3721
  const newlineIndex = state.buffer.indexOf(0x0a);
@@ -3676,6 +3753,9 @@ export function createRemoteHub(options = {}) {
3676
3753
 
3677
3754
  handleAgentMessage(socket, state, message);
3678
3755
  } catch (err) {
3756
+ if (state.authenticated && state.frameOnly) {
3757
+ continue;
3758
+ }
3679
3759
  writeJsonLine(socket, { type: 'error', error: 'invalid-json' });
3680
3760
  logWarn('remote', `invalid agent message: ${err?.message || err}`);
3681
3761
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livedesk",
3
- "version": "0.1.123",
3
+ "version": "0.1.125",
4
4
  "description": "LiveDesk Hub and client launcher",
5
5
  "type": "module",
6
6
  "bin": {