From 4a3d6b2c0a67cd2e8cb0418b3e3fa383652e8b68 Mon Sep 17 00:00:00 2001 From: Chris Wiggins Date: Tue, 17 Sep 2013 14:53:19 +1200 Subject: [PATCH 1/5] Spelling fix --- lib/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client.js b/lib/client.js index 28ff071..daef385 100644 --- a/lib/client.js +++ b/lib/client.js @@ -127,7 +127,7 @@ Client.prototype.actualSend = function(packet, retry) { var packetToLog = { packet: packet, retry: retry }; if (that._closed) { - this.logger.warn(packetToLog, "tryint to send a packet to a disconnected client"); + this.logger.warn(packetToLog, "trying to send a packet to a disconnected client"); } else if (retry === 10) { this.logger.info(packetToLog, "could not deliver the message"); this.connection.emit("error", new Error("client not responding to acks")); From 94e1abde196174cc3b537a00a01c8e7ae98bbb40 Mon Sep 17 00:00:00 2001 From: Chris Wiggins Date: Tue, 17 Sep 2013 17:34:40 +1200 Subject: [PATCH 2/5] Remove unsubAndClose and move all those calls into the close method. Adjust all other functions to use close. --- lib/client.js | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/lib/client.js b/lib/client.js index daef385..a05fa83 100644 --- a/lib/client.js +++ b/lib/client.js @@ -69,7 +69,7 @@ Client.prototype._setup = function() { async.parallel(packet.unsubscriptions.map(that.unsubscribeMapTo.bind(that)), function(err) { if (err) { that.logger.warn(err); - that.unsubAndClose(); + that.close(); return; } client.unsuback({ @@ -80,12 +80,12 @@ Client.prototype._setup = function() { client.on("disconnect", function() { that.logger.debug("disconnect requested"); - that.unsubAndClose(); + that.close(); }); client.on("error", function(err) { that.logger.warn(err); - that.unsubAndClose(); + that.close(); }); client.on("close", function() { @@ -208,19 +208,6 @@ Client.prototype.unsubscribeMapTo = function(topic) { }; }; -/** - * Unsubscribes from everything and closing down. - * - * @api private - */ -Client.prototype.unsubAndClose = function(cb) { - var that = this; - this._closing = true; - async.parallel(Object.keys(that.subscriptions).map(that.unsubscribeMapTo.bind(that)), function() { - that.close(cb); - }); -}; - /** * Handle a connect packet, doing authentication. * @@ -374,7 +361,7 @@ Client.prototype.handleSubscribe = function(packet) { }; }), function(err) { if (err) { - that.unsubAndClose(); + that.close(); return; } @@ -401,7 +388,7 @@ Client.prototype.handleAuthorizePublish = function(err, success, packet) { var that = this; if (err || !success) { - that.unsubAndClose(); + that.close(); return; } @@ -443,7 +430,7 @@ Client.prototype.onClose = function() { this.server.emit("clientDisconnecting", that); - this.unsubAndClose(function() { + this.close(function() { if (that.will) { logger.info({ willTopic: that.will.topic }, "delivering last will"); that.server.ascoltatore.publish( @@ -488,13 +475,20 @@ Client.prototype.close = function(callback) { } }; - if (this._closed) { - cleanup(); - } else { - this.server.persistClient(this); - this.connection.stream.on("end", cleanup); - this.connection.stream.end(); - } + + that._closing = true; + async.parallel(Object.keys(that.subscriptions).map(that.unsubscribeMapTo.bind(that)), function() { + if (that._closed) { + cleanup(); + } else { + that.server.persistClient(that); + that.connection.stream.on("end", cleanup); + that.connection.stream.end(); + } + }); + + + }; module.exports = Client; From ec49f2f31f6aa8512bebe7bee2ea2078aba1209b Mon Sep 17 00:00:00 2001 From: Chris Wiggins Date: Tue, 17 Sep 2013 20:34:05 +1200 Subject: [PATCH 3/5] Only allow one clientId that is the same to be connected at once --- lib/client.js | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/client.js b/lib/client.js index a05fa83..64d5f37 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1,6 +1,7 @@ "use strict"; var async = require("async"); + var REGEXP = /(([^/])\/+$)|(([^/]))|(\/+(\/))/g; var rewriteTopic = function(topic) { return topic.replace(REGEXP, "$2$4$6"); @@ -253,15 +254,26 @@ Client.prototype.handleConnect = function(packet) { } that.clean = packet.clean; - - logger.info("client connected"); - - that.setUpTimer(); - client.connack({ - returnCode: 0 - }); - that.server.restoreClient(that); - that.server.emit("clientConnected", that); + + var completeConnection = function(){ + logger.info("client connected"); + + that.setUpTimer(); + + client.connack({ + returnCode: 0 + }); + + that.server.restoreClient(that); + that.server.emit("clientConnected", that); + }; + + if (that.id in that.server.clients){ + that.server.clients[that.id].close(completeConnection.bind(that)); + }else{ + completeConnection(); + } + }); }; From 8b80f5094834c34abeb8cd6d3da5f5308f32c31f Mon Sep 17 00:00:00 2001 From: Chris Wiggins Date: Wed, 18 Sep 2013 18:37:31 +1200 Subject: [PATCH 4/5] Add multiple clientId test --- test/abstract_server.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/abstract_server.js b/test/abstract_server.js index f364f12..4c43bc5 100644 --- a/test/abstract_server.js +++ b/test/abstract_server.js @@ -118,6 +118,32 @@ module.exports = function(moscaSettings, createConnection) { }); }); }); + + it("should close the first client if a second client with the same clientId connects", function(done){ + var d = donner(2, done); + var opts = buildOpts(), clientId = "123456789"; + opts.clientId = clientId; + async.waterfall([ + function(cb){ + buildAndConnect(d, opts, function(client1){ + //console.log("hi"); + cb(null, client1); + }); + }, + function(client1, cb){ + //console.log("h2i"); + buildAndConnect(d, opts, function(client2){ + //console.log("hi2"); + //console.log(client2); + //console.log('heh'); + expect(client1.stream.destroyed).to.eql(true); + client2.disconnect(); + }); + } + + ]); + + }); it("should close the connection after the keepalive interval", function(done) { buildClient(done, function(client) { From 70983892501443174b992fc8017358f1e09a9e63 Mon Sep 17 00:00:00 2001 From: Chris Wiggins Date: Wed, 18 Sep 2013 19:18:49 +1200 Subject: [PATCH 5/5] Fix for secure server instance. Remove console log output from testing the tester :-) --- test/abstract_server.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/test/abstract_server.js b/test/abstract_server.js index 4c43bc5..61bc5c9 100644 --- a/test/abstract_server.js +++ b/test/abstract_server.js @@ -126,23 +126,20 @@ module.exports = function(moscaSettings, createConnection) { async.waterfall([ function(cb){ buildAndConnect(d, opts, function(client1){ - //console.log("hi"); cb(null, client1); }); }, function(client1, cb){ - //console.log("h2i"); buildAndConnect(d, opts, function(client2){ - //console.log("hi2"); - //console.log(client2); - //console.log('heh'); - expect(client1.stream.destroyed).to.eql(true); + if(settings.secure === undefined){ + expect(client1.stream.destroyed).to.eql(true); + }else{ + expect(client1.stream._destroyed).to.eql(true); + } client2.disconnect(); }); - } - + } ]); - }); it("should close the connection after the keepalive interval", function(done) {