GUAC-561: Close tunnel with timeout error code if data not received from server.

This commit is contained in:
Michael Jumper
2014-03-23 12:48:07 -07:00
parent 03dbfa088e
commit 5ad6d77ef6

View File

@@ -63,6 +63,15 @@ Guacamole.Tunnel = function() {
*/ */
this.state = Guacamole.Tunnel.State.CONNECTING; this.state = Guacamole.Tunnel.State.CONNECTING;
/**
* The maximum amount of time to wait for data to be received, in
* milliseconds. If data is not received within this amount of time,
* the tunnel is closed with an error. The default value is 15000.
*
* @type Number
*/
this.receiveTimeout = 15000;
/** /**
* Fired whenever an error is encountered by the tunnel. * Fired whenever an error is encountered by the tunnel.
* *
@@ -153,6 +162,30 @@ Guacamole.HTTPTunnel = function(tunnelURL) {
var sendingMessages = false; var sendingMessages = false;
var outputMessageBuffer = ""; var outputMessageBuffer = "";
/**
* The current receive timeout ID, if any.
* @private
*/
var receive_timeout = null;
/**
* Initiates a timeout which, if data is not received, causes the tunnel
* to close with an error.
*
* @private
*/
function reset_timeout() {
// Get rid of old timeout (if any)
window.clearTimeout(receive_timeout);
// Set new timeout
receive_timeout = window.setTimeout(function () {
close_tunnel(new Guacamole.Status(Guacamole.Status.Code.UPSTREAM_TIMEOUT, "Server timeout."));
}, tunnel.receiveTimeout);
}
/** /**
* Closes this tunnel, signaling the given status and corresponding * Closes this tunnel, signaling the given status and corresponding
* message, which will be sent to the onerror handler if the status is * message, which will be sent to the onerror handler if the status is
@@ -322,6 +355,8 @@ Guacamole.HTTPTunnel = function(tunnelURL) {
if (xmlhttprequest.readyState === 3 || if (xmlhttprequest.readyState === 3 ||
xmlhttprequest.readyState === 4) { xmlhttprequest.readyState === 4) {
reset_timeout();
// Also poll every 30ms (some browsers don't repeatedly call onreadystatechange for new data) // Also poll every 30ms (some browsers don't repeatedly call onreadystatechange for new data)
if (pollingMode === POLLING_ENABLED) { if (pollingMode === POLLING_ENABLED) {
if (xmlhttprequest.readyState === 3 && !interval) if (xmlhttprequest.readyState === 3 && !interval)
@@ -477,6 +512,9 @@ Guacamole.HTTPTunnel = function(tunnelURL) {
this.connect = function(data) { this.connect = function(data) {
// Start waiting for connect
reset_timeout();
// Start tunnel and connect // Start tunnel and connect
var connect_xmlhttprequest = new XMLHttpRequest(); var connect_xmlhttprequest = new XMLHttpRequest();
connect_xmlhttprequest.onreadystatechange = function() { connect_xmlhttprequest.onreadystatechange = function() {
@@ -490,6 +528,8 @@ Guacamole.HTTPTunnel = function(tunnelURL) {
return; return;
} }
reset_timeout();
// Get UUID from response // Get UUID from response
tunnel_uuid = connect_xmlhttprequest.responseText; tunnel_uuid = connect_xmlhttprequest.responseText;
@@ -537,6 +577,12 @@ Guacamole.WebSocketTunnel = function(tunnelURL) {
*/ */
var socket = null; var socket = null;
/**
* The current receive timeout ID, if any.
* @private
*/
var receive_timeout = null;
/** /**
* The WebSocket protocol corresponding to the protocol used for the current * The WebSocket protocol corresponding to the protocol used for the current
* location. * location.
@@ -580,6 +626,24 @@ Guacamole.WebSocketTunnel = function(tunnelURL) {
} }
/**
* Initiates a timeout which, if data is not received, causes the tunnel
* to close with an error.
*
* @private
*/
function reset_timeout() {
// Get rid of old timeout (if any)
window.clearTimeout(receive_timeout);
// Set new timeout
receive_timeout = window.setTimeout(function () {
close_tunnel(new Guacamole.Status(Guacamole.Status.Code.UPSTREAM_TIMEOUT, "Server timeout."));
}, tunnel.receiveTimeout);
}
/** /**
* Closes this tunnel, signaling the given status and corresponding * Closes this tunnel, signaling the given status and corresponding
* message, which will be sent to the onerror handler if the status is * message, which will be sent to the onerror handler if the status is
@@ -647,13 +711,19 @@ Guacamole.WebSocketTunnel = function(tunnelURL) {
this.connect = function(data) { this.connect = function(data) {
reset_timeout();
// Connect socket // Connect socket
socket = new WebSocket(tunnelURL + "?" + data, "guacamole"); socket = new WebSocket(tunnelURL + "?" + data, "guacamole");
socket.onopen = function(event) { socket.onopen = function(event) {
reset_timeout();
tunnel.state = Guacamole.Tunnel.State.OPEN; tunnel.state = Guacamole.Tunnel.State.OPEN;
if (tunnel.onstatechange) if (tunnel.onstatechange)
tunnel.onstatechange(tunnel.state); tunnel.onstatechange(tunnel.state);
}; };
socket.onclose = function(event) { socket.onclose = function(event) {
@@ -666,6 +736,8 @@ Guacamole.WebSocketTunnel = function(tunnelURL) {
socket.onmessage = function(event) { socket.onmessage = function(event) {
reset_timeout();
var message = event.data; var message = event.data;
var startIndex = 0; var startIndex = 0;
var elementEnd; var elementEnd;