GUAC-553: Send Guacamole status code as sole content of WebSocket close frame.

This commit is contained in:
Michael Jumper
2014-03-19 11:26:09 -07:00
parent c69da31af9
commit 5eb84053cd
2 changed files with 46 additions and 29 deletions

View File

@@ -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());
}
}

View File

@@ -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) {
@@ -135,21 +153,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);
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());
}
}