From dab2b14e89ee0105d56a3f426c207654f1b144b4 Mon Sep 17 00:00:00 2001 From: Dave Kelsey Date: Thu, 6 Dec 2018 14:44:59 +0000 Subject: [PATCH] [0.19.x] Rest server can be terminated by client (#4531) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A client listening on a web socket can terminate the rest server if it is badly behaved and doesn’t cleanly disconnect Signed-off-by: Dave Kelsey --- .../composer-rest-server/server/server.js | 8 +++++++ .../test/server/server.js | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/composer-rest-server/server/server.js b/packages/composer-rest-server/server/server.js index 98442c25fa..e1dd91a5e4 100755 --- a/packages/composer-rest-server/server/server.js +++ b/packages/composer-rest-server/server/server.js @@ -192,6 +192,14 @@ module.exports = function (composer) { clientTracking: true }); + // Add a dummy error handler for a ws connection so bad websocket client + // doesn't kill the rest server + wss.on('connection', (ws) => { + ws.on('error', () => { + // do nothing + }); + }); + // Add a broadcast method that sends data to all connected clients. wss.broadcast = (data) => { wss.clients.forEach((client) => { diff --git a/packages/composer-rest-server/test/server/server.js b/packages/composer-rest-server/test/server/server.js index 23c8b30a43..f4d3eebe03 100644 --- a/packages/composer-rest-server/test/server/server.js +++ b/packages/composer-rest-server/test/server/server.js @@ -23,6 +23,7 @@ const IdCard = require('composer-common').IdCard; const path = require('path'); const server = require('../../server/server'); const WebSocket = require('ws'); +const EventEmitter = require('events'); const chai = require('chai'); const should = chai.should(); @@ -341,4 +342,25 @@ describe('server', () => { }); }); + it('should register an error handler on connection to a websocket and it shoud no nothing when fired', () => { + composerConfig.websockets = true; + const stubWS = new EventEmitter(); + const wsOnSpy = sinon.spy(stubWS, 'on'); + + + return server(composerConfig) + .then((result) => { + result.app.should.exist; + result.server.should.exist; + const wss = result.app.get('wss'); + wss.should.be.an.instanceOf(WebSocket.Server); + wss.emit('connection', stubWS); + sinon.assert.calledOnce(wsOnSpy); + sinon.assert.calledWith(wsOnSpy, 'error'); + + // fire the error event + stubWS.emit('error'); + }); + }); + });