*
* ***** END LICENSE BLOCK ***** */
-// Guacamole namespace
+/**
+ * Namespace for all Guacamole JavaScript objects.
+ * @namespace
+ */
var Guacamole = Guacamole || {};
/**
/**
* Reference to this HTTP tunnel.
+ * @private
*/
var tunnel = this;
* Converts the given value to a length/string pair for use as an
* element in a Guacamole instruction.
*
+ * @private
* @param value The value to convert.
* @return {String} The converted value.
*/
// Once response received, send next queued event.
message_xmlhttprequest.onreadystatechange = function() {
- if (message_xmlhttprequest.readyState == 4)
- sendPendingMessages();
+ if (message_xmlhttprequest.readyState == 4) {
+
+ // If an error occurs during send, handle it
+ if (message_xmlhttprequest.status != 200)
+ handleHTTPTunnelError(message_xmlhttprequest);
+
+ // Otherwise, continue the send loop
+ else
+ sendPendingMessages();
+
+ }
}
message_xmlhttprequest.send(outputMessageBuffer);
}
+ function getHTTPTunnelErrorMessage(xmlhttprequest) {
+
+ var status = xmlhttprequest.status;
+
+ // Special cases
+ if (status == 0) return "Disconnected";
+ if (status == 200) return "Success";
+ if (status == 403) return "Unauthorized";
+ if (status == 404) return "Connection closed"; /* While it may be more
+ * accurate to say the
+ * connection does not
+ * exist, it is confusing
+ * to the user.
+ *
+ * In general, this error
+ * will only happen when
+ * the tunnel does not
+ * exist, which happens
+ * after the connection
+ * is closed and the
+ * tunnel is detached.
+ */
+ // Internal server errors
+ if (status >= 500 && status <= 599) return "Server error";
+
+ // Otherwise, unknown
+ return "Unknown error";
+
+ }
+
+ function handleHTTPTunnelError(xmlhttprequest) {
+
+ // Get error message
+ var message = getHTTPTunnelErrorMessage(xmlhttprequest);
+
+ // Call error handler
+ if (tunnel.onerror) tunnel.onerror(message);
+
+ // Finish
+ tunnel.disconnect();
+
+ }
+
function handleResponse(xmlhttprequest) {
// Halt on error during request
else if (xmlhttprequest.status != 200) {
-
- // Get error message (if any)
- var message = xmlhttprequest.getResponseHeader("X-Guacamole-Error-Message");
- if (!message)
- message = "Internal server error";
-
- // Call error handler
- if (tunnel.onerror) tunnel.onerror(message);
-
- // Finish
- tunnel.disconnect();
+ handleHTTPTunnelError(xmlhttprequest);
return;
}
// If failure, throw error
if (connect_xmlhttprequest.status != 200) {
-
- var message = connect_xmlhttprequest.getResponseHeader("X-Guacamole-Error-Message");
- if (!message)
- message = "Internal error";
-
+ var message = getHTTPTunnelErrorMessage(connect_xmlhttprequest);
throw new Error(message);
-
}
// Get UUID from response
/**
* Reference to this WebSocket tunnel.
+ * @private
*/
var tunnel = this;
/**
* The WebSocket used by this tunnel.
+ * @private
*/
var socket = null;
/**
* The WebSocket protocol corresponding to the protocol used for the current
* location.
+ * @private
*/
var ws_protocol = {
"http:": "ws:",
* Converts the given value to a length/string pair for use as an
* element in a Guacamole instruction.
*
+ * @private
* @param value The value to convert.
* @return {String} The converted value.
*/
/**
* Reference to this chained tunnel.
+ * @private
*/
var chained_tunnel = this;
/**
* The currently wrapped tunnel, if any.
+ * @private
*/
var current_tunnel = null;
/**
* Data passed in via connect(), to be used for
* wrapped calls to other tunnels' connect() functions.
+ * @private
*/
var connect_data;
/**
* Array of all tunnels passed to this ChainedTunnel through the
* constructor arguments.
+ * @private
*/
var tunnels = [];
tunnels.push(arguments[i]);
/**
- * Sets the current tunnel
+ * Sets the current tunnel.
+ *
+ * @private
+ * @param {Guacamole.Tunnel} tunnel The tunnel to set as the current tunnel.
*/
function attach(tunnel) {
+ // Clear handlers of current tunnel, if any
+ if (current_tunnel) {
+ current_tunnel.onerror = null;
+ current_tunnel.oninstruction = null;
+ }
+
// Set own functions to tunnel's functions
chained_tunnel.disconnect = tunnel.disconnect;
chained_tunnel.sendMessage = tunnel.sendMessage;
};
- // Attempt connection
- current_tunnel.connect(connect_data);
+ try {
+
+ // Attempt connection
+ current_tunnel.connect(connect_data);
+
+ }
+ catch (e) {
+
+ // Call error handler of current tunnel on error
+ current_tunnel.onerror(e.message);
+
+ }
+
}