split-message.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. var util = require('../core').util;
  2. var toBuffer = util.buffer.toBuffer;
  3. // All prelude components are unsigned, 32-bit integers
  4. var PRELUDE_MEMBER_LENGTH = 4;
  5. // The prelude consists of two components
  6. var PRELUDE_LENGTH = PRELUDE_MEMBER_LENGTH * 2;
  7. // Checksums are always CRC32 hashes.
  8. var CHECKSUM_LENGTH = 4;
  9. // Messages must include a full prelude, a prelude checksum, and a message checksum
  10. var MINIMUM_MESSAGE_LENGTH = PRELUDE_LENGTH + CHECKSUM_LENGTH * 2;
  11. /**
  12. * @api private
  13. *
  14. * @param {Buffer} message
  15. */
  16. function splitMessage(message) {
  17. if (!util.Buffer.isBuffer(message)) message = toBuffer(message);
  18. if (message.length < MINIMUM_MESSAGE_LENGTH) {
  19. throw new Error('Provided message too short to accommodate event stream message overhead');
  20. }
  21. if (message.length !== message.readUInt32BE(0)) {
  22. throw new Error('Reported message length does not match received message length');
  23. }
  24. var expectedPreludeChecksum = message.readUInt32BE(PRELUDE_LENGTH);
  25. if (
  26. expectedPreludeChecksum !== util.crypto.crc32(
  27. message.slice(0, PRELUDE_LENGTH)
  28. )
  29. ) {
  30. throw new Error(
  31. 'The prelude checksum specified in the message (' +
  32. expectedPreludeChecksum +
  33. ') does not match the calculated CRC32 checksum.'
  34. );
  35. }
  36. var expectedMessageChecksum = message.readUInt32BE(message.length - CHECKSUM_LENGTH);
  37. if (
  38. expectedMessageChecksum !== util.crypto.crc32(
  39. message.slice(0, message.length - CHECKSUM_LENGTH)
  40. )
  41. ) {
  42. throw new Error(
  43. 'The message checksum did not match the expected value of ' +
  44. expectedMessageChecksum
  45. );
  46. }
  47. var headersStart = PRELUDE_LENGTH + CHECKSUM_LENGTH;
  48. var headersEnd = headersStart + message.readUInt32BE(PRELUDE_MEMBER_LENGTH);
  49. return {
  50. headers: message.slice(headersStart, headersEnd),
  51. body: message.slice(headersEnd, message.length - CHECKSUM_LENGTH),
  52. };
  53. }
  54. /**
  55. * @api private
  56. */
  57. module.exports = {
  58. splitMessage: splitMessage
  59. };