chore(base-driver): Update ws dependency
MODIFY
packages/base-driver/lib/express/websocket.js
packages/base-driver/lib/express/websocket.js
import _ from 'lodash';
-import url from 'url';
+import { URL } from 'url';
+import B from 'bluebird';
const DEFAULT_WS_PATHNAME_PREFIX = '/ws';
@@ -18,19 +19,16 @@ const DEFAULT_WS_PATHNAME_PREFIX = '/ws';
* on how to configure the handler properly.
*/
async function addWebSocketHandler (handlerPathname, handlerServer) { // eslint-disable-line require-await
- let isUpgradeListenerAssigned = true;
if (_.isUndefined(this.webSocketsMapping)) {
this.webSocketsMapping = {};
- isUpgradeListenerAssigned = false;
- }
- this.webSocketsMapping[handlerPathname] = handlerServer;
- if (isUpgradeListenerAssigned) {
- return;
- }
-
// https://github.com/websockets/ws/pull/885
this.on('upgrade', (request, socket, head) => {
- const currentPathname = url.parse(request.url).pathname;
+ let currentPathname;
+ try {
+ currentPathname = (new URL(request.url)).pathname;
+ } catch (ign) {
+ currentPathname = request.url;
+ }
for (const [pathname, wsServer] of _.toPairs(this.webSocketsMapping)) {
if (currentPathname === pathname) {
wsServer.handleUpgrade(request, socket, head, (ws) => {
@@ -42,6 +40,8 @@ async function addWebSocketHandler (handlerPathname, handlerServer) { // eslint-
socket.destroy();
});
}
+ this.webSocketsMapping[handlerPathname] = handlerServer;
+}
/**
* Returns web socket handlers registered for the given server
@@ -59,13 +59,12 @@ async function getWebSocketHandlers (keysFilter = null) { // eslint-disable-line
return {};
}
- let result = {};
- for (const [pathname, wsServer] of _.toPairs(this.webSocketsMapping)) {
+ return _.toPairs(this.webSocketsMapping).reduce((acc, [pathname, wsServer]) => {
if (!_.isString(keysFilter) || pathname.includes(keysFilter)) {
- result[pathname] = wsServer;
+ acc[pathname] = wsServer;
}
- }
- return result;
+ return acc;
+ }, {});
}
/**
@@ -79,12 +78,16 @@ async function getWebSocketHandlers (keysFilter = null) { // eslint-disable-line
* @returns {boolean} true if the handlerPathname was found and deleted
*/
async function removeWebSocketHandler (handlerPathname) { // eslint-disable-line require-await
- if (!this.webSocketsMapping || !this.webSocketsMapping[handlerPathname]) {
+ const wsServer = this.webSocketsMapping?.[handlerPathname];
+ if (!wsServer) {
return false;
}
try {
- this.webSocketsMapping[handlerPathname].close();
+ wsServer.close();
+ for (const client of (wsServer.clients || [])) {
+ client.terminate();
+ }
return true;
} catch (ign) {
// ignore
@@ -106,11 +109,11 @@ async function removeAllWebSocketHandlers () {
return false;
}
- let result = false;
- for (const pathname of _.keys(this.webSocketsMapping)) {
- result = result || await this.removeWebSocketHandler(pathname);
- }
- return result;
+ return _.some(
+ await B.all(
+ _.keys(this.webSocketsMapping).map((pathname) => this.removeWebSocketHandler(pathname))
+ )
+ );
}
export {

MODIFY
packages/base-driver/package.json
packages/base-driver/package.json
"morgan": "1.10.0",
"serve-favicon": "2.5.0",
"source-map-support": "0.5.21",
- "validate.js": "0.13.1",
- "ws": "7.5.7"
+ "validate.js": "0.13.1"
+ },
+ "devDependencies": {
+ "ws": "8.5.0"
},
"engines": {
"node": ">=12",

MODIFY
packages/base-driver/test/e2e/basedriver/websockets.e2e.spec.js
packages/base-driver/test/e2e/basedriver/websockets.e2e.spec.js
import _ from 'lodash';
-import { server, routeConfiguringFunction,
- DEFAULT_WS_PATHNAME_PREFIX } from '../../../lib';
+import {
+ server, routeConfiguringFunction, DEFAULT_WS_PATHNAME_PREFIX
+} from '../../../lib';
import { FakeDriver } from '../protocol/fake-driver';
import WebSocket from 'ws';
import B from 'bluebird';
@@ -45,15 +46,20 @@ describe('Websockets (e2e)', function () {
_.keys(await baseServer.getWebSocketHandlers()).length.should.eql(1);
await new B((resolve, reject) => {
const client = new WebSocket(`ws://${TEST_HOST}:${port}${endpoint}`);
- client.on('connection', (ws, req) => {
+ client.once('connection', (ws, req) => {
+ try {
ws.should.not.be.empty;
req.connection.remoteAddress.should.not.be.empty;
+ } catch (e) {
+ reject(e);
+ }
});
- client.on('message', (data) => {
- data.should.eql(WS_DATA);
+ client.once('message', (data) => {
+ const dataStr = _.isString(data) ? data : data.toString();
+ dataStr.should.eql(WS_DATA);
resolve();
});
- client.on('error', reject);
+ client.once('error', reject);
setTimeout(() => reject(new Error('No websocket messages have been received after the timeout')),
timeout);
});

chore(base-driver): Update ws dependency (#16739)