From 1b1d75b750529daa587563a25089ef79ae5bc51a Mon Sep 17 00:00:00 2001 From: Roman Shtylman Date: Tue, 22 Apr 2014 20:34:13 -0400 Subject: [PATCH] detect when http client request is finished and close connection If the request is finished before we need to respond, we set a flag and close the connection. We also close the connection when the request finishes anyway because we really like a new connection for each request. Things play nicer with bouncy that way. --- package.json | 3 ++- server.js | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 2bfc8e1..f726576 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "superstack": "0.0.4", "stylish": "0.4.1", "makeover": "0.0.1", - "tldjs": "1.3.1" + "tldjs": "1.3.1", + "finished": "1.1.2" }, "devDependencies": { "mocha": "1.18.2", diff --git a/server.js b/server.js index 957f8a5..ed96e86 100644 --- a/server.js +++ b/server.js @@ -9,6 +9,7 @@ var makeup = require('makeup'); var engine = require('engine.io'); var browserkthx = require('browserkthx'); var tldjs = require('tldjs'); +var on_finished = require('finished'); var debug = require('debug')('localtunnel-server'); var Proxy = require('./proxy'); @@ -44,11 +45,26 @@ function maybe_bounce(req, res, bounce) { if (!client) { res.statusCode = 502; res.end('localtunnel error: no active client for \'' + client_id + '\''); + req.connection.destroy(); return true; } + var finished = false; + on_finished(res, function(err) { + if (err) { + return log.error(err); + } + finished = true; + req.connection.destroy(); + }); + // get client port client.next_socket(function(socket, done) { + // the request already finished or client disconnected + if (finished) { + return done(); + } + // happens when client upstream is disconnected // we gracefully inform the user and kill their conn // without this, the browser will leave some connections open @@ -64,6 +80,7 @@ function maybe_bounce(req, res, bounce) { var stream = bounce(socket, { headers: { connection: 'close' } }); stream.on('error', function(err) { + log.error(err); socket.destroy(); });