From b39dc62167837a3febbe91825279c63326c2d7c8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 23 Jan 2011 15:24:00 -0800 Subject: [PATCH] Created new tunnel servlet API, removed old Connect/Inbound/Outbound servlets, removed ClientProviders, updated GuacamoleProperties accordingly. --- .../guacamole/net/GuacamoleProperties.java | 34 ---- .../GuacamoleClientProvider.java | 30 ---- .../NullGuacamoleClientProvider.java | 32 ---- .../guacamole/net/tunnel/Connect.java | 54 ------ .../net/tunnel/GuacamoleTunnelServlet.java | 163 ++++++++++++++++++ .../guacamole/net/tunnel/Inbound.java | 67 ------- .../guacamole/net/tunnel/Outbound.java | 110 ------------ 7 files changed, 163 insertions(+), 327 deletions(-) delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java create mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java delete mode 100644 guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java 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 97dff3552..647ffc44b 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,10 +21,8 @@ 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 { @@ -49,38 +47,6 @@ public class GuacamoleProperties { } - 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); diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java deleted file mode 100644 index 07e029cfa..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/GuacamoleClientProvider.java +++ /dev/null @@ -1,30 +0,0 @@ - -package net.sourceforge.guacamole.net.authentication; - -import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleTCPClient; -import net.sourceforge.guacamole.GuacamoleException; - -/* - * 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 . - */ - -public interface GuacamoleClientProvider { - - public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException; - -} diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java deleted file mode 100644 index d69908f63..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/authentication/NullGuacamoleClientProvider.java +++ /dev/null @@ -1,32 +0,0 @@ - -package net.sourceforge.guacamole.net.authentication; - -import javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.GuacamoleTCPClient; -import net.sourceforge.guacamole.GuacamoleException; - -/* - * 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 . - */ - -public class NullGuacamoleClientProvider implements GuacamoleClientProvider { - - public GuacamoleTCPClient 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 deleted file mode 100644 index 322578dec..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Connect.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.sourceforge.guacamole.net.tunnel; - -/* - * 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 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; -import net.sourceforge.guacamole.net.GuacamoleProperties; -import net.sourceforge.guacamole.net.GuacamoleSession; - - -public class Connect extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - - HttpSession httpSession = request.getSession(false); - - try { - - 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/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java new file mode 100644 index 000000000..68fbbe549 --- /dev/null +++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java @@ -0,0 +1,163 @@ +package net.sourceforge.guacamole.net.tunnel; + +/* + * 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 java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +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.GuacamoleClient; +import net.sourceforge.guacamole.GuacamoleException; +import net.sourceforge.guacamole.net.GuacamoleSession; + + +public abstract class GuacamoleTunnelServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { + service(request, response); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { + service(request, response); + } + + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException { + + try { + + String query = request.getQueryString(); + if (query == null) + throw new GuacamoleException("No query string provided."); + + if (query.equals("connect")) + doConnect(request, response); + + else if(query.equals("read")) + doRead(request, response); + + else if(query.equals("write")) + doWrite(request, response); + + else + throw new GuacamoleException("Invalid tunnel operation: " + query); + } + catch (GuacamoleException e) { + throw new ServletException(e); + } + + } + + protected abstract void doConnect(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException; + + protected void doRead(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + + HttpSession httpSession = request.getSession(false); + GuacamoleSession session = new GuacamoleSession(httpSession); + + ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); + instructionStreamLock.lock(); + + try { + + response.setContentType("text/plain"); + Writer out = response.getWriter(); + + try { + + // Query new update from server + GuacamoleClient 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(); + } + + // 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(); + } + + } + + protected void doWrite(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException { + + HttpSession httpSession = request.getSession(false); + GuacamoleSession session = new GuacamoleSession(httpSession); + + // 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); + } + + } + +} + 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 deleted file mode 100644 index 87007b14b..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Inbound.java +++ /dev/null @@ -1,67 +0,0 @@ -package net.sourceforge.guacamole.net.tunnel; - -/* - * 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.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 javax.servlet.http.HttpSession; -import net.sourceforge.guacamole.net.GuacamoleSession; - - -public class Inbound extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - - HttpSession httpSession = request.getSession(false); - - try { - - GuacamoleSession session = new GuacamoleSession(httpSession); - - // 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 (GuacamoleException 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 deleted file mode 100644 index 46ca3e891..000000000 --- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/Outbound.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.sourceforge.guacamole.net.tunnel; - -/* - * 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.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.GuacamoleClient; -import net.sourceforge.guacamole.GuacamoleException; -import net.sourceforge.guacamole.net.GuacamoleSession; - - -public class Outbound extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { - - HttpSession httpSession = request.getSession(false); - - try { - - GuacamoleSession session = new GuacamoleSession(httpSession); - - ReentrantLock instructionStreamLock = session.getInstructionStreamLock(); - instructionStreamLock.lock(); - - try { - - response.setContentType("text/plain"); - Writer out = response.getWriter(); - - try { - - // Query new update from server - GuacamoleClient 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(); - } - - // 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(); - } - - } - catch (GuacamoleException e) { - throw new ServletException(e); - } - - } - -} -