Reusing TCP connection on Node.js HTTP Server

I am using a http.Serverobject of the default http module (-> API).

If a client connects the request event is emmited by the server and a http.ServerRequestobject is passed to the event handler. That request object emits the following three events:

  • data (incoming data)
  • end (request ended)
  • close (connection closed)

I want to keep the initial (TCP) connection of the client and reuse it for several requests. The client supports this behaviour as it sends the "Connection: keep-alive" header.

But how do I realize this using node.js? My problem is that after the first request the end event is emitted, and just like the official API says about that event:

Emitted exactly once for each request. After that, no more 'data' events will be emitted on the request.

OK, I can't use that request. But is there any way to work on the same TCP connection and create a new request on it?

Background: I am working on a proxy implementation. If the user accesses a website that uses NTLM I have to stick to one connection for at least the three client requests that are required for that type of authentication to not run into this problem.

Do you have any idea what I might try?

Thanks in advance!

When I run this code with node v6.17 it suggests keep alive is not working

function notifyNotKeptAlive(httpObject, eventName, httpObjectName){
    httpObject.on(eventName, function(socket){
        socket.on('close', function(){
                console.log("Yeeouch !  "+httpObjectName+" connection was not kept alive!");
        });
    });
}
var http=require('http');
var count=1;
var srv = http.createServer(function (req, res) {
    var secs;
    if ( (count%2)==1){secs=3;}
    else {secs=1;}
    console.log("Got http request #"+count+" so server waits "+secs+" seconds to respond");
    var countForThisClosure=count;
    setTimeout(function(){
        console.log("Waking up from sleep of "+secs);
        res.writeHead(200, {'Content-Type': 'text/plain'});
        if (secs===3){
            res.end('Visit #'+countForThisClosure+' costing a wait of '+secs+' seconds !!');
        } else {
            res.end('Visit #'+countForThisClosure+' costing a wait of '+secs+' seconds !!');
        }
    }, secs*1000);
    count++;
}).listen(8090);

notifyNotKeptAlive(srv, 'connection', 'http server');

for (var i=0;i<2;i++){
    var req=http.request( {'host': 'localhost', 'port':8090}, function (res) {
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            console.log('INCOMING <---' + chunk);
        });
        }
    );
    notifyNotKeptAlive(req, 'socket', 'http client');
    req.end();
}

IT only worked when I added an exclamation mark to line 1263 of the http lib source that Epeli helpfully supplied. Thus the line below that reads "if (req.shouldKeepAlive){" should instead read "if (! req.shouldKeepALive){" res.on('end', function() {

if (req.shouldKeepAlive) {
      socket.removeListener('close', closeListener);
      socket.removeListener('error', errorListener);
      socket.emit('free');
    }
  });

This line is within the on 'end' callback that is set within the ClientRequest.prototype.onSocket closure that starts on line 1113.

The link to this http lib source is (the same as Epeli's) https://github.com/joyent/node/blob/e8067cb68563e3f3ab760e3ce8d0aeb873198f36/lib/http.js#L889