You are on page 1of 4

12/6/2015

Chapter14.guacamolecommon

Chapter14.guacamolecommon
TheJavaAPIprovidedbytheGuacamoleprojectiscalledguacamolecommon.Itprovidesabasicmeansof
tunneling data between the JavaScript client provided by guacamolecommonjs and the native proxy
daemon,guacd.ThereareotherclassesprovidedaswellwhichmakedealingwiththeGuacamoleprotocol
andreadingfromguacamole.propertieseasier,butingeneral,thepurposeofthislibraryistofacilitatethe
creationofcustomtunnelsbetweentheJavaScriptclientandguacd.

HTTPtunnel
The Guacamole Java API implements the HTTP tunnel using a servlet called
GuacamoleHTTPTunnelServlet. This servlet handles all requests coming to it over HTTP from the
JavaScriptclient,andtranslatedthemintoconnect,read,orwriterequests,whicheachgetdispatchedtothe
doConnect(),doRead(),anddoWrite()functionsaccordingly.
Normally,youwouldn'ttouchthedoRead()anddoWrite()functions,asthesehavealreadybeenwrittento
properlyhandletherequestsoftheJavaScripttunnel,andifyoufeeltheneedtotouchthesefunctions,you
are probably better off writing your own tunnel implementation, although such a thing is difficult to do in a
performantway.
When developing an application based on the Guacamole API, you should use
GuacamoleHTTPTunnelServlet by extending it, implementing your own version of doConnect(), which is
theonlyabstractfunctionitdefines.ThetutoriallaterinthisbookdemonstratinghowtowriteaGuacamole
basedwebapplicationshowsthebasicsofdoingthis,butgenerally,doConnect()isan excellent place for
authenticationorothervalidation,asitistheresponsibilityofdoConnect()tocreate(ornotcreate)theactual
tunnel.IfdoConnect()doesnotcreatethetunnel,communicationbetweentheJavaScriptclientandguacd
cannottakeplace,whichisanidealpowertohaveasanauthenticator.
ThedoConnect() function is expected to "attach" a GuacamoleTunnel to the web session, abstracted by
GuacamoleSession. Attaching a tunnel to the session allows future tunnel requests to retrieve the same
tunnelanduseit,thusallowingonetunneltobesplitacrossmultiplerequests.AssumingthedoConnect()
function successfully creates the tunnel, it must then return the created tunnel. The alreadyimplemented
parts of GuacamoleHTTPTunnelServlet then return the unique identifier of this tunnel to the JavaScript
client,allowingitsowntunnelimplementationtocontinuetocommunicatewiththetunnelexistingontheJava
side.
Instances of GuacamoleTunnel are created associated with a GuacamoleSocket, which is the abstract
interfacesurroundingthelowlevelconnectiontoguacd.Overall,thereisasocket(GuacamoleSocket)which
providesaTCPconnectiontoguacd.ThissocketisexposedtoGuacamoleTunnel,whichprovidesabstract
protocolaccessaroundwhatisactually(butsecretly,throughtheabstractionoftheAPI)aTCPsocket.The
GuacamoleSession allows instances of GuacamoleTunnel to be shared across requests, and
GuacamoleHTTPTunnelServletpullsthesetunnelsfromthesessionasnecessarytofulfillrequestsmadeby
theJavaScriptclient.
TheGuacamolewebapplicationextendsthistunnelservletinordertoimplementauthenticationatthelowest
possiblelevel,effectivelyprohibitingcommunicationbetweentheclientandanyremotedesktopsunlessthey
have properly authenticated. Your own implementation can be considerably simpler, especially if you don't
needauthentication:
publicclassMyGuacamoleTunnelServlet
extendsGuacamoleHTTPTunnelServlet{
@Override
protectedGuacamoleTunneldoConnect(HttpServletRequestrequest)
throwsGuacamoleException{
http://guacdev.org/doc/gug/guacamolecommon.html

1/4

12/6/2015

Chapter14.guacamolecommon

//Connecttoguacdhere(thisisaSTUB)
GuacamoleSocketsocket;
//Establishthetunnelusingtheconnectedsocket
GuacamoleTunneltunnel=newGuacamoleTunnel(socket);
//Attachtunneltosession
GuacamoleSessionsession=newGuacamoleSession(httpSession);
session.attachTunnel(tunnel);
//Returnpreattachedtunnel
returntunnel;
}
}

UsingtheGuacamoleprotocol
guacamolecommon provides basic lowlevel support for the Guacamole protocol. This lowlevel support is
leveraged by the HTTP tunnel implementation to satisfy the requirements of the JavaScript client
implementation,astheJavaScriptclientexpectsthehandshakeproceduretohavealreadytakenplace.This
support exists through the GuacamoleReader and GuacamoleWriter classes, which are similar to Java's
ReaderandWriterclasses,exceptthattheydealwiththeGuacamoleprotocolspecifically,andthushave
slightlydifferentcontracts.

GuacamoleReader
GuacamoleReaderprovidesaverybasicread()functionwhichisrequiredtoreturnoneormorecomplete
instructions in a char array. It also provides the typical available() function, which informs you whether
read() is likely to block the next time it is called, and an even more abstract version of read() called
readInstruction() which returns one instruction at a time, wrapped within a GuacamoleInstruction
instance.
Normally, you would not need to use this class yourself. It is used by ConfiguredGuacamoleSocket to
complete the Guacamole protocol handshake procedure, and it is used by GuacamoleHTTPTunnelServlet
withindoRead()toimplementthereadinghalfofthetunnel.
The only concrete implementation of GuacamoleReader is ReaderGuacamoleReader, which wraps a Java
Reader, using that as the source for data to parse into Guacamole instructions. Again, you would not
normallydirectlyusethisclass,norinstantiateityourself.Aworking,concreteinstanceofGuacamoleReader
canberetrievedfromanyGuacamoleSocketorGuacamoleTunnel.

GuacamoleWriter
GuacamoleWriter provides a very basic write() function and a more abstract version called
writeInstruction()whichwritesinstancesofGuacamoleInstruction.Thesefunctionsareanalogousto
theread()andreadInstruction()functionsprovidedbyGuacamoleReader,andhavesimilarrestrictions:
thecontractimposedbywrite()requiresthatwritteninstructionsbecomplete
The only concrete implementation of GuacamoleWriter is WriterGuacamoleWriter, which wraps a Java
Writer,usingthatasthedestinationforGuacamoleinstructiondata,butyouwouldnotnormallydirectlyuse
thisclass,norinstantiateityourself.ItisusedbyConfiguredGuacamoleSockettocompletetheGuacamole
protocol handshake procedure, and it is used by GuacamoleHTTPTunnelServlet within doWrite() to
implementthewritinghalfofthetunnel.
Ifnecessary,aGuacamoleWritercanberetrievedfromanyGuacamoleSocketorGuacamoleTunnel,butin
mostcases,theclassesprovidedbytheGuacamoleJavaAPIwhichalreadyuseGuacamoleWriterwillbe
sufficient.

http://guacdev.org/doc/gug/guacamolecommon.html

2/4

12/6/2015

Chapter14.guacamolecommon

Readingproperties
The Guacamole Java API provides simple access to guacamole.properties for convenience, although
suchsupportisnotstrictlyrequired.ThissupportisprovidedthroughtheGuacamoleProperiesutilityclass,
which cannot be instantiated and provides two simple property retrieval functions: getProperty() and
getRequiredProperty(), the difference being that the former can return null if a property is not defined,
whilethelatterwillthrowanexceptioninstead.Thesefunctionsaregenericandtypesafeandwillreturnthe
correctJavaclassortypewhengivenaninstanceofaproperty.
InGuacamole,eachpropertyisdeclaredasanimplementationofGuacamoleProperty,andmustprovidean
implementation of getName(), which returns the name of the property as it should exist within
guacamole.properties,andparseValue(),whichisgiventheStringvalueofthepropertyasreadfrom
guacamole.properties, and must return the declared type of the GuacamoleProperty implementation. A
good example of how this works is the IntegerGuacamoleProperty implementation included within
guacamolecommon:
publicabstractclassIntegerGuacamolePropertyimplementsGuacamoleProperty<Integer>{
@Override
publicIntegerparseValue(Stringvalue)throwsGuacamoleException{
//Ifnopropertyprovided,returnnull.
if(value==null)
returnnull;
try{
Integerinteger=newInteger(value);
returninteger;
}
catch(NumberFormatExceptione){
thrownewGuacamoleServerException("Property\""+getName()+
"\"mustbeaninteger.",e);
}
}
}
Notice that this implementation does not actually provide getName(). Instead, it only implements
parseValue(),theintentbeingtomakeotherdevelopers'liveseasierwhentheyneedtoretrieveaninteger
propertyfromguacamole.properties.Usingthisclass,retrievinganintegerpropertyissimple:
publicclassMyClass{
publicstaticfinalIntegerGuacamolePropertyIMPORTANT_INT=
newIntegerGuacamoleProperty(){
@Override
publicStringgetName(){return"importantint";}
};
}
...lateronwithinMyClass...
intimportant=GuacamoleProperties.getRequiredProperty(IMPORTANT_INT);

http://guacdev.org/doc/gug/guacamolecommon.html

3/4

12/6/2015

Chapter14.guacamolecommon

guacamolecommonprovidesacoupleofsimilarclassesforretrievingcommontypesofproperties,suchasa
String or File, and implementing your own to facilitate properties that parse into arrays or a List, etc.
shouldbereasonablysimple.

http://guacdev.org/doc/gug/guacamolecommon.html

4/4

You might also like