mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-08 06:01:22 +00:00
#518: Send roughly-appropriate codes and close the WebSocket connection when errors are encountered.
This commit is contained in:
@@ -31,6 +31,9 @@ import org.glyptodon.guacamole.net.GuacamoleTunnel;
|
|||||||
import org.eclipse.jetty.websocket.WebSocket;
|
import org.eclipse.jetty.websocket.WebSocket;
|
||||||
import org.eclipse.jetty.websocket.WebSocket.Connection;
|
import org.eclipse.jetty.websocket.WebSocket.Connection;
|
||||||
import org.eclipse.jetty.websocket.WebSocketServlet;
|
import org.eclipse.jetty.websocket.WebSocketServlet;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -44,7 +47,7 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet {
|
|||||||
/**
|
/**
|
||||||
* Logger for this class.
|
* Logger for this class.
|
||||||
*/
|
*/
|
||||||
private static Logger logger = LoggerFactory.getLogger(GuacamoleWebSocketTunnelServlet.class);
|
private static final Logger logger = LoggerFactory.getLogger(GuacamoleWebSocketTunnelServlet.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default, minimum buffer size for instructions.
|
* The default, minimum buffer size for instructions.
|
||||||
@@ -96,25 +99,46 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet {
|
|||||||
char[] readMessage;
|
char[] readMessage;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while ((readMessage = reader.read()) != null) {
|
|
||||||
|
|
||||||
// Buffer message
|
try {
|
||||||
buffer.append(readMessage);
|
while ((readMessage = reader.read()) != null) {
|
||||||
|
|
||||||
|
// Buffer message
|
||||||
|
buffer.append(readMessage);
|
||||||
|
|
||||||
|
// Flush if we expect to wait or buffer is getting full
|
||||||
|
if (!reader.available() || buffer.length() >= BUFFER_SIZE) {
|
||||||
|
connection.sendMessage(buffer.toString());
|
||||||
|
buffer.setLength(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Flush if we expect to wait or buffer is getting full
|
|
||||||
if (!reader.available() || buffer.length() >= BUFFER_SIZE) {
|
|
||||||
connection.sendMessage(buffer.toString());
|
|
||||||
buffer.setLength(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
catch (GuacamoleException e) {
|
||||||
|
logger.error("Server error in tunnel", e);
|
||||||
|
connection.close(1011, null); // Server error
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
logger.debug("Tunnel read failed due to I/O error.", e);
|
logger.debug("Tunnel read failed due to I/O error.", e);
|
||||||
}
|
}
|
||||||
catch (GuacamoleException e) {
|
|
||||||
logger.debug("Tunnel read failed.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@ import java.io.InputStream;
|
|||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import org.apache.catalina.websocket.Constants;
|
||||||
import org.glyptodon.guacamole.GuacamoleException;
|
import org.glyptodon.guacamole.GuacamoleException;
|
||||||
import org.glyptodon.guacamole.io.GuacamoleReader;
|
import org.glyptodon.guacamole.io.GuacamoleReader;
|
||||||
import org.glyptodon.guacamole.io.GuacamoleWriter;
|
import org.glyptodon.guacamole.io.GuacamoleWriter;
|
||||||
@@ -34,6 +35,9 @@ import org.glyptodon.guacamole.net.GuacamoleTunnel;
|
|||||||
import org.apache.catalina.websocket.StreamInbound;
|
import org.apache.catalina.websocket.StreamInbound;
|
||||||
import org.apache.catalina.websocket.WebSocketServlet;
|
import org.apache.catalina.websocket.WebSocketServlet;
|
||||||
import org.apache.catalina.websocket.WsOutbound;
|
import org.apache.catalina.websocket.WsOutbound;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
|
||||||
|
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -52,7 +56,7 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet {
|
|||||||
/**
|
/**
|
||||||
* Logger for this class.
|
* Logger for this class.
|
||||||
*/
|
*/
|
||||||
private Logger logger = LoggerFactory.getLogger(GuacamoleWebSocketTunnelServlet.class);
|
private final Logger logger = LoggerFactory.getLogger(GuacamoleWebSocketTunnelServlet.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StreamInbound createWebSocketInbound(String protocol, HttpServletRequest request) {
|
public StreamInbound createWebSocketInbound(String protocol, HttpServletRequest request) {
|
||||||
@@ -101,40 +105,51 @@ public abstract class GuacamoleWebSocketTunnelServlet extends WebSocketServlet {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
CharBuffer charBuffer = CharBuffer.allocate(BUFFER_SIZE);
|
|
||||||
StringBuilder buffer = new StringBuilder(BUFFER_SIZE);
|
StringBuilder buffer = new StringBuilder(BUFFER_SIZE);
|
||||||
GuacamoleReader reader = tunnel.acquireReader();
|
GuacamoleReader reader = tunnel.acquireReader();
|
||||||
char[] readMessage;
|
char[] readMessage;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while ((readMessage = reader.read()) != null) {
|
|
||||||
|
|
||||||
// Buffer message
|
// Attempt to read
|
||||||
buffer.append(readMessage);
|
try {
|
||||||
|
while ((readMessage = reader.read()) != null) {
|
||||||
|
|
||||||
// Flush if we expect to wait or buffer is getting full
|
// Buffer message
|
||||||
if (!reader.available() || buffer.length() >= BUFFER_SIZE) {
|
buffer.append(readMessage);
|
||||||
|
|
||||||
// Reallocate buffer if necessary
|
// Flush if we expect to wait or buffer is getting full
|
||||||
if (buffer.length() > charBuffer.length())
|
if (!reader.available() || buffer.length() >= BUFFER_SIZE) {
|
||||||
charBuffer = CharBuffer.allocate(buffer.length());
|
outbound.writeTextMessage(CharBuffer.wrap(buffer));
|
||||||
else
|
buffer.setLength(0);
|
||||||
charBuffer.clear();
|
}
|
||||||
|
|
||||||
charBuffer.put(buffer.toString().toCharArray());
|
|
||||||
charBuffer.flip();
|
|
||||||
|
|
||||||
outbound.writeTextMessage(charBuffer);
|
|
||||||
buffer.setLength(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
catch (GuacamoleException e) {
|
||||||
|
logger.error("Server error in tunnel", e);
|
||||||
|
outbound.close(Constants.STATUS_UNEXPECTED_CONDITION, null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
logger.debug("Tunnel read failed due to I/O error.", e);
|
logger.debug("I/O error prevents further reads.", e);
|
||||||
}
|
|
||||||
catch (GuacamoleException e) {
|
|
||||||
logger.debug("Tunnel read failed.", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user