mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-05 20:57:40 +00:00
GUACAMOLE-422: Allow arbitrary protocol versions to be represented. Remove API-level assumption that protocol capabilities will have a minimum base version and remain present from that point forward.
This commit is contained in:
@@ -61,7 +61,7 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket {
|
||||
* it will be assumed that it operates at this version and certain features
|
||||
* may be unavailable.
|
||||
*/
|
||||
private GuacamoleProtocolVersion protocol =
|
||||
private GuacamoleProtocolVersion protocolVersion =
|
||||
GuacamoleProtocolVersion.VERSION_1_0_0;
|
||||
|
||||
/**
|
||||
@@ -151,11 +151,21 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket {
|
||||
// Retrieve argument name
|
||||
String arg_name = arg_names.get(i);
|
||||
|
||||
// Check for protocol version as first argument
|
||||
if (i == 0 && arg_name.startsWith("VERSION_")) {
|
||||
protocol = GuacamoleProtocolVersion.getVersion(arg_name);
|
||||
arg_values[i] = protocol.toString();
|
||||
continue;
|
||||
// Check for valid protocol version as first argument
|
||||
if (i == 0) {
|
||||
GuacamoleProtocolVersion version = GuacamoleProtocolVersion.parseVersion(arg_name);
|
||||
if (version != null) {
|
||||
|
||||
// Use the lowest common version supported
|
||||
if (version.atLeast(GuacamoleProtocolVersion.LATEST))
|
||||
version = GuacamoleProtocolVersion.LATEST;
|
||||
|
||||
// Respond with the version selected
|
||||
arg_values[i] = version.toString();
|
||||
protocolVersion = version;
|
||||
continue;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Get defined value for name
|
||||
@@ -200,17 +210,11 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket {
|
||||
info.getImageMimetypes().toArray(new String[0])
|
||||
));
|
||||
|
||||
// Check for support for timezone handshake
|
||||
if (protocol.isSupported(GuacamoleProtocolCapability.TIMEZONE_HANDSHAKE)) {
|
||||
// Send client timezone, if available
|
||||
// Send client timezone, if supported and available
|
||||
if (GuacamoleProtocolCapability.TIMEZONE_HANDSHAKE.isSupported(protocolVersion)) {
|
||||
String timezone = info.getTimezone();
|
||||
if (timezone != null) {
|
||||
writer.writeInstruction(
|
||||
new GuacamoleInstruction(
|
||||
"timezone",
|
||||
info.getTimezone()
|
||||
));
|
||||
}
|
||||
if (timezone != null)
|
||||
writer.writeInstruction(new GuacamoleInstruction("timezone", info.getTimezone()));
|
||||
}
|
||||
|
||||
// Send args
|
||||
|
@@ -59,19 +59,23 @@ public enum GuacamoleProtocolCapability {
|
||||
* The minimum required protocol version for supporting the
|
||||
* capability.
|
||||
*/
|
||||
GuacamoleProtocolCapability(GuacamoleProtocolVersion version) {
|
||||
private GuacamoleProtocolCapability(GuacamoleProtocolVersion version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the minimum protocol version required to support this
|
||||
* capability.
|
||||
*
|
||||
* Returns whether this capability is supported in the given Guacamole
|
||||
* protocol version.
|
||||
*
|
||||
* @param version
|
||||
* The Guacamole protocol version to check.
|
||||
*
|
||||
* @return
|
||||
* The minimum protocol version required to support this capability.
|
||||
* true if this capability is supported by the given protocol version,
|
||||
* false otherwise.
|
||||
*/
|
||||
public GuacamoleProtocolVersion getVersion() {
|
||||
return version;
|
||||
public boolean isSupported(GuacamoleProtocolVersion version) {
|
||||
return version.atLeast(this.version);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -23,11 +23,12 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* An enum that defines the available Guacamole protocol versions that can be
|
||||
* used between guacd and clients, and provides convenience methods for parsing
|
||||
* and comparing versions.
|
||||
* Representation of a Guacamole protocol version. Convenience methods are
|
||||
* provided for parsing and comparing versions, as is necessary when
|
||||
* determining the version of the Guacamole protocol common to guacd and a
|
||||
* client.
|
||||
*/
|
||||
public enum GuacamoleProtocolVersion {
|
||||
public class GuacamoleProtocolVersion {
|
||||
|
||||
/**
|
||||
* Protocol version 1.0.0 and older. Any client that doesn't explicitly
|
||||
@@ -36,14 +37,20 @@ public enum GuacamoleProtocolVersion {
|
||||
* lacks support for certain protocol-related features introduced in later
|
||||
* versions.
|
||||
*/
|
||||
VERSION_1_0_0(1, 0, 0),
|
||||
public static final GuacamoleProtocolVersion VERSION_1_0_0 = new GuacamoleProtocolVersion(1, 0, 0);
|
||||
|
||||
/**
|
||||
* Protocol version 1.1.0, which introduces Client-Server version
|
||||
* detection, arbitrary handshake instruction order, and support
|
||||
* for passing the client timezone to the server during the handshake.
|
||||
*/
|
||||
VERSION_1_1_0(1, 1, 0);
|
||||
public static final GuacamoleProtocolVersion VERSION_1_1_0 = new GuacamoleProtocolVersion(1, 1, 0);
|
||||
|
||||
/**
|
||||
* The most recent version of the Guacamole protocol at the time this
|
||||
* version of GuacamoleProtocolVersion was built.
|
||||
*/
|
||||
public static final GuacamoleProtocolVersion LATEST = VERSION_1_1_0;
|
||||
|
||||
/**
|
||||
* A regular expression that matches the VERSION_X_Y_Z pattern, where
|
||||
@@ -83,7 +90,7 @@ public enum GuacamoleProtocolVersion {
|
||||
* @param patch
|
||||
* The integer representation of the patch version component.
|
||||
*/
|
||||
GuacamoleProtocolVersion(int major, int minor, int patch) {
|
||||
public GuacamoleProtocolVersion(int major, int minor, int patch) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
@@ -131,7 +138,7 @@ public enum GuacamoleProtocolVersion {
|
||||
* @return
|
||||
* True if this object is greater than or equal to the other version.
|
||||
*/
|
||||
private boolean atLeast(GuacamoleProtocolVersion otherVersion) {
|
||||
public boolean atLeast(GuacamoleProtocolVersion otherVersion) {
|
||||
|
||||
// If major is not the same, return inequality
|
||||
if (major != otherVersion.getMajor())
|
||||
@@ -146,39 +153,6 @@ public enum GuacamoleProtocolVersion {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this version with the major, minor, and patch components
|
||||
* provided to the method, and determine if this version is compatible
|
||||
* with the provided version, returning a boolean true if it is compatible,
|
||||
* otherwise false. This version is compatible with the version specified
|
||||
* by the provided components if the major, minor, and patch components
|
||||
* are equivalent or less than those provided.
|
||||
*
|
||||
* @param major
|
||||
* The major version component to compare for compatibility.
|
||||
*
|
||||
* @param minor
|
||||
* The minor version component to compare for compatibility.
|
||||
*
|
||||
* @param patch
|
||||
* The patch version component to compare for compatibility.
|
||||
*
|
||||
* @return
|
||||
* True if this version is compatibility with the version components
|
||||
* provided, otherwise false.
|
||||
*/
|
||||
private boolean isCompatible(int major, int minor, int patch) {
|
||||
|
||||
if (this.major != major)
|
||||
return this.major < major;
|
||||
|
||||
if (this.minor != minor)
|
||||
return this.minor < minor;
|
||||
|
||||
return this.patch <= patch;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the String format of the version provided and return the
|
||||
* the enum value matching that version. If no value is provided, return
|
||||
@@ -191,60 +165,20 @@ public enum GuacamoleProtocolVersion {
|
||||
* The enum value that matches the specified version, VERSION_1_0_0
|
||||
* if no match is found, or null if no comparison version is provided.
|
||||
*/
|
||||
public static GuacamoleProtocolVersion getVersion(String version) {
|
||||
|
||||
// If nothing is passed in, return null
|
||||
if (version == null || version.isEmpty())
|
||||
return null;
|
||||
|
||||
// Check the string against the pattern matcher
|
||||
public static GuacamoleProtocolVersion parseVersion(String version) {
|
||||
|
||||
// Validate format of version string
|
||||
Matcher versionMatcher = VERSION_PATTERN.matcher(version);
|
||||
|
||||
// If there is no RegEx match, return null
|
||||
if (!versionMatcher.matches())
|
||||
return null;
|
||||
|
||||
try {
|
||||
// Try the valueOf function
|
||||
return valueOf(version);
|
||||
|
||||
}
|
||||
|
||||
// If nothing matches, find the closest compatible version.
|
||||
catch (IllegalArgumentException e) {
|
||||
int myMajor = Integer.parseInt(versionMatcher.group(1));
|
||||
int myMinor = Integer.parseInt(versionMatcher.group(2));
|
||||
int myPatch = Integer.parseInt(versionMatcher.group(3));
|
||||
|
||||
GuacamoleProtocolVersion myVersion = VERSION_1_0_0;
|
||||
|
||||
// Loop through possible versions, grabbing the latest compatible
|
||||
for (GuacamoleProtocolVersion v : values()) {
|
||||
if (v.isCompatible(myMajor, myMinor, myPatch))
|
||||
myVersion = v;
|
||||
}
|
||||
|
||||
return myVersion;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified capability is supported in the current
|
||||
* protocol version, otherwise false.
|
||||
*
|
||||
* @param capability
|
||||
* The protocol capability that is being checked for support.
|
||||
*
|
||||
* @return
|
||||
* True if the capability is supported in the current version,
|
||||
* otherwise false.
|
||||
*/
|
||||
public boolean isSupported(GuacamoleProtocolCapability capability) {
|
||||
|
||||
return atLeast(capability.getVersion());
|
||||
|
||||
// Parse version number from version string
|
||||
return new GuacamoleProtocolVersion(
|
||||
Integer.parseInt(versionMatcher.group(1)),
|
||||
Integer.parseInt(versionMatcher.group(2)),
|
||||
Integer.parseInt(versionMatcher.group(3))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user