From 8a48eb3f947cf2dc5154610ace59df2db85d2ff3 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 23 Mar 2018 18:44:33 +0100 Subject: [PATCH] Tune prefix handling for web socket pathnames (#198) --- index.js | 4 ++++ lib/express/websocket.js | 15 ++++++++------- test/basedriver/websockets-e2e-specs.js | 11 ++++++----- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index 477be51c5..d8578aa89 100644 --- a/index.js +++ b/index.js @@ -34,3 +34,7 @@ export { statusCodes, getSummaryByCode }; // W3C capabilities parser import { processCapabilities } from './lib/basedriver/capabilities'; export { processCapabilities }; + +// Web socket helpers +import { DEFAULT_WS_PATHNAME_PREFIX } from './lib/express/websocket'; +export { DEFAULT_WS_PATHNAME_PREFIX }; diff --git a/lib/express/websocket.js b/lib/express/websocket.js index a3fe8998d..25f964c96 100644 --- a/lib/express/websocket.js +++ b/lib/express/websocket.js @@ -1,7 +1,7 @@ import _ from 'lodash'; import url from 'url'; -const PATHNAME_PREFIX = '/ws'; +const DEFAULT_WS_PATHNAME_PREFIX = '/ws'; /** @@ -11,14 +11,13 @@ const PATHNAME_PREFIX = '/ws'; * * @param {Object} server - An instance of express HTTP server. * @param {string} handlerPathname - Web socket endpoint path starting with - * single slash charcter. `/wd/ws` prefix is automatically added to the - * actual endpoint. + * a single slash character. It is recommended to always add + * DEFAULT_WS_PATHNAME_PREFIX to all web socket pathnames. * @param {Object} handlerServer - WebSocket server instance. See * https://github.com/websockets/ws/pull/885 for more details * on how to configure the handler properly. - * @param {?string} pathnamePrefix ['/ws'] - Pathname prefix. */ -async function addWebSocketHandler (handlerPathname, handlerServer, pathnamePrefix = PATHNAME_PREFIX) { +async function addWebSocketHandler (handlerPathname, handlerServer) { let isUpgradeListenerAssigned = true; if (_.isUndefined(this.webSocketsMapping)) { this.webSocketsMapping = {}; @@ -33,7 +32,7 @@ async function addWebSocketHandler (handlerPathname, handlerServer, pathnamePref this.on('upgrade', (request, socket, head) => { const currentPathname = url.parse(request.url).pathname; for (const [pathname, wsServer] of _.toPairs(this.webSocketsMapping)) { - if (currentPathname === (_.isEmpty(pathnamePrefix) ? pathname : `${pathnamePrefix}${pathname}`)) { + if (currentPathname === pathname) { wsServer.handleUpgrade(request, socket, head, (ws) => { wsServer.emit('connection', ws); }); @@ -114,4 +113,6 @@ async function removeAllWebSocketHandlers () { return result; } -export { addWebSocketHandler, removeWebSocketHandler, removeAllWebSocketHandlers, getWebSocketHandlers }; +export { addWebSocketHandler, removeWebSocketHandler, + removeAllWebSocketHandlers, getWebSocketHandlers, + DEFAULT_WS_PATHNAME_PREFIX }; diff --git a/test/basedriver/websockets-e2e-specs.js b/test/basedriver/websockets-e2e-specs.js index 1f51c33ec..cefe5697e 100644 --- a/test/basedriver/websockets-e2e-specs.js +++ b/test/basedriver/websockets-e2e-specs.js @@ -1,5 +1,6 @@ import _ from 'lodash'; -import { server, routeConfiguringFunction} from '../..'; +import { server, routeConfiguringFunction, + DEFAULT_WS_PATHNAME_PREFIX } from '../..'; import { FakeDriver } from '../protocol/fake-driver'; import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; @@ -35,13 +36,13 @@ describe('Websockets (e2e)', function () { } }); const previousListenerCount = baseServer.listenerCount('upgrade'); - const endpoint = '/hello'; - const timeout = 5000; + const endpoint = `${DEFAULT_WS_PATHNAME_PREFIX}/hello`; + const timeout = 5000; await baseServer.addWebSocketHandler(endpoint, wss); baseServer.listenerCount('upgrade').should.be.above(previousListenerCount); _.keys(await baseServer.getWebSocketHandlers()).length.should.eql(1); await new B((resolve, reject) => { - const client = new WebSocket(`ws://localhost:${PORT}/ws${endpoint}`); + const client = new WebSocket(`ws://localhost:${PORT}${endpoint}`); client.on('message', (data) => { data.should.eql(WS_DATA); resolve(); @@ -54,7 +55,7 @@ describe('Websockets (e2e)', function () { (await baseServer.removeWebSocketHandler(endpoint)).should.be.true; _.keys(await baseServer.getWebSocketHandlers()).length.should.eql(0); await new B((resolve, reject) => { - const client = new WebSocket(`ws://localhost:${PORT}/ws${endpoint}`); + const client = new WebSocket(`ws://localhost:${PORT}${endpoint}`); client.on('message', (data) => reject(new Error(`No websocket messages are expected after the handler ` + `has been removed. '${data}' is received instead. `))