From 8b5e1b644a178b227bedd7957dea333d04c9d52d Mon Sep 17 00:00:00 2001 From: ZyLacx Date: Mon, 27 Dec 2021 17:15:56 +0100 Subject: [PATCH] Update stream.js --- node_modules/ws/lib/stream.js | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/node_modules/ws/lib/stream.js b/node_modules/ws/lib/stream.js index 6e2f0b4..19e1bff 100644 --- a/node_modules/ws/lib/stream.js +++ b/node_modules/ws/lib/stream.js @@ -5,7 +5,7 @@ const { Duplex } = require('stream'); /** * Emits the `'close'` event on a stream. * - * @param {stream.Duplex} The stream. + * @param {Duplex} stream The stream. * @private */ function emitClose(stream) { @@ -26,6 +26,7 @@ function duplexOnEnd() { /** * The listener of the `'error'` event. * + * @param {Error} err The error * @private */ function duplexOnError(err) { @@ -41,12 +42,13 @@ function duplexOnError(err) { * Wraps a `WebSocket` in a duplex stream. * * @param {WebSocket} ws The `WebSocket` to wrap - * @param {Object} options The options for the `Duplex` constructor - * @return {stream.Duplex} The duplex stream + * @param {Object} [options] The options for the `Duplex` constructor + * @return {Duplex} The duplex stream * @public */ function createWebSocketStream(ws, options) { let resumeOnReceiverDrain = true; + let terminateOnDestroy = true; function receiverOnDrain() { if (resumeOnReceiverDrain) ws._socket.resume(); @@ -80,6 +82,16 @@ function createWebSocketStream(ws, options) { ws.once('error', function error(err) { if (duplex.destroyed) return; + // Prevent `ws.terminate()` from being called by `duplex._destroy()`. + // + // - If the `'error'` event is emitted before the `'open'` event, then + // `ws.terminate()` is a noop as no socket is assigned. + // - Otherwise, the error is re-emitted by the listener of the `'error'` + // event of the `Receiver` object. The listener already closes the + // connection by calling `ws.close()`. This allows a close frame to be + // sent to the other peer. If `ws.terminate()` is called right after this, + // then the close frame might not be sent. + terminateOnDestroy = false; duplex.destroy(err); }); @@ -107,7 +119,8 @@ function createWebSocketStream(ws, options) { if (!called) callback(err); process.nextTick(emitClose, duplex); }); - ws.terminate(); + + if (terminateOnDestroy) ws.terminate(); }; duplex._final = function (callback) { @@ -139,7 +152,10 @@ function createWebSocketStream(ws, options) { }; duplex._read = function () { - if (ws.readyState === ws.OPEN && !resumeOnReceiverDrain) { + if ( + (ws.readyState === ws.OPEN || ws.readyState === ws.CLOSING) && + !resumeOnReceiverDrain + ) { resumeOnReceiverDrain = true; if (!ws._receiver._writableState.needDrain) ws._socket.resume(); }