RpcMessageDecoder.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.RpcMessageDecoder = void 0;
  4. const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
  5. const errors_1 = require("./errors");
  6. const messages_1 = require("./messages");
  7. const EMPTY_BUFFER = new Uint8Array(0);
  8. const EMPTY_READER = new Reader_1.Reader(EMPTY_BUFFER);
  9. class RpcMessageDecoder {
  10. decodeMessage(reader) {
  11. const startPos = reader.x;
  12. try {
  13. if (reader.size() < 8)
  14. return undefined;
  15. const xid = reader.u32();
  16. const msgType = reader.u32();
  17. if (msgType === 0) {
  18. if (reader.size() < 20)
  19. return (reader.x = startPos), undefined;
  20. const rpcvers = reader.u32();
  21. const prog = reader.u32();
  22. const vers = reader.u32();
  23. const proc = reader.u32();
  24. const cred = this.readOpaqueAuth(reader);
  25. if (!cred)
  26. return (reader.x = startPos), undefined;
  27. const verf = this.readOpaqueAuth(reader);
  28. if (!verf)
  29. return (reader.x = startPos), undefined;
  30. const params = reader.size() > 0 ? reader.cut(reader.size()) : undefined;
  31. return new messages_1.RpcCallMessage(xid, rpcvers, prog, vers, proc, cred, verf, params);
  32. }
  33. else if (msgType === 1) {
  34. if (reader.size() < 4)
  35. return (reader.x = startPos), undefined;
  36. const replyStat = reader.u32();
  37. if (replyStat === 0) {
  38. const verf = this.readOpaqueAuth(reader);
  39. if (!verf || reader.size() < 4)
  40. return (reader.x = startPos), undefined;
  41. const acceptStat = reader.u32();
  42. let mismatchInfo;
  43. if (acceptStat === 2) {
  44. if (reader.size() < 8)
  45. return (reader.x = startPos), undefined;
  46. const low = reader.u32();
  47. const high = reader.u32();
  48. mismatchInfo = new messages_1.RpcMismatchInfo(low, high);
  49. }
  50. const results = reader.size() > 0 ? reader.cut(reader.size()) : undefined;
  51. return new messages_1.RpcAcceptedReplyMessage(xid, verf, acceptStat, mismatchInfo, results);
  52. }
  53. else if (replyStat === 1) {
  54. if (reader.size() < 4)
  55. return (reader.x = startPos), undefined;
  56. const rejectStat = reader.u32();
  57. let mismatchInfo;
  58. let authStat;
  59. if (rejectStat === 0) {
  60. if (reader.size() < 8)
  61. return (reader.x = startPos), undefined;
  62. const low = reader.u32();
  63. const high = reader.u32();
  64. mismatchInfo = new messages_1.RpcMismatchInfo(low, high);
  65. if (!mismatchInfo)
  66. return (reader.x = startPos), undefined;
  67. }
  68. else if (rejectStat === 1) {
  69. if (reader.size() < 4)
  70. return (reader.x = startPos), undefined;
  71. authStat = reader.u32();
  72. }
  73. return new messages_1.RpcRejectedReplyMessage(xid, rejectStat, mismatchInfo, authStat);
  74. }
  75. else {
  76. throw new errors_1.RpcDecodingError('Invalid reply_stat');
  77. }
  78. }
  79. else {
  80. throw new errors_1.RpcDecodingError('Invalid msg_type');
  81. }
  82. }
  83. catch (err) {
  84. if (err instanceof RangeError) {
  85. reader.x = startPos;
  86. return undefined;
  87. }
  88. throw err;
  89. }
  90. }
  91. readOpaqueAuth(reader) {
  92. if (reader.size() < 8)
  93. return undefined;
  94. const flavor = reader.u32();
  95. const length = reader.u32();
  96. if (length > 400)
  97. throw new errors_1.RpcDecodingError('Auth body too large');
  98. const paddedLength = (length + 3) & ~3;
  99. if (reader.size() < paddedLength)
  100. return undefined;
  101. const body = length > 0 ? reader.cut(length) : EMPTY_READER;
  102. const padding = paddedLength - length;
  103. if (padding > 0)
  104. reader.skip(padding);
  105. return new messages_1.RpcOpaqueAuth(flavor, body);
  106. }
  107. }
  108. exports.RpcMessageDecoder = RpcMessageDecoder;
  109. //# sourceMappingURL=RpcMessageDecoder.js.map