blob: ee362d6e83d9ca77cf027732e88645ba1fe1ba60 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<chapter xml:id="guacamole-common" xmlns="http://docbook.org/ns/docbook"
version="5.0" xml:lang="en" xmlns:xl="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<title><package>guacamole-common</package></title>
<indexterm>
<primary>API</primary>
<secondary>Java</secondary>
</indexterm>
<indexterm>
<primary><package>guacamole-common</package></primary>
</indexterm>
<para>The Java API provided by the Guacamole project is called guacamole-common. It provides a
basic means of tunneling data between the JavaScript client provided by guacamole-common-js
and the native proxy daemon, guacd, and for dealing with the Guacamole protocol. The purpose
of this library is to facilitate the creation of custom tunnels between the JavaScript
client and guacd, allowing your Guacamole-driven web application to enforce its own security
model, if any, and dictate exactly what connections are established.</para>
<section xml:id="java-http-tunnel">
<title>HTTP tunnel</title>
<para>The Guacamole Java API implements the HTTP tunnel using a servlet
called <classname>GuacamoleHTTPTunnelServlet</classname>. This
servlet handles all requests coming to it over HTTP from the
JavaScript client, and translated them into connect, read, or write
requests, which each get dispatched to the
<methodname>doConnect()</methodname>,
<methodname>doRead()</methodname>, and
<methodname>doWrite()</methodname> functions accordingly.</para>
<para>Normally, you wouldn't touch the <methodname>doRead()</methodname>
and <methodname>doWrite()</methodname> functions, as these have
already been written to properly handle the requests of the
JavaScript tunnel, and if you feel the need to touch these
functions, you are probably better off writing your own tunnel
implementation, although such a thing is difficult to do in a
performant way.</para>
<para>When developing an application based on the Guacamole API, you
should use <classname>GuacamoleHTTPTunnelServlet</classname> by
extending it, implementing your own version of
<methodname>doConnect()</methodname>, which is the only abstract
function it defines. The tutorial later in this book demonstrating
how to write a Guacamole-based web application shows the basics of
doing this, but generally, <methodname>doConnect()</methodname> is
an excellent place for authentication or other validation, as it is
the responsibility of <methodname>doConnect()</methodname> to create
(or not create) the actual tunnel. If
<methodname>doConnect()</methodname> does not create the tunnel,
communication between the JavaScript client and guacd cannot take
place, which is an ideal power to have as an authenticator.</para>
<para>The <methodname>doConnect()</methodname> function is expected to return a new
<classname>GuacamoleTunnel</classname>, but it is completely up to the
implementation to decide how that tunnel is to be created. The already-implemented parts
of <classname>GuacamoleHTTPTunnelServlet</classname> then return the unique identifier
of this tunnel to the JavaScript client, allowing its own tunnel implementation to
continue to communicate with the tunnel existing on the Java side.</para>
<para>Instances of <classname>GuacamoleTunnel</classname> are created associated with a
<classname>GuacamoleSocket</classname>, which is the abstract interface surrounding
the low-level connection to guacd. Overall, there is a socket
(<classname>GuacamoleSocket</classname>) which provides a TCP connection to guacd.
This socket is exposed to <classname>GuacamoleTunnel</classname>, which provides
abstract protocol access around what is actually (but secretly, through the abstraction
of the API) a TCP socket.</para>
<para>The Guacamole web application extends this tunnel servlet in order
to implement authentication at the lowest possible level,
effectively prohibiting communication between the client and any
remote desktops unless they have properly authenticated. Your own
implementation can be considerably simpler, especially if you don't
need authentication:</para>
<informalexample>
<programlisting>public class MyGuacamoleTunnelServlet
extends GuacamoleHTTPTunnelServlet {
@Override
protected GuacamoleTunnel doConnect(HttpServletRequest request)
throws GuacamoleException {
// Connect to guacd here (this is a STUB)
GuacamoleSocket socket;
// Return a new tunnel which uses the connected socket
return new SimpleGuacamoleTunnel(socket);
}
}</programlisting>
</informalexample>
</section>
<section xml:id="java-protocol-usage">
<title>Using the Guacamole protocol</title>
<para>guacamole-common provides basic low-level support for the
Guacamole protocol. This low-level support is leveraged by the HTTP
tunnel implementation to satisfy the requirements of the JavaScript
client implementation, as the JavaScript client expects the
handshake procedure to have already taken place. This support exists
through the <classname>GuacamoleReader</classname> and
<classname>GuacamoleWriter</classname> classes, which are
similar to Java's <classname>Reader</classname> and
<classname>Writer</classname> classes, except that they deal
with the Guacamole protocol specifically, and thus have slightly
different contracts.</para>
<section xml:id="java-reading-protocol">
<title><classname>GuacamoleReader</classname></title>
<para><classname>GuacamoleReader</classname> provides a very basic
<methodname>read()</methodname> function which is required
to return one or more complete instructions in a
<type>char</type> array. It also provides the typical
<methodname>available()</methodname> function, which informs
you whether <methodname>read()</methodname> is likely to block
the next time it is called, and an even more abstract version of
<methodname>read()</methodname> called
<methodname>readInstruction()</methodname> which returns one
instruction at a time, wrapped within a
<classname>GuacamoleInstruction</classname> instance.</para>
<para>Normally, you would not need to use this class yourself. It is
used by <classname>ConfiguredGuacamoleSocket</classname> to
complete the Guacamole protocol handshake procedure, and it is
used by <classname>GuacamoleHTTPTunnelServlet</classname> within
<methodname>doRead()</methodname> to implement the reading
half of the tunnel.</para>
<para>The only concrete implementation of
<classname>GuacamoleReader</classname> is
<classname>ReaderGuacamoleReader</classname>, which wraps a
Java <classname>Reader</classname>, using that as the source for
data to parse into Guacamole instructions. Again, you would not
normally directly use this class, nor instantiate it yourself. A
working, concrete instance of
<classname>GuacamoleReader</classname> can be retrieved from
any <classname>GuacamoleSocket</classname> or
<classname>GuacamoleTunnel</classname>.</para>
</section>
<section xml:id="java-writing-protocol">
<title><classname>GuacamoleWriter</classname></title>
<para><classname>GuacamoleWriter</classname> provides a very basic
<methodname>write()</methodname> function and a more
abstract version called
<methodname>writeInstruction()</methodname> which writes
instances of <classname>GuacamoleInstruction</classname>. These
functions are analogous to the <methodname>read()</methodname>
and <methodname>readInstruction()</methodname> functions
provided by <classname>GuacamoleReader</classname>, and have
similar restrictions: the contract imposed by
<methodname>write()</methodname> requires that written
instructions be complete</para>
<para>The only concrete implementation of
<classname>GuacamoleWriter</classname> is
<classname>WriterGuacamoleWriter</classname>, which wraps a
Java <classname>Writer</classname>, using that as the
destination for Guacamole instruction data, but you would not
normally directly use this class, nor instantiate it yourself.
It is used by <classname>ConfiguredGuacamoleSocket</classname>
to complete the Guacamole protocol handshake procedure, and it
is used by <classname>GuacamoleHTTPTunnelServlet</classname>
within <methodname>doWrite()</methodname> to implement the
writing half of the tunnel.</para>
<para>If necessary, a <classname>GuacamoleWriter</classname> can be
retrieved from any <classname>GuacamoleSocket</classname> or
<classname>GuacamoleTunnel</classname>, but in most cases,
the classes provided by the Guacamole Java API which already use
<classname>GuacamoleWriter</classname> will be
sufficient.</para>
</section>
</section>
</chapter>