diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java index 55713acf2..2aa8da52a 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSocket.java @@ -76,4 +76,12 @@ public interface GuacamoleSocket { */ public void close() throws GuacamoleException; + /** + * Returns whether this GuacamoleSocket is open and can be used for reading + * and writing. + * + * @return true if this GuacamoleSocket is open, false otherwise. + */ + public boolean isOpen(); + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java index cb1020cd7..4a7bc0fd5 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java @@ -57,6 +57,8 @@ public class GuacamoleTunnel { private ReentrantLock readerLock; private ReentrantLock writerLock; + private boolean open = true; + /** * Creates a new GuacamoleTunnel which synchronizes access to the * Guacamole instruction stream associated with the given GuacamoleSocket. @@ -146,6 +148,16 @@ public class GuacamoleTunnel { return uuid; } + /** + * Returns the GuacamoleSocket used by this GuacamoleTunnel for reading + * and writing. + * + * @return The GuacamoleSocket used by this GuacamoleTunnel. + */ + public GuacamoleSocket getSocket() { + return socket; + } + /** * Release all resources allocated to this GuacamoleTunnel. * @@ -156,4 +168,13 @@ public class GuacamoleTunnel { socket.close(); } + /** + * Returns whether this GuacamoleTunnel is open, or has been closed. + * + * @return true if this GuacamoleTunnel is open, false if it is closed. + */ + public boolean isOpen() { + return socket.isOpen(); + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java index cd5783023..9a0e19893 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/InetGuacamoleSocket.java @@ -132,5 +132,10 @@ public class InetGuacamoleSocket implements GuacamoleSocket { return writer; } + @Override + public boolean isOpen() { + return !sock.isClosed(); + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java index a3de88cd7..192c32ca2 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -121,4 +121,9 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { socket.close(); } + @Override + public boolean isOpen() { + return socket.isOpen(); + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index 90d91ab60..e652f154d 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -227,10 +227,15 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { HttpSession httpSession = request.getSession(false); GuacamoleSession session = new GuacamoleSession(httpSession); + // Get tunnel, ensure tunnel exists GuacamoleTunnel tunnel = session.getTunnel(tunnelUUID); if (tunnel == null) throw new GuacamoleResourceNotFoundException("No such tunnel."); + // Ensure tunnel is open + if (!tunnel.isOpen()) + throw new GuacamoleResourceNotFoundException("Tunnel is closed."); + // Obtain exclusive read access GuacamoleReader reader = tunnel.acquireReader(); @@ -265,7 +270,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { if (tunnel.hasQueuedReaderThreads()) break; - } while ((message = reader.read()) != null); + } while (tunnel.isOpen() && (message = reader.read()) != null); // Close tunnel immediately upon EOF if (message == null) @@ -340,7 +345,8 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { char[] buffer = new char[8192]; int length; - while ((length = input.read(buffer, 0, buffer.length)) != -1) + while (tunnel.isOpen() && + (length = input.read(buffer, 0, buffer.length)) != -1) writer.write(buffer, 0, length); }