From 1430bed43e8a2728cae332c28a3391c337ea7923 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Jan 2011 02:36:31 -0800 Subject: [PATCH] API improvements --- .../guacamole/net/Configuration.java | 110 ++------------ .../guacamole/net/GuacamoleConfiguration.java | 80 ---------- .../guacamole/net/GuacamoleProperties.java | 139 ++++++++++++++++++ .../guacamole/net/GuacamoleServlet.java | 83 ----------- .../guacamole/net/GuacamoleSession.java | 58 +------- ...ider.java => GuacamoleClientProvider.java} | 6 +- ....java => NullGuacamoleClientProvider.java} | 8 +- .../guacamole/net/tunnel/Connect.java | 33 +++-- .../guacamole/net/tunnel/Inbound.java | 40 +++-- .../guacamole/net/tunnel/Outbound.java | 93 +++++++----- 10 files changed, 263 insertions(+), 387 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java rename guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/{GuacamoleSessionProvider.java => GuacamoleClientProvider.java} (82%) rename guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/{NullGuacamoleSessionProvider.java => NullGuacamoleClientProvider.java} (80%) diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java index 6e78eb296..b086cf1ac 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java @@ -1,6 +1,8 @@ package net.sourceforge.guacamole.net; +import java.util.HashMap; + /* * Guacamole - Clientless Remote Desktop * Copyright (C) 2010 Michael Jumper @@ -19,111 +21,25 @@ package net.sourceforge.guacamole.net; * along with this program. If not, see . */ -import javax.servlet.ServletContext; -import net.sourceforge.guacamole.GuacamoleException; +public class Configuration { -public abstract class Configuration { - - protected String humanReadableList(Object... values) { - - String list = ""; - for (int i=0; i= 1) - list += ", "; - - if (i == values.length -1) - list += " or "; - - list += "\"" + values[i] + "\""; - } - - return list; + private String protocol; + private HashMap parameters = new HashMap(); + public String getProtocol() { + return protocol; } - protected String readParameter(String name) throws GuacamoleException { - String value = GuacamoleProperties.getProperty(name); - return value; + public void setProtocol(String protocol) { + this.protocol = protocol; } - protected String readParameter(String name, String defaultValue, String... allowedValues) throws GuacamoleException { - - String value = GuacamoleProperties.getProperty(name); - - // Use default if not specified - if (value == null) { - if (defaultValue == null) - throw new GuacamoleException("Parameter \"" + name + "\" is required."); - - return defaultValue; - } - - // If not restricted to certain values, just return whatever is given. - if (allowedValues.length == 0) - return value; - - // If restricted, only return value within given list - for (String allowedValue : allowedValues) - if (value.equals(allowedValue)) - return value; - - throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues)); + public String getParameter(String name) { + return parameters.get(name); } - protected boolean readBooleanParameter(String name, Boolean defaultValue) throws GuacamoleException { - - String value = GuacamoleProperties.getProperty(name); - - // Use default if not specified - if (value == null) { - if (defaultValue == null) - throw new GuacamoleException("Parameter \"" + name + "\" is required."); - - return defaultValue; - } - - value = value.trim(); - if (value.equals("true")) - return true; - - if (value.equals("false")) - return false; - - throw new GuacamoleException("Parameter \"" + name + "\" must be \"true\" or \"false\"."); - - } - - protected int readIntParameter(String name, Integer defaultValue, Integer... allowedValues) throws GuacamoleException { - - String parmString = GuacamoleProperties.getProperty(name); - - // Use default if not specified - if (parmString== null) { - if (defaultValue == null) - throw new GuacamoleException("Parameter \"" + name + "\" is required."); - - return defaultValue; - } - - try { - int value = Integer.parseInt(parmString); - - // If not restricted to certain values, just return whatever is given. - if (allowedValues.length == 0) - return value; - - // If restricted, only return value within given list - for (int allowedValue : allowedValues) - if (value == allowedValue) - return value; - - throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues)); - } - catch (NumberFormatException e) { - throw new GuacamoleException("Parameter \"" + name + "\" must be an integer.", e); - } - + public void setParameter(String name, String value) { + parameters.put(name, value); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java deleted file mode 100644 index a6bfeeb52..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleConfiguration.java +++ /dev/null @@ -1,80 +0,0 @@ - -package net.sourceforge.guacamole.net; - -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import net.sourceforge.guacamole.net.authentication.GuacamoleSessionProvider; -import java.lang.reflect.InvocationTargetException; -import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleException; - -public class GuacamoleConfiguration extends Configuration { - - private String guacd_hostname; - private int guacd_port; - private GuacamoleSessionProvider sessionProvider; - - public GuacamoleConfiguration() throws GuacamoleException { - - guacd_hostname = readParameter("guacd-hostname"); - guacd_port = readIntParameter("guacd-port", null); - - // Get session provider instance - try { - String sessionProviderClassName = readParameter("session-provider"); - Object obj = Class.forName(sessionProviderClassName).getConstructor().newInstance(); - if (!(obj instanceof GuacamoleSessionProvider)) - throw new GuacamoleException("Specified session provider class is not a GuacamoleSessionProvider"); - - sessionProvider = (GuacamoleSessionProvider) obj; - } - catch (ClassNotFoundException e) { - throw new GuacamoleException("Session provider class not found", e); - } - catch (NoSuchMethodException e) { - throw new GuacamoleException("Default constructor for session provider not present", e); - } - catch (SecurityException e) { - throw new GuacamoleException("Creation of session provider disallowed; check your security settings", e); - } - catch (InstantiationException e) { - throw new GuacamoleException("Unable to instantiate session provider", e); - } - catch (IllegalAccessException e) { - throw new GuacamoleException("Unable to access default constructor of session provider", e); - } - catch (InvocationTargetException e) { - throw new GuacamoleException("Internal error in constructor of session provider", e.getTargetException()); - } - - } - - public int getProxyPort() { - return guacd_port; - } - - public String getProxyHostname() { - return guacd_hostname; - } - - public GuacamoleSession createSession(HttpSession session) throws GuacamoleException { - return sessionProvider.createSession(session); - } - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java index 6c4340dd1..f68c2e4a6 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleProperties.java @@ -21,8 +21,10 @@ package net.sourceforge.guacamole.net; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; import java.util.Properties; import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.authentication.GuacamoleClientProvider; public class GuacamoleProperties { @@ -47,9 +49,146 @@ public class GuacamoleProperties { } + public static String getProxyHostname() throws GuacamoleException { + return GuacamoleProperties.getProperty("guacd-hostname"); + } + + public static int getProxyPort() throws GuacamoleException { + return GuacamoleProperties.getIntProperty("guacd-port", null); + } + + public static GuacamoleClientProvider getClientProvider() throws GuacamoleException { + + // Get client provider instance + try { + String sessionProviderClassName = GuacamoleProperties.getProperty("client-provider"); + Object obj = Class.forName(sessionProviderClassName).getConstructor().newInstance(); + if (!(obj instanceof GuacamoleClientProvider)) + throw new GuacamoleException("Specified client provider class is not a GuacamoleClientProvider"); + + return (GuacamoleClientProvider) obj; + } + catch (ClassNotFoundException e) { + throw new GuacamoleException("Session provider class not found", e); + } + catch (NoSuchMethodException e) { + throw new GuacamoleException("Default constructor for client provider not present", e); + } + catch (SecurityException e) { + throw new GuacamoleException("Creation of client provider disallowed; check your security settings", e); + } + catch (InstantiationException e) { + throw new GuacamoleException("Unable to instantiate client provider", e); + } + catch (IllegalAccessException e) { + throw new GuacamoleException("Unable to access default constructor of client provider", e); + } + catch (InvocationTargetException e) { + throw new GuacamoleException("Internal error in constructor of client provider", e.getTargetException()); + } + + } + public static String getProperty(String name) throws GuacamoleException { if (exception != null) throw exception; return properties.getProperty(name); } + protected static String humanReadableList(Object... values) { + + String list = ""; + for (int i=0; i= 1) + list += ", "; + + if (i == values.length -1) + list += " or "; + + list += "\"" + values[i] + "\""; + } + + return list; + + } + + public static String getProperty(String name, String defaultValue, String... allowedValues) throws GuacamoleException { + + String value = getProperty(name); + + // Use default if not specified + if (value == null) { + if (defaultValue == null) + throw new GuacamoleException("Parameter \"" + name + "\" is required."); + + return defaultValue; + } + + // If not restricted to certain values, just return whatever is given. + if (allowedValues.length == 0) + return value; + + // If restricted, only return value within given list + for (String allowedValue : allowedValues) + if (value.equals(allowedValue)) + return value; + + throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues)); + } + + public static boolean getBooleanProperty(String name, Boolean defaultValue) throws GuacamoleException { + + String value = getProperty(name); + + // Use default if not specified + if (value == null) { + if (defaultValue == null) + throw new GuacamoleException("Parameter \"" + name + "\" is required."); + + return defaultValue; + } + + value = value.trim(); + if (value.equals("true")) + return true; + + if (value.equals("false")) + return false; + + throw new GuacamoleException("Parameter \"" + name + "\" must be \"true\" or \"false\"."); + + } + + public static int getIntProperty(String name, Integer defaultValue, Integer... allowedValues) throws GuacamoleException { + + String parmString = getProperty(name); + + // Use default if not specified + if (parmString== null) { + if (defaultValue == null) + throw new GuacamoleException("Parameter \"" + name + "\" is required."); + + return defaultValue; + } + + try { + int value = Integer.parseInt(parmString); + + // If not restricted to certain values, just return whatever is given. + if (allowedValues.length == 0) + return value; + + // If restricted, only return value within given list + for (int allowedValue : allowedValues) + if (value == allowedValue) + return value; + + throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues)); + } + catch (NumberFormatException e) { + throw new GuacamoleException("Parameter \"" + name + "\" must be an integer.", e); + } + + } + } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java deleted file mode 100644 index a1e713132..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleServlet.java +++ /dev/null @@ -1,83 +0,0 @@ - -package net.sourceforge.guacamole.net; - -/* - * Guacamole - Clientless Remote Desktop - * Copyright (C) 2010 Michael Jumper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import java.io.IOException; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleException; - -public abstract class GuacamoleServlet extends HttpServlet { - - private GuacamoleConfiguration config; - - @Override - public void init() throws ServletException { - try { - this.config = new GuacamoleConfiguration(); - } - catch (GuacamoleException e) { - throw new ServletException(e); - } - } - - @Override - protected final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - try { - handleRequest(req, resp); - } - catch (GuacamoleException e) { - throw new ServletException(e); - } - } - - @Override - protected final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - try { - handleRequest(req, resp); - } - catch (GuacamoleException e) { - throw new ServletException(e); - } - } - - private final void handleRequest(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { - - HttpSession httpSession = request.getSession(shouldCreateSession()); - - if (httpSession != null) { - GuacamoleSession session = config.createSession(httpSession); - handleRequest(session, request, response); - } - else - throw new GuacamoleException("No session"); - } - - protected abstract void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException; - - protected boolean shouldCreateSession() { - return false; - } - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java index 57568e5ad..10699246e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java @@ -19,7 +19,6 @@ package net.sourceforge.guacamole.net; * along with this program. If not, see . */ -import java.util.HashMap; import java.util.concurrent.locks.ReentrantLock; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionBindingEvent; @@ -30,31 +29,10 @@ import net.sourceforge.guacamole.GuacamoleException; public class GuacamoleSession { - private GuacamoleConfiguration config; - private final HttpSession session; private SessionClient client; private ReentrantLock instructionStreamLock; - private String protocol; - private HashMap parameters = new HashMap(); - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getParameter(String name) { - return parameters.get(name); - } - - public void setParameter(String name, String value) { - parameters.put(name, value); - } - public class SessionClient extends Client implements HttpSessionBindingListener { private Client client; @@ -96,34 +74,22 @@ public class GuacamoleSession { throw new GuacamoleException("User has no session."); this.session = session; - synchronized (session) { - // Read configuration parameters - config = new GuacamoleConfiguration(); + synchronized (session) { client = (SessionClient) session.getAttribute("CLIENT"); instructionStreamLock = (ReentrantLock) session.getAttribute("INSTRUCTION_STREAM_LOCK"); + } } - public void connect() throws GuacamoleException { + public void attachClient(GuacamoleClient client) throws GuacamoleException { synchronized (session) { - if (client != null) - client.disconnect(); - - client = new SessionClient( - new GuacamoleClient ( - config.getProxyHostname(), - config.getProxyPort() - ) - ); - - // TODO: Send "select" and "connect" messages here. - - session.setAttribute("CLIENT", client); + this.client = new SessionClient(client); + session.setAttribute("CLIENT", this.client); instructionStreamLock = new ReentrantLock(); session.setAttribute("INSTRUCTION_STREAM_LOCK", instructionStreamLock); @@ -132,21 +98,11 @@ public class GuacamoleSession { } - public boolean isConnected() { - synchronized (session) { - return client != null; - } - } - - public GuacamoleConfiguration getConfiguration() { - return config; - } - public SessionClient getClient() throws GuacamoleException { synchronized (session) { if (client == null) - throw new GuacamoleException("Client not yet connected."); + throw new GuacamoleException("Client not yet attached."); return client; } @@ -156,7 +112,7 @@ public class GuacamoleSession { session.invalidate(); } - public void disconnect() throws GuacamoleException { + public void detachClient() throws GuacamoleException { synchronized (session) { diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java similarity index 82% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java index bbe82a2de..a4989dcac 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleSessionProvider.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java @@ -2,8 +2,8 @@ package net.sourceforge.guacamole.net.authentication; import javax.servlet.http.HttpSession; +import net.sourceforge.guacamole.GuacamoleClient; import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.GuacamoleSession; /* * Guacamole - Clientless Remote Desktop @@ -23,8 +23,8 @@ import net.sourceforge.guacamole.net.GuacamoleSession; * along with this program. If not, see . */ -public interface GuacamoleSessionProvider { +public interface GuacamoleClientProvider { - public GuacamoleSession createSession(HttpSession session) throws GuacamoleException; + public GuacamoleClient createClient(HttpSession session) throws GuacamoleException; } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java similarity index 80% rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java rename to guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java index a46d0fe57..786939553 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleSessionProvider.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java @@ -2,8 +2,8 @@ package net.sourceforge.guacamole.net.authentication; import javax.servlet.http.HttpSession; +import net.sourceforge.guacamole.GuacamoleClient; import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.GuacamoleSession; /* * Guacamole - Clientless Remote Desktop @@ -23,10 +23,10 @@ import net.sourceforge.guacamole.net.GuacamoleSession; * along with this program. If not, see . */ -public class NullGuacamoleSessionProvider implements GuacamoleSessionProvider { +public class NullGuacamoleClientProvider implements GuacamoleClientProvider { - public GuacamoleSession createSession(HttpSession session) throws GuacamoleException { - throw new GuacamoleException("Null provider will not create sessions"); + public GuacamoleClient createClient(HttpSession session) throws GuacamoleException { + throw new GuacamoleException("Null provider will not create clients."); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java index 273aab895..322578dec 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java @@ -18,30 +18,35 @@ package net.sourceforge.guacamole.net.tunnel; * along with this program. If not, see . */ -import net.sourceforge.guacamole.GuacamoleException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import net.sourceforge.guacamole.net.GuacamoleServlet; - +import javax.servlet.http.HttpSession; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.GuacamoleProperties; import net.sourceforge.guacamole.net.GuacamoleSession; -public class Connect extends GuacamoleServlet { + +public class Connect extends HttpServlet { @Override - protected boolean shouldCreateSession() { - return true; - } + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - @Override - protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + HttpSession httpSession = request.getSession(false); - // Disconnect if already connected - if (session.isConnected()) - session.disconnect(); + try { - // Obtain new connection - session.connect(); + GuacamoleSession session = new GuacamoleSession(httpSession); + session.attachClient( + GuacamoleProperties.getClientProvider().createClient(httpSession) + ); + + } + catch (GuacamoleException e) { + throw new ServletException(e); + } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java index 8a939c07c..87007b14b 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java @@ -22,33 +22,43 @@ import net.sourceforge.guacamole.GuacamoleException; import java.io.Reader; import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import net.sourceforge.guacamole.net.GuacamoleServlet; - +import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.net.GuacamoleSession; -public class Inbound extends GuacamoleServlet { + +public class Inbound extends HttpServlet { @Override - protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { - - // Send data + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { + + HttpSession httpSession = request.getSession(false); + try { - Reader input = request.getReader(); - char[] buffer = new char[8192]; + GuacamoleSession session = new GuacamoleSession(httpSession); - int length; - while ((length = input.read(buffer, 0, buffer.length)) != -1) - session.getClient().write(buffer, 0, length); + // Send data + try { + + Reader input = request.getReader(); + char[] buffer = new char[8192]; + + int length; + while ((length = input.read(buffer, 0, buffer.length)) != -1) + session.getClient().write(buffer, 0, length); + + } + catch (IOException e) { + throw new GuacamoleException("I/O Error sending data to server: " + e.getMessage(), e); + } - } - catch (IOException e) { - throw new GuacamoleException("I/O Error sending data to server: " + e.getMessage(), e); } catch (GuacamoleException e) { - throw new GuacamoleException("Error sending data to server: " + e.getMessage(), e); + throw new ServletException(e); } } diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java index 942a2d72d..5b09c463e 100644 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java @@ -22,73 +22,86 @@ import java.io.Writer; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.concurrent.locks.ReentrantLock; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import net.sourceforge.guacamole.Client; -import net.sourceforge.guacamole.net.GuacamoleServlet; import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.net.GuacamoleSession; -public class Outbound extends GuacamoleServlet { +public class Outbound extends HttpServlet { @Override - protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); - instructionStreamLock.lock(); + HttpSession httpSession = request.getSession(false); try { - response.setContentType("text/plain"); - Writer out = response.getWriter(); + GuacamoleSession session = new GuacamoleSession(httpSession); + + ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); + instructionStreamLock.lock(); try { - // Query new update from server - Client client = session.getClient(); + response.setContentType("text/plain"); + Writer out = response.getWriter(); - // For all messages, until another stream is ready (we send at least one message) - char[] message; - while ((message = client.read()) != null) { + try { - // Get message output bytes - out.write(message, 0, message.length); + // Query new update from server + Client client = session.getClient(); + + // For all messages, until another stream is ready (we send at least one message) + char[] message; + while ((message = client.read()) != null) { + + // Get message output bytes + out.write(message, 0, message.length); + out.flush(); + response.flushBuffer(); + + // No more messages another stream can take over + if (instructionStreamLock.hasQueuedThreads()) + break; + + } + + if (message == null) { + session.detachClient(); + throw new GuacamoleException("Disconnected."); + } + + } + catch (GuacamoleException e) { + out.write("error:" + e.getMessage() + ";"); out.flush(); response.flushBuffer(); - - // No more messages another stream can take over - if (instructionStreamLock.hasQueuedThreads()) - break; - } - if (message == null) { - session.disconnect(); - throw new GuacamoleException("Disconnected."); - } - - } - catch (GuacamoleException e) { - out.write("error:" + e.getMessage() + ";"); + // End-of-instructions marker + out.write(';'); out.flush(); response.flushBuffer(); + + } + catch (UnsupportedEncodingException e) { + throw new ServletException("UTF-8 not supported by Java.", e); + } + catch (IOException e) { + throw new ServletException("I/O error writing to servlet output stream.", e); + } + finally { + instructionStreamLock.unlock(); } - // End-of-instructions marker - out.write(';'); - out.flush(); - response.flushBuffer(); - } - catch (UnsupportedEncodingException e) { - throw new GuacamoleException("UTF-8 not supported by Java.", e); - } - catch (IOException e) { - throw new GuacamoleException("I/O error writing to servlet output stream.", e); - } - finally { - instructionStreamLock.unlock(); + catch (GuacamoleException e) { + throw new ServletException(e); } }