123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /**
- * @file Utility functions for creating frames
- */
- 'use strict'
- /**
- * Creates a text frame
- * @param {string} data
- * @param {boolean} [masked=false] if the frame should be masked
- * @returns {Buffer}
- * @private
- */
- exports.createTextFrame = function (data, masked) {
- var payload, meta
- payload = Buffer.from(data)
- meta = generateMetaData(true, 1, masked === undefined ? false : masked, payload)
- return Buffer.concat([meta, payload], meta.length + payload.length)
- }
- /**
- * Create a binary frame
- * @param {Buffer} data
- * @param {boolean} [masked=false] if the frame should be masked
- * @param {boolean} [first=true] if this is the first frame in a sequence
- * @param {boolean} [fin=true] if this is the final frame in a sequence
- * @returns {Buffer}
- * @private
- */
- exports.createBinaryFrame = function (data, masked, first, fin) {
- var payload, meta
- first = first === undefined ? true : first
- masked = masked === undefined ? false : masked
- if (masked) {
- payload = Buffer.alloc(data.length)
- data.copy(payload)
- } else {
- payload = data
- }
- meta = generateMetaData(fin === undefined ? true : fin, first ? 2 : 0, masked, payload)
- return Buffer.concat([meta, payload], meta.length + payload.length)
- }
- /**
- * Create a close frame
- * @param {number} code
- * @param {string} [reason='']
- * @param {boolean} [masked=false] if the frame should be masked
- * @returns {Buffer}
- * @private
- */
- exports.createCloseFrame = function (code, reason, masked) {
- var payload, meta
- if (code !== undefined && code !== 1005) {
- payload = Buffer.from(reason === undefined ? '--' : '--' + reason)
- payload.writeUInt16BE(code, 0)
- } else {
- payload = Buffer.alloc(0)
- }
- meta = generateMetaData(true, 8, masked === undefined ? false : masked, payload)
- return Buffer.concat([meta, payload], meta.length + payload.length)
- }
- /**
- * Create a ping frame
- * @param {string} data
- * @param {boolean} [masked=false] if the frame should be masked
- * @returns {Buffer}
- * @private
- */
- exports.createPingFrame = function (data, masked) {
- var payload, meta
- payload = Buffer.from(data)
- meta = generateMetaData(true, 9, masked === undefined ? false : masked, payload)
- return Buffer.concat([meta, payload], meta.length + payload.length)
- }
- /**
- * Create a pong frame
- * @param {string} data
- * @param {boolean} [masked=false] if the frame should be masked
- * @returns {Buffer}
- * @private
- */
- exports.createPongFrame = function (data, masked) {
- var payload, meta
- payload = Buffer.from(data)
- meta = generateMetaData(true, 10, masked === undefined ? false : masked, payload)
- return Buffer.concat([meta, payload], meta.length + payload.length)
- }
- /**
- * Creates the meta-data portion of the frame
- * If the frame is masked, the payload is altered accordingly
- * @param {boolean} fin
- * @param {number} opcode
- * @param {boolean} masked
- * @param {Buffer} payload
- * @returns {Buffer}
- * @private
- */
- function generateMetaData(fin, opcode, masked, payload) {
- var len, meta, start, mask, i
- len = payload.length
- // Creates the buffer for meta-data
- meta = Buffer.alloc(2 + (len < 126 ? 0 : (len < 65536 ? 2 : 8)) + (masked ? 4 : 0))
- // Sets fin and opcode
- meta[0] = (fin ? 128 : 0) + opcode
- // Sets the mask and length
- meta[1] = masked ? 128 : 0
- start = 2
- if (len < 126) {
- meta[1] += len
- } else if (len < 65536) {
- meta[1] += 126
- meta.writeUInt16BE(len, 2)
- start += 2
- } else {
- // Warning: JS doesn't support integers greater than 2^53
- meta[1] += 127
- meta.writeUInt32BE(Math.floor(len / Math.pow(2, 32)), 2)
- meta.writeUInt32BE(len % Math.pow(2, 32), 6)
- start += 8
- }
- // Set the mask-key
- if (masked) {
- mask = Buffer.alloc(4)
- for (i = 0; i < 4; i++) {
- meta[start + i] = mask[i] = Math.floor(Math.random() * 256)
- }
- for (i = 0; i < payload.length; i++) {
- payload[i] ^= mask[i % 4]
- }
- start += 4
- }
- return meta
- }
|