diff --git a/lib/websocket/receiver.js b/lib/websocket/receiver.js index c75939c29b7..28ff8b25f5c 100644 --- a/lib/websocket/receiver.js +++ b/lib/websocket/receiver.js @@ -107,8 +107,11 @@ class ByteParser extends Writable { // Close frame, the endpoint MUST send a Close frame in response. (When // sending a Close frame in response, the endpoint typically echos the // status code it received.) - const body = Buffer.allocUnsafe(2) - body.writeUInt16BE(this.#info.closeInfo.code, 0) + let body = emptyBuffer + if (this.#info.closeInfo.code) { + body = Buffer.allocUnsafe(2) + body.writeUInt16BE(this.#info.closeInfo.code, 0) + } const closeFrame = new WebsocketFrameSend(body) this.ws[kResponse].socket.write( diff --git a/test/websocket/issue-2679.js b/test/websocket/issue-2679.js new file mode 100644 index 00000000000..85efe10a4f2 --- /dev/null +++ b/test/websocket/issue-2679.js @@ -0,0 +1,29 @@ +'use strict' + +const { test } = require('node:test') +const assert = require('node:assert') +const { once } = require('node:events') +const { WebSocketServer } = require('ws') +const { WebSocket } = require('../..') + +test('Close without receiving code does not send an invalid payload', async () => { + const server = new WebSocketServer({ port: 0 }) + + await once(server, 'listening') + + server.on('connection', (sock, request) => { + setTimeout(() => { + sock.close() + }, 3000) + }) + + server.on('error', (err) => assert.ifError(err)) + + const client = new WebSocket(`ws://127.0.0.1:${server.address().port}`) + await once(client, 'open') + + await once(client, 'close') + + server.close() + await once(server, 'close') +})