WsFrameDecoder.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.WsFrameDecoder = void 0;
  4. const StreamingOctetReader_1 = require("@jsonjoy.com/buffers/lib/StreamingOctetReader");
  5. const constants_1 = require("./constants");
  6. const errors_1 = require("./errors");
  7. const frames_1 = require("./frames");
  8. class WsFrameDecoder {
  9. constructor() {
  10. this.reader = new StreamingOctetReader_1.StreamingOctetReader();
  11. }
  12. push(uint8) {
  13. this.reader.push(uint8);
  14. }
  15. readFrameHeader() {
  16. try {
  17. const reader = this.reader;
  18. if (reader.size() < 2)
  19. return undefined;
  20. const b0 = reader.u8();
  21. const b1 = reader.u8();
  22. const fin = (b0 >>> 7);
  23. const opcode = b0 & 0b1111;
  24. const maskBit = b1 >>> 7;
  25. let length = b1 & 0b01111111;
  26. if (length === 126) {
  27. if (reader.size() < 2)
  28. return undefined;
  29. length = (reader.u8() << 8) | reader.u8();
  30. }
  31. else if (length === 127) {
  32. if (reader.size() < 8)
  33. return undefined;
  34. reader.skip(4);
  35. length = reader.u32();
  36. }
  37. let mask;
  38. if (maskBit) {
  39. if (reader.size() < 4)
  40. return undefined;
  41. mask = [reader.u8(), reader.u8(), reader.u8(), reader.u8()];
  42. }
  43. if (opcode >= constants_1.WsFrameOpcode.MIN_CONTROL_OPCODE) {
  44. switch (opcode) {
  45. case constants_1.WsFrameOpcode.CLOSE: {
  46. return new frames_1.WsCloseFrame(fin, opcode, length, mask, 0, '');
  47. }
  48. case constants_1.WsFrameOpcode.PING: {
  49. if (length > 125)
  50. throw new errors_1.WsFrameDecodingError();
  51. const data = mask ? reader.bufXor(length, mask, 0) : reader.buf(length);
  52. return new frames_1.WsPingFrame(fin, opcode, length, mask, data);
  53. }
  54. case constants_1.WsFrameOpcode.PONG: {
  55. if (length > 125)
  56. throw new errors_1.WsFrameDecodingError();
  57. const data = mask ? reader.bufXor(length, mask, 0) : reader.buf(length);
  58. return new frames_1.WsPongFrame(fin, opcode, length, mask, data);
  59. }
  60. default: {
  61. throw new errors_1.WsFrameDecodingError();
  62. }
  63. }
  64. }
  65. return new frames_1.WsFrameHeader(fin, opcode, length, mask);
  66. }
  67. catch (err) {
  68. if (err instanceof RangeError)
  69. return undefined;
  70. throw err;
  71. }
  72. }
  73. readFrameData(frame, remaining, dst, pos) {
  74. const reader = this.reader;
  75. const mask = frame.mask;
  76. const readSize = Math.min(reader.size(), remaining);
  77. if (!mask)
  78. reader.copy(readSize, dst, pos);
  79. else {
  80. const alreadyRead = frame.length - remaining;
  81. reader.copyXor(readSize, dst, pos, mask, alreadyRead);
  82. }
  83. return remaining - readSize;
  84. }
  85. copyFrameData(frame, dst, pos) {
  86. const reader = this.reader;
  87. const mask = frame.mask;
  88. const readSize = frame.length;
  89. if (!mask)
  90. reader.copy(readSize, dst, pos);
  91. else
  92. reader.copyXor(readSize, dst, pos, mask, 0);
  93. }
  94. readCloseFrameData(frame) {
  95. let length = frame.length;
  96. if (length > 125)
  97. throw new errors_1.WsFrameDecodingError();
  98. let code = 0;
  99. let reason = '';
  100. if (length > 0) {
  101. if (length < 2)
  102. throw new errors_1.WsFrameDecodingError();
  103. const reader = this.reader;
  104. const mask = frame.mask;
  105. const octet1 = reader.u8() ^ (mask ? mask[0] : 0);
  106. const octet2 = reader.u8() ^ (mask ? mask[1] : 0);
  107. code = (octet1 << 8) | octet2;
  108. length -= 2;
  109. if (length)
  110. reason = reader.utf8(length, mask ?? [0, 0, 0, 0], 2);
  111. }
  112. frame.code = code;
  113. frame.reason = reason;
  114. }
  115. }
  116. exports.WsFrameDecoder = WsFrameDecoder;
  117. //# sourceMappingURL=WsFrameDecoder.js.map