mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-44: Expose tunnel UUID to JavaScript. Document allowed internal use of the empty opcode.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,16 @@ import org.apache.guacamole.io.GuacamoleWriter;
|
||||
*/
|
||||
public interface GuacamoleTunnel {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
static final String INTERNAL_DATA_OPCODE = "";
|
||||
|
||||
/**
|
||||
* Acquires exclusive read access to the Guacamole instruction stream
|
||||
* and returns a GuacamoleReader for reading from that stream.
|
||||
|
@@ -36,6 +36,7 @@ import org.apache.guacamole.io.GuacamoleWriter;
|
||||
import org.apache.guacamole.net.GuacamoleTunnel;
|
||||
import org.apache.guacamole.GuacamoleClientException;
|
||||
import org.apache.guacamole.GuacamoleConnectionClosedException;
|
||||
import org.apache.guacamole.protocol.GuacamoleInstruction;
|
||||
import org.apache.guacamole.protocol.GuacamoleStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -149,6 +150,12 @@ public abstract class GuacamoleWebSocketTunnelEndpoint extends Endpoint {
|
||||
|
||||
try {
|
||||
|
||||
// Send tunnel UUID
|
||||
remote.sendText(new GuacamoleInstruction(
|
||||
GuacamoleTunnel.INTERNAL_DATA_OPCODE,
|
||||
tunnel.getUUID().toString()
|
||||
).toString());
|
||||
|
||||
try {
|
||||
|
||||
// Attempt to read
|
||||
|
@@ -124,10 +124,6 @@ public class TunnelRESTService {
|
||||
GuacamoleSession session = authenticationService.getGuacamoleSession(authToken);
|
||||
Map<String, StreamInterceptingTunnel> tunnels = session.getTunnels();
|
||||
|
||||
// STUB: For sake of testing, if only one tunnel exists, use that
|
||||
if (tunnels.size() == 1)
|
||||
tunnelUUID = tunnels.keySet().iterator().next();
|
||||
|
||||
// Pull tunnel with given UUID
|
||||
final StreamInterceptingTunnel tunnel = tunnels.get(tunnelUUID);
|
||||
if (tunnel == null)
|
||||
|
@@ -30,6 +30,7 @@ import org.eclipse.jetty.websocket.WebSocket.Connection;
|
||||
import org.eclipse.jetty.websocket.WebSocketServlet;
|
||||
import org.apache.guacamole.GuacamoleClientException;
|
||||
import org.apache.guacamole.GuacamoleConnectionClosedException;
|
||||
import org.apache.guacamole.protocol.GuacamoleInstruction;
|
||||
import org.apache.guacamole.tunnel.http.HTTPTunnelRequest;
|
||||
import org.apache.guacamole.tunnel.TunnelRequest;
|
||||
import org.apache.guacamole.protocol.GuacamoleStatus;
|
||||
@@ -136,6 +137,12 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet {
|
||||
|
||||
try {
|
||||
|
||||
// Send tunnel UUID
|
||||
connection.sendMessage(new GuacamoleInstruction(
|
||||
GuacamoleTunnel.INTERNAL_DATA_OPCODE,
|
||||
tunnel.getUUID().toString()
|
||||
).toString());
|
||||
|
||||
try {
|
||||
|
||||
// Attempt to read
|
||||
|
@@ -30,6 +30,7 @@ import org.apache.guacamole.GuacamoleException;
|
||||
import org.apache.guacamole.io.GuacamoleReader;
|
||||
import org.apache.guacamole.io.GuacamoleWriter;
|
||||
import org.apache.guacamole.net.GuacamoleTunnel;
|
||||
import org.apache.guacamole.protocol.GuacamoleInstruction;
|
||||
import org.apache.guacamole.protocol.GuacamoleStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -127,6 +128,12 @@ public abstract class GuacamoleWebSocketTunnelListener implements WebSocketListe
|
||||
|
||||
try {
|
||||
|
||||
// Send tunnel UUID
|
||||
remote.sendString(new GuacamoleInstruction(
|
||||
GuacamoleTunnel.INTERNAL_DATA_OPCODE,
|
||||
tunnel.getUUID().toString()
|
||||
).toString());
|
||||
|
||||
try {
|
||||
|
||||
// Attempt to read
|
||||
|
@@ -35,6 +35,7 @@ import org.apache.catalina.websocket.WebSocketServlet;
|
||||
import org.apache.catalina.websocket.WsOutbound;
|
||||
import org.apache.guacamole.GuacamoleClientException;
|
||||
import org.apache.guacamole.GuacamoleConnectionClosedException;
|
||||
import org.apache.guacamole.protocol.GuacamoleInstruction;
|
||||
import org.apache.guacamole.tunnel.http.HTTPTunnelRequest;
|
||||
import org.apache.guacamole.tunnel.TunnelRequest;
|
||||
import org.apache.guacamole.protocol.GuacamoleStatus;
|
||||
@@ -164,6 +165,12 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet {
|
||||
|
||||
try {
|
||||
|
||||
// Send tunnel UUID
|
||||
outbound.writeTextMessage(CharBuffer.wrap(new GuacamoleInstruction(
|
||||
GuacamoleTunnel.INTERNAL_DATA_OPCODE,
|
||||
tunnel.getUUID().toString()
|
||||
).toString()));
|
||||
|
||||
try {
|
||||
|
||||
// Attempt to read
|
||||
|
Reference in New Issue
Block a user