Skip to content

Commit 01346b5

Browse files
authored
fix(websocket): deprecation warning & 64-bit unsigned int body length (nodejs#1818)
1 parent 0cfe689 commit 01346b5

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

lib/websocket/frame.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ class WebsocketFrameSend {
4545
if (payloadLength === 126) {
4646
new DataView(buffer.buffer).setUint16(2, bodyLength)
4747
} else if (payloadLength === 127) {
48-
// TODO: optimize this once tests are added for payloads >= 2^16 bytes
48+
// Clear extended payload length
49+
buffer[2] = buffer[3] = 0
4950
buffer.writeUIntBE(bodyLength, 4, 6)
5051
}
5152

lib/websocket/receiver.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,10 @@ class ByteParser extends Writable {
196196
}
197197

198198
const buffer = this.consume(8)
199+
const upper = buffer.readUInt32BE(0)
200+
const lower = buffer.readUInt32BE(4)
199201

200-
// TODO: optimize this
201-
// TODO: this likely doesn't work because it returns a bigint
202-
this.#info.payloadLength = buffer.readBigUint64BE(0)
202+
this.#info.payloadLength = (upper << 8) + lower
203203
this.#state = parserStates.READ_DATA
204204
} else if (this.#state === parserStates.READ_DATA) {
205205
if (this.#byteOffset < this.#info.payloadLength) {

lib/websocket/websocket.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,14 @@ class WebSocket extends EventTarget {
314314
// by the length of data’s buffer in bytes.
315315

316316
const ab = new ArrayBuffer(data.byteLength)
317-
new data.constructor(ab).set(data)
317+
318+
if (Buffer.isBuffer(data)) {
319+
// new Buffer signature is deprecated
320+
Buffer.from(ab).set(data)
321+
} else {
322+
new data.constructor(ab).set(data)
323+
}
324+
318325
const value = Buffer.from(ab)
319326

320327
const frame = new WebsocketFrameSend(value)

test/websocket/send.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict'
2+
3+
const { test } = require('tap')
4+
const { WebSocketServer } = require('ws')
5+
const { Blob } = require('buffer')
6+
const { WebSocket } = require('../..')
7+
8+
test('Sending > 2^16 bytes', (t) => {
9+
t.plan(3)
10+
11+
const server = new WebSocketServer({ port: 0 })
12+
13+
server.on('connection', (ws) => {
14+
ws.on('message', (m, isBinary) => {
15+
ws.send(m, { binary: isBinary })
16+
})
17+
})
18+
19+
const payload = Buffer.allocUnsafe(2 ** 16).fill('Hello')
20+
21+
const ws = new WebSocket(`ws://localhost:${server.address().port}`)
22+
23+
ws.addEventListener('open', () => {
24+
ws.send(payload)
25+
})
26+
27+
ws.addEventListener('message', async ({ data }) => {
28+
t.type(data, Blob)
29+
t.equal(data.size, payload.length)
30+
t.same(Buffer.from(await data.arrayBuffer()), payload)
31+
32+
ws.close()
33+
server.close()
34+
})
35+
})

0 commit comments

Comments
 (0)