From 97521bbfebcdb40110416b65e0ff4a4d2e759b91 Mon Sep 17 00:00:00 2001 From: KLuka Date: Thu, 5 Mar 2015 18:34:21 +0100 Subject: [PATCH] Issue #275: gracefully manage HTTP time-outs and connection problems Patch reference: e69132f3762bd57a328dfc40b645d670d651afe7 Patch message: When connecting to shellinabox through an HTTP Proxy, we need to be careful in holding the HTTP/S connection with unbound pending HTTP-POST as they would occupy one thread in the outbound proxy. We do need to make sure that: - HTTP POST will graceful time-out from the client side, if no data is returned by the server in 30s (gives the impression to the HTTP Proxy that the "page load" is completed after tha time and then would release the thread) - In case of connection errors, the browser doesn't retry with a short loop but waits 1s before trying again. This prevent the browser freezing and the CPU looping. --- shellinabox/shell_in_a_box.jspp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/shellinabox/shell_in_a_box.jspp b/shellinabox/shell_in_a_box.jspp index de7e5be..5b3825a 100644 --- a/shellinabox/shell_in_a_box.jspp +++ b/shellinabox/shell_in_a_box.jspp @@ -164,6 +164,7 @@ ShellInABox.prototype.sendRequest = function(request) { request = new XMLHttpRequest(); } request.open('POST', this.url + '?', true); + request.timeout = 30000; // Don't leave POST pending forever: force 30s timeout to prevent HTTP Proxy thread hijack request.setRequestHeader('Cache-Control', 'no-cache'); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); @@ -202,8 +203,12 @@ ShellInABox.prototype.onReadyStateChange = function(request) { this.sendRequest(request); } } else if (request.status == 0) { - // Time Out - this.sendRequest(request); + // Time Out or other connection problems: retry after 1s to prevent release CPU before retry + setTimeout(function(shellInABox) { + return function() { + shellInABox.sendRequest(); + }; + }(this), 1000); } else { this.sessionClosed(); }