joyent/node — Issue #2453: http ServerResponse is not cleaned up after aborted ServerRequest
Author: tomlanyon
Created: 2012-01-03 02:08:00+00:00
State: open

The attached server.js test case pipes a fs readStream to the http ServerResponse. However, if the HTTP connection is aborted before the response is sent (e.g. due to broken client or bad network connectivity) the readStream is never closed and the process leaks filehandles; this eventually results in an EMFILE as the process runs out of available filehandles to use.

Included below is a client.js test case which can reproduce this behaviour.

// server.js
var count = 0;
require('http').createServer(function(req,res){
console.log('request ' + ++count);

res.writeHead(200);
var file = require('fs').createReadStream('/bin/echo');
file.pipe(res);
}).listen('3000');

// client.js
var count = 0;
var options = { host: '127.0.0.1', port: 3000, agent: false };

function sendReq(){
var req = require('http').get( options, function(res){
console.log( 'received response.' );
}).on( 'drain', function(){
console.log('aborting connection');
req.abort();
}).on( 'error', function(){
console.log('sending request ' + ++count);
sendReq();
});
}
sendReq();

From looking at node's lib/http.js it appears as though both the ServerRequest and ServerResponse objects are not cleaned up automatically when the underlying socket is aborted. Potential solution would be to have node automatically .end() the ServerRequest and ServerResponse upon premature socket failure.