diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/websocket/jetty/GuacamoleWebSocketTunnelServlet.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/websocket/jetty/GuacamoleWebSocketTunnelServlet.java index fcd292be8..612e21f4a 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/websocket/jetty/GuacamoleWebSocketTunnelServlet.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/websocket/jetty/GuacamoleWebSocketTunnelServlet.java @@ -32,8 +32,7 @@ import org.eclipse.jetty.websocket.WebSocket; import org.eclipse.jetty.websocket.WebSocket.Connection; import org.eclipse.jetty.websocket.WebSocketServlet; import org.glyptodon.guacamole.GuacamoleClientException; -import org.glyptodon.guacamole.GuacamoleResourceNotFoundException; -import org.glyptodon.guacamole.GuacamoleSecurityException; +import org.glyptodon.guacamole.protocol.GuacamoleStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,6 +53,22 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { */ private static final int BUFFER_SIZE = 8192; + /** + * Sends an error on the given WebSocket connection and closes the + * connection. The error sent is determined from using the information + * within the given GuacamoleStatus. + * + * @param connection The WebSocket connection to close. + * @param guac_status The status to send. + */ + public static void sendError(Connection connection, + GuacamoleStatus guac_status) { + + connection.close(guac_status.getWebSocketCode(), + Integer.toString(guac_status.getGuacamoleStatusCode())); + + } + @Override public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) { @@ -124,21 +139,13 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { // Catch any thrown guacamole exception and attempt // to pass within the WebSocket connection, logging // each error appropriately. - catch (GuacamoleSecurityException e) { - logger.warn("Authorization failed.", e); - connection.close(1008, null); // Policy violation - } - catch (GuacamoleResourceNotFoundException e) { - logger.debug("Resource not found.", e); - connection.close(1002, null); // Protocol error - } catch (GuacamoleClientException e) { - logger.warn("Error in client request.", e); - connection.close(1002, null); // Protocol error + logger.warn("Client request rejected: {}", e.getMessage()); + sendError(connection, e.getStatus()); } catch (GuacamoleException e) { - logger.error("Server error in tunnel", e); - connection.close(1011, null); // Server error + logger.error("Internal server error.", e); + sendError(connection, e.getStatus()); } } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/websocket/tomcat/GuacamoleWebSocketTunnelServlet.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/websocket/tomcat/GuacamoleWebSocketTunnelServlet.java index 58c5b2f20..237fd9a47 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/websocket/tomcat/GuacamoleWebSocketTunnelServlet.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/websocket/tomcat/GuacamoleWebSocketTunnelServlet.java @@ -25,6 +25,7 @@ package org.glyptodon.guacamole.net.basic.websocket.tomcat; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.nio.ByteBuffer; import java.nio.CharBuffer; import javax.servlet.http.HttpServletRequest; import org.apache.catalina.websocket.Constants; @@ -36,8 +37,7 @@ import org.apache.catalina.websocket.StreamInbound; import org.apache.catalina.websocket.WebSocketServlet; import org.apache.catalina.websocket.WsOutbound; import org.glyptodon.guacamole.GuacamoleClientException; -import org.glyptodon.guacamole.GuacamoleResourceNotFoundException; -import org.glyptodon.guacamole.GuacamoleSecurityException; +import org.glyptodon.guacamole.protocol.GuacamoleStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,6 +58,24 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { */ private final Logger logger = LoggerFactory.getLogger(GuacamoleWebSocketTunnelServlet.class); + /** + * Sends an error on the given WebSocket connection and closes the + * connection. The error sent is determined from using the information + * within the given GuacamoleStatus. + * + * @param outbound The outbound WebSocket connection to close. + * @param guac_status The status to send. + * @throws IOException If an error prevents proper closure of the WebSocket + * connection. + */ + public static void sendError(WsOutbound outbound, + GuacamoleStatus guac_status) throws IOException { + + byte[] message = Integer.toString(guac_status.getGuacamoleStatusCode()).getBytes("UTF-8"); + outbound.close(guac_status.getWebSocketCode(), ByteBuffer.wrap(message)); + + } + @Override public StreamInbound createWebSocketInbound(String protocol, HttpServletRequest request) { @@ -129,27 +147,19 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { // No more data outbound.close(Constants.STATUS_SHUTDOWN, null); - + } // Catch any thrown guacamole exception and attempt // to pass within the WebSocket connection, logging // each error appropriately. - catch (GuacamoleSecurityException e) { - logger.warn("Authorization failed.", e); - outbound.close(Constants.STATUS_POLICY_VIOLATION, null); - } - catch (GuacamoleResourceNotFoundException e) { - logger.debug("Resource not found.", e); - outbound.close(Constants.STATUS_PROTOCOL_ERROR, null); - } catch (GuacamoleClientException e) { - logger.warn("Error in client request.", e); - outbound.close(Constants.STATUS_PROTOCOL_ERROR, null); + logger.warn("Client request rejected: {}", e.getMessage()); + sendError(outbound, e.getStatus()); } catch (GuacamoleException e) { - logger.error("Server error in tunnel", e); - outbound.close(Constants.STATUS_UNEXPECTED_CONDITION, null); + logger.error("Internal server error.", e); + sendError(outbound, e.getStatus()); } }