code: protected void doWrite(HttpServletRequest request,
              HttpServletResponse response, String tunnelUUID)
              throws GuacamoleException {
  
          GuacamoleTunnel tunnel = getTunnel(tunnelUUID);
  
          // We still need to set the content type to avoid the default of
          // text/html, as such a content type would cause some browsers to
          // attempt to parse the result, even though the JavaScript client
          // does not explicitly request such parsing.
          response.setContentType("application/octet-stream");
          response.setHeader("Cache-Control", "no-cache");
          response.setContentLength(0);
  
          // Send data
          try {
  
              // Get writer from tunnel
              GuacamoleWriter writer = tunnel.acquireWriter();
  
              // Get input reader for HTTP stream
              Reader input = new InputStreamReader(
                      request.getInputStream(), "UTF-8");
  
              // Transfer data from input stream to tunnel output, ensuring
              // input is always closed
              try {
  
                  // Buffer
                  int length;
                  char[] buffer = new char[8192];
  
                  // Transfer data using buffer
                  while (tunnel.isOpen() &&
                          (length = input.read(buffer, 0, buffer.length)) != -1)
                      writer.write(buffer, 0, length);
  
              }
  
              // Close input stream in all cases
              finally {
                  input.close();
              }
  
          }
          catch (GuacamoleConnectionClosedException e) {
              logger.debug("Connection to guacd closed.", e);
          }
          catch (IOException e) {
  
              // Deregister and close
              deregisterTunnel(tunnel);
              tunnel.close();
  
              throw new GuacamoleServerException("I/O Error sending data to server: " + e.getMessage(), e);
          }
          finally {
              tunnel.releaseWriter();
          }
  
      }
docs: Called whenever the JavaScript Guacamole client makes a write request.
  This function should in general not be overridden, as it already
  contains a proper implementation of the write operation.
  
  @param request
  The HttpServletRequest associated with the write request received.
  Any data to be written will be specified within the body of this
  request.
  
  @param response
  The HttpServletResponse associated with the write request received.
  
  @param tunnelUUID
  The UUID of the tunnel to write to, as specified in the write
  request. This tunnel must have been created by a previous call to
  doConnect().
  
  @throws GuacamoleException
  If an error occurs while handling the write request.