protected void doRead ( HttpServletRequest request , HttpServletResponse response , String tunnelUUID ) throws GuacamoleException { // Get tunnel, ensure tunnel exists GuacamoleTunnel tunnel = getTunnel ( tunnelUUID ) ; // Ensure tunnel is open if ( ! tunnel . isOpen ( ) ) throw new GuacamoleResourceNotFoundException ( "Tunnel is closed." ) ; // Obtain exclusive read access GuacamoleReader reader = tunnel . acquireReader ( ) ; try { // Note that although we are sending text, Webkit browsers will // buffer 1024 bytes before starting a normal stream if we use // anything but application/octet-stream. response . setContentType ( "application/octet-stream" ) ; response . setHeader ( "Cache-Control" , "no-cache" ) ; // Get writer for response Writer out = new BufferedWriter ( new OutputStreamWriter ( response . getOutputStream ( ) , "UTF-8" ) ) ; // Stream data to response, ensuring output stream is closed try { // Deregister tunnel and throw error if we reach EOF without // having ever sent any data char [ ] message = reader . read ( ) ; if ( message == null ) throw new GuacamoleConnectionClosedException ( "Tunnel reached end of stream." ) ; // For all messages, until another stream is ready (we send at least one message) do { // Get message output bytes out . write ( message , 0 , message . length ) ; // Flush if we expect to wait if ( ! reader . available ( ) ) { out . flush ( ) ; response . flushBuffer ( ) ; } // No more messages another stream can take over if ( tunnel . hasQueuedReaderThreads ( ) ) break ; } while ( tunnel . isOpen ( ) && ( message = reader . read ( ) ) != null ) ; // Close tunnel immediately upon EOF if ( message == null ) { deregisterTunnel ( tunnel ) ; tunnel . close ( ) ; } // End-of-instructions marker out . write ( "0.;" ) ; out . flush ( ) ; response . flushBuffer ( ) ; } // Send end-of-stream marker and close tunnel if connection is closed catch ( GuacamoleConnectionClosedException e ) { // Deregister and close deregisterTunnel ( tunnel ) ; tunnel . close ( ) ; // End-of-instructions marker out . write ( "0.;" ) ; out . flush ( ) ; response . flushBuffer ( ) ; } catch ( GuacamoleException e ) { // Deregister and close deregisterTunnel ( tunnel ) ; tunnel . close ( ) ; throw e ; } // Always close output stream finally { out . close ( ) ; } } catch ( IOException e ) { // Log typically frequent I/O error if desired logger . debug ( "Error writing to servlet output stream" , e ) ; // Deregister and close deregisterTunnel ( tunnel ) ; tunnel . close ( ) ; } finally { tunnel . releaseReader ( ) ; } }
Called whenever the JavaScript Guacamole client makes a read request . This function should in general not be overridden as it already contains a proper implementation of the read operation .