GUACAMOLE-44: Expose tunnel UUID to JavaScript. Document allowed internal use of the empty opcode.

This commit is contained in:
Michael Jumper
2016-04-13 18:09:34 -07:00
parent 12d35d4feb
commit d398509660
7 changed files with 77 additions and 16 deletions

View File

@@ -70,6 +70,14 @@ Guacamole.Tunnel = function() {
*/
this.receiveTimeout = 15000;
/**
* The UUID uniquely identifying this tunnel. If not yet known, this will
* be null.
*
* @type {String}
*/
this.uuid = null;
/**
* Fired whenever an error is encountered by the tunnel.
*
@@ -99,6 +107,18 @@ Guacamole.Tunnel = function() {
};
/**
* The Guacamole protocol instruction opcode reserved for arbitrary internal
* use by tunnel implementations. The value of this opcode is guaranteed to be
* the empty string (""). Tunnel implementations may use this opcode for any
* purpose. It is currently used by the HTTP tunnel to mark the end of the HTTP
* response, and by the WebSocket tunnel to transmit the tunnel UUID.
*
* @constant
* @type {String}
*/
Guacamole.Tunnel.INTERNAL_DATA_OPCODE = '';
/**
* All possible tunnel states.
*/
@@ -152,8 +172,6 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain) {
*/
var tunnel = this;
var tunnel_uuid;
var TUNNEL_CONNECT = tunnelURL + "?connect";
var TUNNEL_READ = tunnelURL + "?read:";
var TUNNEL_WRITE = tunnelURL + "?write:";
@@ -286,7 +304,7 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain) {
sendingMessages = true;
var message_xmlhttprequest = new XMLHttpRequest();
message_xmlhttprequest.open("POST", TUNNEL_WRITE + tunnel_uuid);
message_xmlhttprequest.open("POST", TUNNEL_WRITE + tunnel.uuid);
message_xmlhttprequest.withCredentials = withCredentials;
message_xmlhttprequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
@@ -517,7 +535,7 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain) {
// Make request, increment request ID
var xmlhttprequest = new XMLHttpRequest();
xmlhttprequest.open("GET", TUNNEL_READ + tunnel_uuid + ":" + (request_id++));
xmlhttprequest.open("GET", TUNNEL_READ + tunnel.uuid + ":" + (request_id++));
xmlhttprequest.withCredentials = withCredentials;
xmlhttprequest.send(null);
@@ -546,7 +564,7 @@ Guacamole.HTTPTunnel = function(tunnelURL, crossDomain) {
reset_timeout();
// Get UUID from response
tunnel_uuid = connect_xmlhttprequest.responseText;
tunnel.uuid = connect_xmlhttprequest.responseText;
tunnel.state = Guacamole.Tunnel.State.OPEN;
if (tunnel.onstatechange)
@@ -733,13 +751,7 @@ Guacamole.WebSocketTunnel = function(tunnelURL) {
socket = new WebSocket(tunnelURL + "?" + data, "guacamole");
socket.onopen = function(event) {
reset_timeout();
tunnel.state = Guacamole.Tunnel.State.OPEN;
if (tunnel.onstatechange)
tunnel.onstatechange(tunnel.state);
};
socket.onclose = function(event) {
@@ -794,8 +806,22 @@ Guacamole.WebSocketTunnel = function(tunnelURL) {
// Get opcode
var opcode = elements.shift();
// Update state and UUID when first instruction received
if (tunnel.state !== Guacamole.Tunnel.State.OPEN) {
// Associate tunnel UUID if received
if (opcode === Guacamole.Tunnel.INTERNAL_DATA_OPCODE)
tunnel.uuid = elements[0];
// Tunnel is now open and UUID is available
tunnel.state = Guacamole.Tunnel.State.OPEN;
if (tunnel.onstatechange)
tunnel.onstatechange(tunnel.state);
}
// Call instruction handler.
if (tunnel.oninstruction)
if (opcode !== Guacamole.Tunnel.INTERNAL_DATA_OPCODE && tunnel.oninstruction)
tunnel.oninstruction(opcode, elements);
// Clear elements
@@ -926,6 +952,7 @@ Guacamole.ChainedTunnel = function(tunnelChain) {
tunnel.onstatechange = chained_tunnel.onstatechange;
tunnel.oninstruction = chained_tunnel.oninstruction;
tunnel.onerror = chained_tunnel.onerror;
chained_tunnel.uuid = tunnel.uuid;
committedTunnel = tunnel;
}