Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -106,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
Expand All @@ -119,11 +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
this.server.on('connection', this.server['@']);
// support both https ('secureConnection' event) and http ('connection' event)
//
var event = this.server.cert ? 'secureConnection' : 'connection';
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`.
Expand Down Expand Up @@ -250,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);
Expand Down
17 changes: 12 additions & 5 deletions tests/unit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<policy-file-request/>\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);
Expand All @@ -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();
});
});
});
Expand Down Expand Up @@ -228,4 +235,4 @@ module.exports = {
server.close();
});
}
};
};