From 79bf31a889e2e672d616bdb75f7d3b25b3fb543c Mon Sep 17 00:00:00 2001 From: Khafra Date: Wed, 31 Jan 2024 11:26:03 -0500 Subject: [PATCH] websocket: fix close when no closing code is received --- lib/websocket/receiver.js | 7 +++++-- test/websocket/issue-2679.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 test/websocket/issue-2679.js 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') +})