Created new tunnel servlet API, removed old Connect/Inbound/Outbound servlets, removed ClientProviders, updated GuacamoleProperties accordingly.

This commit is contained in:
Michael Jumper
2011-01-23 15:24:00 -08:00
parent adb577ca8e
commit b39dc62167
7 changed files with 163 additions and 327 deletions

View File

@@ -21,10 +21,8 @@ package net.sourceforge.guacamole.net;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties; import java.util.Properties;
import net.sourceforge.guacamole.GuacamoleException; import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.authentication.GuacamoleClientProvider;
public class GuacamoleProperties { 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 { public static String getProperty(String name) throws GuacamoleException {
if (exception != null) throw exception; if (exception != null) throw exception;
return properties.getProperty(name); return properties.getProperty(name);

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
public interface GuacamoleClientProvider {
public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
public class NullGuacamoleClientProvider implements GuacamoleClientProvider {
public GuacamoleTCPClient createClient(HttpSession session) throws GuacamoleException {
throw new GuacamoleException("Null provider will not create clients.");
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}