Spaces:
Runtime error
Runtime error
const { maxUnsigned16Bit } = require('./constants') | |
/** @type {import('crypto')} */ | |
let crypto | |
try { | |
crypto = require('crypto') | |
} catch { | |
} | |
class WebsocketFrameSend { | |
/** | |
* @param {Buffer|undefined} data | |
*/ | |
constructor (data) { | |
this.frameData = data | |
this.maskKey = crypto.randomBytes(4) | |
} | |
createFrame (opcode) { | |
const bodyLength = this.frameData?.byteLength ?? 0 | |
/** @type {number} */ | |
let payloadLength = bodyLength // 0-125 | |
let offset = 6 | |
if (bodyLength > maxUnsigned16Bit) { | |
offset += 8 // payload length is next 8 bytes | |
payloadLength = 127 | |
} else if (bodyLength > 125) { | |
offset += 2 // payload length is next 2 bytes | |
payloadLength = 126 | |
} | |
const buffer = Buffer.allocUnsafe(bodyLength + offset) | |
// Clear first 2 bytes, everything else is overwritten | |
buffer[0] = buffer[1] = 0 | |
buffer[0] |= 0x80 // FIN | |
buffer[0] = (buffer[0] & 0xF0) + opcode // opcode | |
/*! ws. MIT License. Einar Otto Stangvik <[email protected]> */ | |
buffer[offset - 4] = this.maskKey[0] | |
buffer[offset - 3] = this.maskKey[1] | |
buffer[offset - 2] = this.maskKey[2] | |
buffer[offset - 1] = this.maskKey[3] | |
buffer[1] = payloadLength | |
if (payloadLength === 126) { | |
buffer.writeUInt16BE(bodyLength, 2) | |
} else if (payloadLength === 127) { | |
// Clear extended payload length | |
buffer[2] = buffer[3] = 0 | |
buffer.writeUIntBE(bodyLength, 4, 6) | |
} | |
buffer[1] |= 0x80 // MASK | |
// mask body | |
for (let i = 0; i < bodyLength; i++) { | |
buffer[offset + i] = this.frameData[i] ^ this.maskKey[i % 4] | |
} | |
return buffer | |
} | |
} | |
module.exports = { | |
WebsocketFrameSend | |
} | |