From 57229a06c205fef550eeb73ce591d89c8f92edf6 Mon Sep 17 00:00:00 2001 From: Kostas Chatzikokolakis Date: Wed, 9 Sep 2015 20:30:00 +0200 Subject: [PATCH 1/5] inline test: check that data was actually received --- tests/unit.test.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/unit.test.js b/tests/unit.test.js index 932b3c1..2d3c974 100644 --- a/tests/unit.test.js +++ b/tests/unit.test.js @@ -136,11 +136,20 @@ module.exports = { httpserver.listen(port, function(){ server.listen(port + 1, httpserver, function(){ var client = net.createConnection(port); + var gotData = false; client.write('\0'); client.on('error', function(err){ assert.ok(!err, err) }); + client.on('end', function(){ + assert.ok(gotData, 'connection closed before sending data'); + + // clean up + server.close(); + httpserver.close(); + }); client.on('data', function(data){ + gotData = true; var response = data.toString(); console.log(response); @@ -149,10 +158,8 @@ module.exports = { response.indexOf('domain="*"').should.be.above(0); response.indexOf('domain="google.com"').should.equal(-1); - // clean up - client.destroy(); - server.close(); - httpserver.close(); + // cleanup done by the 'end' handler + client.end(); }); }); }); @@ -228,4 +235,4 @@ module.exports = { server.close(); }); } -}; \ No newline at end of file +}; From 689cf11845f7a94161e03756caf2a056a98c8880 Mon Sep 17 00:00:00 2001 From: Kostas Chatzikokolakis Date: Wed, 9 Sep 2015 19:09:18 +0200 Subject: [PATCH 2/5] ensure that the inline connection listener is executed first In some versions of node.js (tested with v0.12.7) the http.Server class closes the socket immediately when it sees that the request is not HTTP, before we manage to send the xml! So we need to make sure that our connection listener is executed _first_. To do so we remove them all and we re-add them. --- lib/server.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index 90b1883..c6e169b 100644 --- a/lib/server.js +++ b/lib/server.js @@ -123,7 +123,19 @@ Server.prototype.listen = function listen (port, server, cb){ }; // attach it - this.server.on('connection', this.server['@']); + // Note: in some versions of node.js (tested with v0.12.7) the http.Server + // class closes the socket immediately when it sees that the request is not + // HTTP, before we manage to send the xml! So we need to make sure that our + // connection listener is executed _first_. To do so we remove them all and + // we re-add them. + // + var listeners = this.server.listeners('connection'); + listeners.unshift(this.server['@']); + + this.server.removeAllListeners('connection'); + listeners.forEach(function(l) { + me.server.on('connection', l); + }); } // We add a callback method, so we can set a flag for when the server is `enabled` or `online`. From 12eae60bd7e1ee3b8fd9ebfe81cf660a4861854d Mon Sep 17 00:00:00 2001 From: Kostas Chatzikokolakis Date: Wed, 21 Oct 2015 14:22:43 +0200 Subject: [PATCH 3/5] support https for use with SecureSocket When SecureSocket is used, flash requests the policy file over the TLS encrypted socket. By passing an https server to policyfile we can answer such policy requests inline. --- lib/server.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/server.js b/lib/server.js index c6e169b..944c8f8 100644 --- a/lib/server.js +++ b/lib/server.js @@ -66,7 +66,8 @@ function Server (options, origins) { // Remove the inline policy listener if we close down // but only when the server was `online` (see listen prototype) if (me.server['@'] && me.server.online) { - me.server.removeListener('connection', me.server['@']); + var event = this.server.cert ? 'secureConnection' : 'connection'; + me.server.removeListener(event, me.server['@']); } // not online anymore @@ -129,12 +130,15 @@ Server.prototype.listen = function listen (port, server, cb){ // connection listener is executed _first_. To do so we remove them all and // we re-add them. // - var listeners = this.server.listeners('connection'); + // support both https ('secureConnection' event) and http ('connection' event) + // + var event = this.server.cert ? 'secureConnection' : 'connection'; + var listeners = this.server.listeners(event); listeners.unshift(this.server['@']); - this.server.removeAllListeners('connection'); + this.server.removeAllListeners(event); listeners.forEach(function(l) { - me.server.on('connection', l); + me.server.on(event, l); }); } From 151a41bb2b353cec4f8379b1256716baad4fed08 Mon Sep 17 00:00:00 2001 From: Kostas Chatzikokolakis Date: Fri, 30 Oct 2015 18:42:46 -0500 Subject: [PATCH 4/5] support for node v4.x For some reason the data event handler was not being called. We now do the trick of removing/inserting all handlers for the data event, instead of the connection event. --- lib/server.js | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/server.js b/lib/server.js index 944c8f8..cadce8a 100644 --- a/lib/server.js +++ b/lib/server.js @@ -107,7 +107,7 @@ Server.prototype.listen = function listen (port, server, cb){ // no one in their right mind would ever create a `@` prototype, so Im just gonna store // my function on the server, so I can remove it later again once the server(s) closes this.server['@'] = function connection (socket) { - socket.once('data', function requestData (data) { + function requestData (data) { // if it's a Flash policy request, and we can write to the if ( data @@ -120,26 +120,30 @@ Server.prototype.listen = function listen (port, server, cb){ try { socket.end(me.buffer); } catch (e) {} } + } + + // Note: in some versions of node.js (tested with v0.12.7) the http.Server + // class closes the socket immediately when it sees that the request is not + // HTTP, before we manage to send the xml! So we need to make sure that our + // data listener is executed _first_. To do so we remove them all and + // we re-add them. + // In node v0.12.7 this trick was done for the connection event, in v4.2.1 + // this was broken for some reason, but doing it for the data event works. + // + var listeners = socket.listeners('data'); + socket.removeAllListeners('data'); + socket.once('data', requestData); + + listeners.forEach(function(l) { + socket.on('data', l); }); }; // attach it - // Note: in some versions of node.js (tested with v0.12.7) the http.Server - // class closes the socket immediately when it sees that the request is not - // HTTP, before we manage to send the xml! So we need to make sure that our - // connection listener is executed _first_. To do so we remove them all and - // we re-add them. - // // support both https ('secureConnection' event) and http ('connection' event) // var event = this.server.cert ? 'secureConnection' : 'connection'; - var listeners = this.server.listeners(event); - listeners.unshift(this.server['@']); - - this.server.removeAllListeners(event); - listeners.forEach(function(l) { - me.server.on(event, l); - }); + this.server.on(event, this.server['@']); } // We add a callback method, so we can set a flag for when the server is `enabled` or `online`. From e4b0dca74c67bff2e780ffc2e106dadfc79972ec Mon Sep 17 00:00:00 2001 From: nowrap Date: Fri, 8 Dec 2017 21:53:38 +0100 Subject: [PATCH 5/5] Update server.js process.EventEmitter is deprecated. use require('events') instead --- lib/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index cadce8a..6a89c02 100644 --- a/lib/server.js +++ b/lib/server.js @@ -270,7 +270,7 @@ Server.prototype.close = function close () { * Proxy the event listener requests to the created Net server */ -Object.keys(process.EventEmitter.prototype).forEach(function proxy (key){ +Object.keys(require('events').prototype).forEach(function proxy (key){ Server.prototype[key] = Server.prototype[key] || function () { if (this.socket) { this.socket[key].apply(this.socket, arguments);