mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUAC-906: Implement GuacamoleConnectionClosedException. Throw when read/write fails due to closure.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package org.glyptodon.guacamole;
|
||||
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleStatus;
|
||||
|
||||
|
||||
/**
|
||||
* An exception which is thrown when an operation cannot be performed because
|
||||
* its corresponding connection is closed.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
public class GuacamoleConnectionClosedException extends GuacamoleServerException {
|
||||
|
||||
/**
|
||||
* Creates a new GuacamoleConnectionClosedException with the given message
|
||||
* and cause.
|
||||
*
|
||||
* @param message A human readable description of the exception that
|
||||
* occurred.
|
||||
* @param cause The cause of this exception.
|
||||
*/
|
||||
public GuacamoleConnectionClosedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GuacamoleConnectionClosedException with the given message.
|
||||
*
|
||||
* @param message A human readable description of the exception that
|
||||
* occurred.
|
||||
*/
|
||||
public GuacamoleConnectionClosedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GuacamoleConnectionClosedException with the given cause.
|
||||
*
|
||||
* @param cause The cause of this exception.
|
||||
*/
|
||||
public GuacamoleConnectionClosedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuacamoleStatus getStatus() {
|
||||
return GuacamoleStatus.SERVER_ERROR;
|
||||
}
|
||||
|
||||
}
|
@@ -25,9 +25,11 @@ package org.glyptodon.guacamole.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import org.glyptodon.guacamole.GuacamoleConnectionClosedException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleServerException;
|
||||
import org.glyptodon.guacamole.GuacamoleUpstreamTimeoutException;
|
||||
@@ -182,6 +184,9 @@ public class ReaderGuacamoleReader implements GuacamoleReader {
|
||||
catch (SocketTimeoutException e) {
|
||||
throw new GuacamoleUpstreamTimeoutException("Connection to guacd timed out.", e);
|
||||
}
|
||||
catch (SocketException e) {
|
||||
throw new GuacamoleConnectionClosedException("Connection to guacd is closed.", e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GuacamoleServerException(e);
|
||||
}
|
||||
|
@@ -25,8 +25,12 @@ package org.glyptodon.guacamole.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import org.glyptodon.guacamole.GuacamoleConnectionClosedException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleServerException;
|
||||
import org.glyptodon.guacamole.GuacamoleUpstreamTimeoutException;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleInstruction;
|
||||
|
||||
/**
|
||||
@@ -58,6 +62,12 @@ public class WriterGuacamoleWriter implements GuacamoleWriter {
|
||||
output.write(chunk, off, len);
|
||||
output.flush();
|
||||
}
|
||||
catch (SocketTimeoutException e) {
|
||||
throw new GuacamoleUpstreamTimeoutException("Connection to guacd timed out.", e);
|
||||
}
|
||||
catch (SocketException e) {
|
||||
throw new GuacamoleConnectionClosedException("Connection to guacd is closed.", e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GuacamoleServerException(e);
|
||||
}
|
||||
|
@@ -35,9 +35,9 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import org.glyptodon.guacamole.GuacamoleConnectionClosedException;
|
||||
import org.glyptodon.guacamole.GuacamoleException;
|
||||
import org.glyptodon.guacamole.GuacamoleResourceNotFoundException;
|
||||
import org.glyptodon.guacamole.GuacamoleSecurityException;
|
||||
import org.glyptodon.guacamole.GuacamoleServerException;
|
||||
import org.glyptodon.guacamole.io.GuacamoleReader;
|
||||
import org.glyptodon.guacamole.io.GuacamoleWriter;
|
||||
@@ -287,7 +287,7 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet {
|
||||
// data yet.
|
||||
char[] message = reader.read();
|
||||
if (message == null)
|
||||
throw new GuacamoleResourceNotFoundException("Tunnel reached end of stream.");
|
||||
throw new GuacamoleConnectionClosedException("Tunnel reached end of stream.");
|
||||
|
||||
// For all messages, until another stream is ready (we send at least one message)
|
||||
do {
|
||||
@@ -317,20 +317,28 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet {
|
||||
response.flushBuffer();
|
||||
}
|
||||
|
||||
// Send end-of-stream marker if connection is closed
|
||||
catch (GuacamoleConnectionClosedException e) {
|
||||
out.write("0.;");
|
||||
out.flush();
|
||||
response.flushBuffer();
|
||||
}
|
||||
|
||||
catch (GuacamoleException e) {
|
||||
|
||||
// Detach and close
|
||||
session.detachTunnel(tunnel);
|
||||
tunnel.close();
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Always close output stream
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
|
||||
// Detach and close
|
||||
session.detachTunnel(tunnel);
|
||||
tunnel.close();
|
||||
|
||||
throw e;
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
||||
// Log typically frequent I/O error if desired
|
||||
@@ -411,6 +419,9 @@ public abstract class GuacamoleHTTPTunnelServlet extends HttpServlet {
|
||||
}
|
||||
|
||||
}
|
||||
catch (GuacamoleConnectionClosedException e) {
|
||||
logger.debug("Connection closed.", e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
||||
// Detach and close
|
||||
|
@@ -38,6 +38,7 @@ import org.glyptodon.guacamole.io.GuacamoleReader;
|
||||
import org.glyptodon.guacamole.io.GuacamoleWriter;
|
||||
import org.glyptodon.guacamole.net.GuacamoleTunnel;
|
||||
import org.glyptodon.guacamole.GuacamoleClientException;
|
||||
import org.glyptodon.guacamole.GuacamoleConnectionClosedException;
|
||||
import org.glyptodon.guacamole.protocol.GuacamoleStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -178,6 +179,10 @@ public abstract class GuacamoleWebSocketTunnelEndpoint extends Endpoint {
|
||||
logger.warn("Client request rejected: {}", e.getMessage());
|
||||
closeConnection(session, e.getStatus());
|
||||
}
|
||||
catch (GuacamoleConnectionClosedException e) {
|
||||
logger.debug("Connection closed.", e);
|
||||
closeConnection(session, GuacamoleStatus.SUCCESS);
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
logger.error("Internal server error.", e);
|
||||
closeConnection(session, e.getStatus());
|
||||
@@ -205,6 +210,9 @@ public abstract class GuacamoleWebSocketTunnelEndpoint extends Endpoint {
|
||||
// Write received message
|
||||
writer.write(message.toCharArray());
|
||||
}
|
||||
catch (GuacamoleConnectionClosedException e) {
|
||||
logger.debug("Connection closed.", e);
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
logger.debug("Tunnel write failed.", e);
|
||||
}
|
||||
|
Reference in New Issue
Block a user