GUACAMOLE-422: Implement protocol version support in the client.

This commit is contained in:
Virtually Nick
2019-03-30 17:24:26 -04:00
parent d3e00abab7
commit c5a7ab757f
2 changed files with 252 additions and 9 deletions

View File

@@ -19,7 +19,6 @@
package org.apache.guacamole.protocol; package org.apache.guacamole.protocol;
import java.util.List; import java.util.List;
import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.GuacamoleServerException;
@@ -56,6 +55,15 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket {
*/ */
private String id; private String id;
/**
* The protocol version that will be used to communicate with guacd. The
* default is 1.0.0, and, if the server does not provide a specific version
* it will be assumed that it operates at this version and certain features
* may be unavailable.
*/
private GuacamoleProtocolVersion protocol =
GuacamoleProtocolVersion.VERSION_1_0_0;
/** /**
* Waits for the instruction having the given opcode, returning that * Waits for the instruction having the given opcode, returning that
* instruction once it has been read. If the instruction is never read, * instruction once it has been read. If the instruction is never read,
@@ -137,6 +145,13 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket {
// Build args list off provided names and config // Build args list off provided names and config
List<String> arg_names = args.getArgs(); List<String> arg_names = args.getArgs();
// Check for protocol version as first argument
if (arg_names.get(0).startsWith("VERSION_")) {
String protocolArg = arg_names.get(0);
protocol = GuacamoleProtocolVersion.valueOf(protocolArg);
}
String[] arg_values = new String[arg_names.size()]; String[] arg_values = new String[arg_names.size()];
for (int i=0; i<arg_names.size(); i++) { for (int i=0; i<arg_names.size(); i++) {
@@ -185,14 +200,18 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket {
info.getImageMimetypes().toArray(new String[0]) info.getImageMimetypes().toArray(new String[0])
)); ));
// Send client timezone, if available // Protocol version 1.1.0 and higher options
String timezone = info.getTimezone();
if (timezone != null && !timezone.isEmpty()) { if (protocol.atLeast(GuacamoleProtocolVersion.VERSION_1_1_0)) {
writer.writeInstruction( // Send client timezone, if available
new GuacamoleInstruction( String timezone = info.getTimezone();
"timezone", if (timezone != null && !timezone.isEmpty()) {
info.getTimezone() writer.writeInstruction(
)); new GuacamoleInstruction(
"timezone",
info.getTimezone()
));
}
} }
// Send args // Send args

View File

@@ -0,0 +1,224 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.guacamole.protocol;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleUnsupportedException;
/**
* 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.
*/
public enum GuacamoleProtocolVersion {
VERSION_1_0_0("1.0.0", 1, 0, 0),
VERSION_1_1_0("1.1.0", 1, 1, 0);
// The string representation of the version.
private final String version;
// The major version number.
private final int major;
// The minor version number.
private final int minor;
// The patch version number.
private final int patch;
/**
* Generate a new GuacamoleProtocolVersion object with the given
* string version, major version, and minor version.
*
* @param version
* The String representation of the version.
*
* @param major
* The integer representation of the major version component.
*
* @param minor
* The integer representation of the minor version component.
*
* @param patch
* The integer representation of the patch version component.
*/
GuacamoleProtocolVersion(String version, int major, int minor, int patch) {
this.version = version;
this.major = major;
this.minor = minor;
this.patch = patch;
}
/**
* Return the string representation of the version.
*
* @return
* The string representation of the version.
*/
public String getVersion() {
return version;
}
/**
* Return the major version number.
*
* @return
* The integer major version.
*/
public int getMajor() {
return major;
}
/**
* Return the minor version number.
*
* @return
* The integer minor version.
*/
public int getMinor() {
return minor;
}
/**
* Return the patch version number.
* @return
* The integer patch version.
*/
public int getPatch() {
return patch;
}
/**
* Determines whether or not this object is greater than or equal to the
* the version passed in to the method. Returns a boolean true if the
* version is the same as or greater than the other version, otherwise
* false.
*
* @param otherVersion
* The version to which this object should be compared.
*
* @return
* True if this object is greater than or equal to the other version.
*/
public boolean atLeast(GuacamoleProtocolVersion otherVersion) {
// Major version is greater
if (major > otherVersion.getMajor())
return true;
// Major version is less than or equal to.
else {
// Major version is less than
if (major < otherVersion.getMajor())
return false;
// Major version is equal, minor version is greater
if (minor > otherVersion.getMinor())
return true;
// Minor version is less than or equal to.
else {
// Minor version is less than
if (minor < otherVersion.getMinor())
return false;
// Patch version is greater or equal
if (patch >= otherVersion.getPatch())
return true;
}
}
// Version is either less than or equal to.
return false;
}
/**
* Parses the given string version, returning the GuacamoleProtocolVersion
* object that matches the string version. If a matching version is not
* found an exception is thrown.
*
* @param version
* The String representation of a version to parse.
*
* @return
* The GuacamoleProtocolVersion that matches the string version
* that has been provided.
*
* @throws GuacamoleException
* If the string version does not match any known enum values.
*/
public static GuacamoleProtocolVersion parseVersion(String version)
throws GuacamoleException {
for (GuacamoleProtocolVersion v : GuacamoleProtocolVersion.values()) {
if (v.getVersion().equals(version))
return v;
}
throw new GuacamoleUnsupportedException("Version " + version
+ " of Guacamole protocol is not valid.");
}
/**
* Parse the version provided as individual version components to the
* matching enum version. If a match is not found an exception is
* thrown.
*
* @param major
* The integer major version.
*
* @param minor
* The integer minor version.
*
* @param patch
* The integer patch version.
*
* @return
* The GuacamoleProtocolVersion that matches the individual components
* that were provided.
*
* @throws GuacamoleException
* If the provided components do not match any known enum value.
*/
public static GuacamoleProtocolVersion parseVersion(int major, int minor, int patch)
throws GuacamoleException {
for (GuacamoleProtocolVersion v : GuacamoleProtocolVersion.values()) {
if (v.getMajor() == major
&& v.getMinor() == minor
&& v.getPatch() == patch)
return v;
}
throw new GuacamoleUnsupportedException("Version "
+ Integer.toString(major) + "."
+ Integer.toString(minor) + "."
+ Integer.toString(patch)
+ " is not valid.");
}
}