diff --git a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleException.java b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleException.java index 1b2226df3..d9842266d 100644 --- a/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleException.java +++ b/guacamole-common/src/main/java/org/apache/guacamole/GuacamoleException.java @@ -68,5 +68,29 @@ public class GuacamoleException extends Exception { public GuacamoleStatus getStatus() { return GuacamoleStatus.SERVER_ERROR; } + + /** + * Returns the most applicable HTTP status code that can be associated + * with this exception. + * + * @return + * An integer representing the most applicable HTTP status code + * associated with this exception. + */ + public int getHttpStatusCode() { + return getStatus().getHttpStatusCode(); + } + + /** + * Returns the most applicable WebSocket status code that can be + * associated with this exception. + * + * @return + * An integer representing the most applicable WebSocket status + * code associated with this exception. + */ + public int getWebSocketCode() { + return getStatus().getWebSocketCode(); + } } diff --git a/guacamole-common/src/main/java/org/apache/guacamole/servlet/GuacamoleHTTPTunnelServlet.java b/guacamole-common/src/main/java/org/apache/guacamole/servlet/GuacamoleHTTPTunnelServlet.java index fdbfb8edc..be2da1312 100644 --- a/guacamole-common/src/main/java/org/apache/guacamole/servlet/GuacamoleHTTPTunnelServlet.java +++ b/guacamole-common/src/main/java/org/apache/guacamole/servlet/GuacamoleHTTPTunnelServlet.java @@ -149,26 +149,29 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { * @param response * The HTTP response to use to send the error. * - * @param guacStatus - * The status to send + * @param guacamoleStatusCode + * The GuacamoleStatus code to send. + * + * @param guacamoleHttpCode + * The numeric HTTP code to send. * * @param message - * A human-readable message that can be presented to the user. + * The human-readable error message to send. * * @throws ServletException * If an error prevents sending of the error code. */ - protected void sendError(HttpServletResponse response, - GuacamoleStatus guacStatus, String message) + protected void sendError(HttpServletResponse response, int guacamoleStatusCode, + int guacamoleHttpCode, String message) throws ServletException { try { // If response not committed, send error code and message if (!response.isCommitted()) { - response.addHeader("Guacamole-Status-Code", Integer.toString(guacStatus.getGuacamoleStatusCode())); + response.addHeader("Guacamole-Status-Code", Integer.toString(guacamoleStatusCode)); response.addHeader("Guacamole-Error-Message", message); - response.sendError(guacStatus.getHttpStatusCode()); + response.sendError(guacamoleHttpCode); } } @@ -237,14 +240,14 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // If read operation, call doRead() with tunnel UUID, ignoring any // characters following the tunnel UUID. - else if(query.startsWith(READ_PREFIX)) + else if (query.startsWith(READ_PREFIX)) doRead(request, response, query.substring( READ_PREFIX_LENGTH, READ_PREFIX_LENGTH + UUID_LENGTH)); // If write operation, call doWrite() with tunnel UUID, ignoring any // characters following the tunnel UUID. - else if(query.startsWith(WRITE_PREFIX)) + else if (query.startsWith(WRITE_PREFIX)) doWrite(request, response, query.substring( WRITE_PREFIX_LENGTH, WRITE_PREFIX_LENGTH + UUID_LENGTH)); @@ -258,12 +261,14 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet { // HTTP response, logging each error appropriately. catch (GuacamoleClientException e) { logger.warn("HTTP tunnel request rejected: {}", e.getMessage()); - sendError(response, e.getStatus(), e.getMessage()); + sendError(response, e.getStatus().getGuacamoleStatusCode(), + e.getStatus().getHttpStatusCode(), e.getMessage()); } catch (GuacamoleException e) { logger.error("HTTP tunnel request failed: {}", e.getMessage()); logger.debug("Internal error in HTTP tunnel.", e); - sendError(response, e.getStatus(), "Internal server error."); + sendError(response, e.getStatus().getGuacamoleStatusCode(), + e.getStatus().getHttpStatusCode(), "Internal server error."); } } diff --git a/guacamole-common/src/main/java/org/apache/guacamole/websocket/GuacamoleWebSocketTunnelEndpoint.java b/guacamole-common/src/main/java/org/apache/guacamole/websocket/GuacamoleWebSocketTunnelEndpoint.java index 0cae732bb..0e0262254 100644 --- a/guacamole-common/src/main/java/org/apache/guacamole/websocket/GuacamoleWebSocketTunnelEndpoint.java +++ b/guacamole-common/src/main/java/org/apache/guacamole/websocket/GuacamoleWebSocketTunnelEndpoint.java @@ -66,17 +66,24 @@ public abstract class GuacamoleWebSocketTunnelEndpoint extends Endpoint { private GuacamoleTunnel tunnel; /** - * Sends the given status on the given WebSocket connection and closes the - * connection. + * Sends the numeric Guacaomle Status Code and Web Socket + * code and closes the connection. * - * @param session The outbound WebSocket connection to close. - * @param guac_status The status to send. + * @param session + * The outbound WebSocket connection to close. + * + * @param guacamoleStatusCode + * The numeric Guacamole status to send. + * + * @param webSocketCode + * The numeric WebSocket status to send. */ - private void closeConnection(Session session, GuacamoleStatus guac_status) { + private void closeConnection(Session session, int guacamoleStatusCode, + int webSocketCode) { try { - CloseCode code = CloseReason.CloseCodes.getCloseCode(guac_status.getWebSocketCode()); - String message = Integer.toString(guac_status.getGuacamoleStatusCode()); + CloseCode code = CloseReason.CloseCodes.getCloseCode(webSocketCode); + String message = Integer.toString(guacamoleStatusCode); session.close(new CloseReason(code, message)); } catch (IOException e) { @@ -85,6 +92,21 @@ public abstract class GuacamoleWebSocketTunnelEndpoint extends Endpoint { } + /** + * Sends the given Guacaomle Status and closes the given + * connection. + * + * @param session + * The outbound WebSocket connection to close. + * + * @param guacStatus + * The status to use for the connection. + */ + private void closeConnection(Session session, GuacamoleStatus guacStatus) { + closeConnection(session, guacStatus.getGuacamoleStatusCode(), + guacStatus.getWebSocketCode()); + } + /** * Returns a new tunnel for the given session. How this tunnel is created * or retrieved is implementation-dependent. @@ -117,7 +139,8 @@ public abstract class GuacamoleWebSocketTunnelEndpoint extends Endpoint { catch (GuacamoleException e) { logger.error("Creation of WebSocket tunnel to guacd failed: {}", e.getMessage()); logger.debug("Error connecting WebSocket tunnel.", e); - closeConnection(session, e.getStatus()); + closeConnection(session, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); return; } @@ -181,7 +204,8 @@ public abstract class GuacamoleWebSocketTunnelEndpoint extends Endpoint { catch (GuacamoleClientException e) { logger.info("WebSocket connection terminated: {}", e.getMessage()); logger.debug("WebSocket connection terminated due to client error.", e); - closeConnection(session, e.getStatus()); + closeConnection(session, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); } catch (GuacamoleConnectionClosedException e) { logger.debug("Connection to guacd closed.", e); @@ -190,7 +214,8 @@ public abstract class GuacamoleWebSocketTunnelEndpoint extends Endpoint { catch (GuacamoleException e) { logger.error("Connection to guacd terminated abnormally: {}", e.getMessage()); logger.debug("Internal error during connection to guacd.", e); - closeConnection(session, e.getStatus()); + closeConnection(session, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); } } diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java index 28736e8de..a0c756ebe 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTExceptionWrapper.java @@ -173,7 +173,7 @@ public class RESTExceptionWrapper implements MethodInterceptor { // Translate GuacamoleException subclasses to HTTP error codes catch (GuacamoleException e) { throw new APIException( - Response.Status.fromStatusCode(e.getStatus().getHttpStatusCode()), + Response.Status.fromStatusCode(e.getHttpStatusCode()), e ); } diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/jetty8/GuacamoleWebSocketTunnelServlet.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/jetty8/GuacamoleWebSocketTunnelServlet.java index 976964625..e5c5db9a1 100644 --- a/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/jetty8/GuacamoleWebSocketTunnelServlet.java +++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/jetty8/GuacamoleWebSocketTunnelServlet.java @@ -53,17 +53,42 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { private static final int BUFFER_SIZE = 8192; /** - * Sends the given status on the given WebSocket connection and closes the + * Sends the given numeric Guacamole and WebSocket status + * on the given WebSocket connection and closes the * connection. * - * @param connection The WebSocket connection to close. - * @param guac_status The status to send. + * @param connection + * The WebSocket connection to close. + * + * @param guacamoleStatusCode + * The numeric Guacamole Status code to send. + * + * @param webSocketCode + * The numeric WebSocket status code to send. */ - public static void closeConnection(Connection connection, - GuacamoleStatus guac_status) { + private static void closeConnection(Connection connection, + int guacamoleStatusCode, int webSocketCode) { - connection.close(guac_status.getWebSocketCode(), - Integer.toString(guac_status.getGuacamoleStatusCode())); + connection.close(webSocketCode, + Integer.toString(guacamoleStatusCode)); + + } + + /** + * Sends the given status on the given WebSocket connection + * and closes the connection. + * + * @param connection + * The WebSocket connection to close. + * + * @param guacStatus + * The status to send. + */ + private static void closeConnection(Connection connection, + GuacamoleStatus guacStatus) { + + closeConnection(connection, guacStatus.getGuacamoleStatusCode(), + guacStatus.getWebSocketCode()); } @@ -114,7 +139,8 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { catch (GuacamoleException e) { logger.error("Creation of WebSocket tunnel to guacd failed: {}", e.getMessage()); logger.debug("Error connecting WebSocket tunnel.", e); - closeConnection(connection, e.getStatus()); + closeConnection(connection, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); return; } @@ -168,7 +194,8 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { catch (GuacamoleClientException e) { logger.info("WebSocket connection terminated: {}", e.getMessage()); logger.debug("WebSocket connection terminated due to client error.", e); - closeConnection(connection, e.getStatus()); + closeConnection(connection, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); } catch (GuacamoleConnectionClosedException e) { logger.debug("Connection to guacd closed.", e); @@ -177,7 +204,8 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { catch (GuacamoleException e) { logger.error("Connection to guacd terminated abnormally: {}", e.getMessage()); logger.debug("Internal error during connection to guacd.", e); - closeConnection(connection, e.getStatus()); + closeConnection(connection, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); } } diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/jetty9/GuacamoleWebSocketTunnelListener.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/jetty9/GuacamoleWebSocketTunnelListener.java index 5375d75a6..0594d06aa 100644 --- a/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/jetty9/GuacamoleWebSocketTunnelListener.java +++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/jetty9/GuacamoleWebSocketTunnelListener.java @@ -57,18 +57,25 @@ public abstract class GuacamoleWebSocketTunnelListener implements WebSocketListe private GuacamoleTunnel tunnel; /** - * Sends the given status on the given WebSocket connection and closes the + * Sends the given numeric Guacamole and WebSocket status + * codes on the given WebSocket connection and closes the * connection. * - * @param session The outbound WebSocket connection to close. - * @param guac_status The status to send. + * @param session + * The outbound WebSocket connection to close. + * + * @param guacamoleStatusCode + * The numeric Guacamole status code to send. + * + * @param webSocketCode + * The numeric WebSocket status code to send. */ - private void closeConnection(Session session, GuacamoleStatus guac_status) { + private void closeConnection(Session session, int guacamoleStatusCode, + int webSocketCode) { try { - int code = guac_status.getWebSocketCode(); - String message = Integer.toString(guac_status.getGuacamoleStatusCode()); - session.close(new CloseStatus(code, message)); + String message = Integer.toString(guacamoleStatusCode); + session.close(new CloseStatus(webSocketCode, message)); } catch (IOException e) { logger.debug("Unable to close WebSocket connection.", e); @@ -76,6 +83,24 @@ public abstract class GuacamoleWebSocketTunnelListener implements WebSocketListe } + /** + * Sends the given status on the given WebSocket connection + * and closes the connection. + * + * @param session + * The outbound WebSocket connection to close. + * + * @param guacStatus + * The status to send. + */ + private void closeConnection(Session session, + GuacamoleStatus guacStatus) { + + closeConnection(session, guacStatus.getGuacamoleStatusCode(), + guacStatus.getWebSocketCode()); + + } + /** * Returns a new tunnel for the given session. How this tunnel is created * or retrieved is implementation-dependent. @@ -105,7 +130,7 @@ public abstract class GuacamoleWebSocketTunnelListener implements WebSocketListe catch (GuacamoleException e) { logger.error("Creation of WebSocket tunnel to guacd failed: {}", e.getMessage()); logger.debug("Error connecting WebSocket tunnel.", e); - closeConnection(session, e.getStatus()); + closeConnection(session, e.getStatus().getGuacamoleStatusCode(), e.getWebSocketCode()); return; } @@ -159,7 +184,8 @@ public abstract class GuacamoleWebSocketTunnelListener implements WebSocketListe catch (GuacamoleClientException e) { logger.info("WebSocket connection terminated: {}", e.getMessage()); logger.debug("WebSocket connection terminated due to client error.", e); - closeConnection(session, e.getStatus()); + closeConnection(session, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); } catch (GuacamoleConnectionClosedException e) { logger.debug("Connection to guacd closed.", e); @@ -168,7 +194,8 @@ public abstract class GuacamoleWebSocketTunnelListener implements WebSocketListe catch (GuacamoleException e) { logger.error("Connection to guacd terminated abnormally: {}", e.getMessage()); logger.debug("Internal error during connection to guacd.", e); - closeConnection(session, e.getStatus()); + closeConnection(session, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); } } diff --git a/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/tomcat/GuacamoleWebSocketTunnelServlet.java b/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/tomcat/GuacamoleWebSocketTunnelServlet.java index 986650eac..a2e8b3981 100644 --- a/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/tomcat/GuacamoleWebSocketTunnelServlet.java +++ b/guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/tomcat/GuacamoleWebSocketTunnelServlet.java @@ -58,17 +58,25 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { private final Logger logger = LoggerFactory.getLogger(GuacamoleWebSocketTunnelServlet.class); /** - * Sends the given status on the given WebSocket connection and closes the + * Sends the given Guacamole and WebSocket numeric status + * on the given WebSocket connection and closes the * connection. * - * @param outbound The outbound WebSocket connection to close. - * @param guac_status The status to send. + * @param outbound + * The outbound WebSocket connection to close. + * + * @param guacamoleStatusCode + * The status to send. + * + * @param webSocketCode + * The numeric WebSocket status code to send. */ - public void closeConnection(WsOutbound outbound, GuacamoleStatus guac_status) { + private void closeConnection(WsOutbound outbound, int guacamoleStatusCode, + int webSocketCode) { try { - byte[] message = Integer.toString(guac_status.getGuacamoleStatusCode()).getBytes("UTF-8"); - outbound.close(guac_status.getWebSocketCode(), ByteBuffer.wrap(message)); + byte[] message = Integer.toString(guacamoleStatusCode).getBytes("UTF-8"); + outbound.close(webSocketCode, ByteBuffer.wrap(message)); } catch (IOException e) { logger.debug("Unable to close WebSocket tunnel.", e); @@ -76,6 +84,24 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { } + /** + * Sends the given status on the given WebSocket connection + * and closes the connection. + * + * @param outbound + * The outbound WebSocket connection to close. + * + * @param guacStatus + * The status to send. + */ + private void closeConnection(WsOutbound outbound, + GuacamoleStatus guacStatus) { + + closeConnection(outbound, guacStatus.getGuacamoleStatusCode(), + guacStatus.getWebSocketCode()); + + } + @Override protected String selectSubProtocol(List subProtocols) { @@ -142,7 +168,8 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { catch (GuacamoleException e) { logger.error("Creation of WebSocket tunnel to guacd failed: {}", e.getMessage()); logger.debug("Error connecting WebSocket tunnel.", e); - closeConnection(outbound, e.getStatus()); + closeConnection(outbound, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); return; } @@ -196,7 +223,8 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { catch (GuacamoleClientException e) { logger.info("WebSocket connection terminated: {}", e.getMessage()); logger.debug("WebSocket connection terminated due to client error.", e); - closeConnection(outbound, e.getStatus()); + closeConnection(outbound, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); } catch (GuacamoleConnectionClosedException e) { logger.debug("Connection to guacd closed.", e); @@ -205,7 +233,8 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet { catch (GuacamoleException e) { logger.error("Connection to guacd terminated abnormally: {}", e.getMessage()); logger.debug("Internal error during connection to guacd.", e); - closeConnection(outbound, e.getStatus()); + closeConnection(outbound, e.getStatus().getGuacamoleStatusCode(), + e.getWebSocketCode()); } }