diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java
deleted file mode 100644
index ac1176975..000000000
--- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleClient.java
+++ /dev/null
@@ -1,134 +0,0 @@
-
-package net.sourceforge.guacamole;
-
-import java.util.LinkedList;
-import net.sourceforge.guacamole.GuacamoleInstruction.Operation;
-import net.sourceforge.guacamole.net.Configuration;
-
-/*
- * 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 abstract class GuacamoleClient {
-
- public abstract void write(char[] chunk, int off, int len) throws GuacamoleException;
-
- public void write(char[] chunk) throws GuacamoleException {
- write(chunk, 0, chunk.length);
- }
-
- public void write(GuacamoleInstruction instruction) throws GuacamoleException {
- write(instruction.toString().toCharArray());
- }
-
- public abstract char[] read() throws GuacamoleException;
-
- private int instructionStart;
- private char[] buffer;
-
- public GuacamoleInstruction readInstruction() throws GuacamoleException {
-
- // Fill buffer if not already filled
- if (buffer == null) {
- buffer = read();
- instructionStart = 0;
- }
-
- // Locate end-of-opcode and end-of-instruction
- int opcodeEnd = -1;
- int instructionEnd = -1;
-
- for (int i=instructionStart; i opcodeEnd)
- args = new String(buffer, opcodeEnd+1, instructionEnd - opcodeEnd - 1).split(",");
- else
- args = new String[0];
-
- // Create instruction
- GuacamoleInstruction instruction = new GuacamoleInstruction(
- Operation.fromOpcode(opcode),
- args
- );
-
- // Advance buffer
- instructionStart = instructionEnd + 1;
- if (instructionStart >= buffer.length)
- buffer = null;
-
- return instruction;
-
- }
-
- public abstract void disconnect() throws GuacamoleException;
-
- public void connect(Configuration config) throws GuacamoleException {
-
- // Send protocol
- write(new GuacamoleInstruction(Operation.CLIENT_SELECT, config.getProtocol()));
-
- // Wait for server args
- GuacamoleInstruction instruction;
- do {
- instruction = readInstruction();
- } while (instruction.getOperation() != Operation.SERVER_ARGS);
-
- // Build args list off provided names and config
- String[] args = new String[instruction.getArgs().length];
- for (int i=0; i.
+ */
+
+public interface GuacamoleReader {
+
+ public char[] read() throws GuacamoleException;
+ public GuacamoleInstruction readInstruction() throws GuacamoleException;
+
+}
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java
new file mode 100644
index 000000000..2d0168ed1
--- /dev/null
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/GuacamoleWriter.java
@@ -0,0 +1,31 @@
+
+package net.sourceforge.guacamole.io;
+
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.protocol.GuacamoleInstruction;
+
+/*
+ * 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 GuacamoleWriter {
+
+ public void write(char[] chunk, int off, int len) throws GuacamoleException;
+ public void write(char[] chunk) throws GuacamoleException;
+ public void writeInstruction(GuacamoleInstruction instruction) throws GuacamoleException;
+
+}
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java
similarity index 53%
rename from guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java
rename to guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java
index 0a1c254e7..a99f4055f 100644
--- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleTCPClient.java
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/ReaderGuacamoleReader.java
@@ -1,5 +1,13 @@
-package net.sourceforge.guacamole;
+package net.sourceforge.guacamole.io;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.protocol.GuacamoleInstruction;
+import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation;
+import net.sourceforge.guacamole.protocol.Configuration;
/*
* Guacamole - Clientless Remote Desktop
@@ -19,77 +27,21 @@ package net.sourceforge.guacamole;
* along with this program. If not, see .
*/
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
+public class ReaderGuacamoleReader implements GuacamoleReader {
-import java.io.Reader;
-import java.io.InputStreamReader;
-
-import java.io.Writer;
-import java.io.OutputStreamWriter;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-
-
-public class GuacamoleTCPClient extends GuacamoleClient {
-
- private static final int SOCKET_TIMEOUT = 15000;
-
- private Socket sock;
private Reader input;
- private Writer output;
- public GuacamoleTCPClient(String hostname, int port) throws GuacamoleException {
-
- try {
-
- // Get address
- SocketAddress address = new InetSocketAddress(
- InetAddress.getByName(hostname),
- port
- );
-
- // Connect with timeout
- sock = new Socket();
- sock.connect(address, SOCKET_TIMEOUT);
-
- // Set read timeout
- sock.setSoTimeout(SOCKET_TIMEOUT);
-
- // On successful connect, retrieve I/O streams
- input = new InputStreamReader(sock.getInputStream());
- output = new OutputStreamWriter(sock.getOutputStream());
-
- }
- catch (IOException e) {
- throw new GuacamoleException(e);
- }
-
- }
-
- public void write(char[] chunk, int off, int len) throws GuacamoleException {
- try {
- output.write(chunk, off, len);
- output.flush();
- }
- catch (IOException e) {
- throw new GuacamoleException(e);
- }
- }
-
- public void disconnect() throws GuacamoleException {
- try {
- sock.close();
- }
- catch (IOException e) {
- throw new GuacamoleException(e);
- }
+ public ReaderGuacamoleReader(Reader input) {
+ this.input = input;
}
private int usedLength = 0;
private char[] buffer = new char[20000];
+ private int instructionStart;
+ private char[] instructionBuffer;
+
+ @Override
public char[] read() throws GuacamoleException {
try {
@@ -142,4 +94,64 @@ public class GuacamoleTCPClient extends GuacamoleClient {
}
+ @Override
+ public GuacamoleInstruction readInstruction() throws GuacamoleException {
+
+ // Fill instructionBuffer if not already filled
+ if (instructionBuffer == null) {
+ instructionBuffer = read();
+ instructionStart = 0;
+ }
+
+ // Locate end-of-opcode and end-of-instruction
+ int opcodeEnd = -1;
+ int instructionEnd = -1;
+
+ for (int i=instructionStart; i opcodeEnd)
+ args = new String(instructionBuffer, opcodeEnd+1, instructionEnd - opcodeEnd - 1).split(",");
+ else
+ args = new String[0];
+
+ // Create instruction
+ GuacamoleInstruction instruction = new GuacamoleInstruction(
+ Operation.fromOpcode(opcode),
+ args
+ );
+
+ // Advance instructionBuffer
+ instructionStart = instructionEnd + 1;
+ if (instructionStart >= instructionBuffer.length)
+ instructionBuffer = null;
+
+ return instruction;
+
+ }
+
}
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java
new file mode 100644
index 000000000..db6fc849b
--- /dev/null
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/io/WriterGuacamoleWriter.java
@@ -0,0 +1,59 @@
+
+package net.sourceforge.guacamole.io;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.protocol.GuacamoleInstruction;
+import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation;
+import net.sourceforge.guacamole.protocol.Configuration;
+
+/*
+ * 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 WriterGuacamoleWriter implements GuacamoleWriter {
+
+ private Writer output;
+
+ public WriterGuacamoleWriter(Writer output) {
+ this.output = output;
+ }
+
+ @Override
+ public void write(char[] chunk, int off, int len) throws GuacamoleException {
+ try {
+ output.write(chunk, off, len);
+ output.flush();
+ }
+ catch (IOException e) {
+ throw new GuacamoleException(e);
+ }
+ }
+
+ @Override
+ public void write(char[] chunk) throws GuacamoleException {
+ write(chunk, 0, chunk.length);
+ }
+
+ @Override
+ public void writeInstruction(GuacamoleInstruction instruction) throws GuacamoleException {
+ write(instruction.toString().toCharArray());
+ }
+
+}
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java
new file mode 100644
index 000000000..3d999ce06
--- /dev/null
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/AbstractGuacamoleSocket.java
@@ -0,0 +1,69 @@
+
+package net.sourceforge.guacamole.net;
+
+import net.sourceforge.guacamole.io.GuacamoleReader;
+import net.sourceforge.guacamole.io.GuacamoleWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.protocol.GuacamoleInstruction;
+import net.sourceforge.guacamole.protocol.GuacamoleInstruction.Operation;
+import net.sourceforge.guacamole.protocol.Configuration;
+
+/*
+ * 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 abstract class AbstractGuacamoleSocket implements GuacamoleSocket {
+
+ @Override
+ public void connect(Configuration config) throws GuacamoleException {
+
+ // Get reader and writer
+ GuacamoleReader reader = getReader();
+ GuacamoleWriter writer = getWriter();
+
+ // Send protocol
+ writer.writeInstruction(new GuacamoleInstruction(Operation.CLIENT_SELECT, config.getProtocol()));
+
+ // Wait for server args
+ GuacamoleInstruction instruction;
+ do {
+ instruction = reader.readInstruction();
+ } while (instruction.getOperation() != Operation.SERVER_ARGS);
+
+ // Build args list off provided names and config
+ String[] args = new String[instruction.getArgs().length];
+ for (int i=0; i.
*/
-import java.util.UUID;
-import java.util.concurrent.locks.ReentrantLock;
-import net.sourceforge.guacamole.GuacamoleClient;
-import net.sourceforge.guacamole.GuacamoleException;
+public interface GuacamoleSocket {
-public class GuacamoleTunnel {
+ public GuacamoleReader getReader();
+ public GuacamoleWriter getWriter();
- private UUID uuid;
- private GuacamoleClient client;
- private ReentrantLock instructionStreamLock;
-
- public GuacamoleTunnel(GuacamoleClient client) throws GuacamoleException {
-
- this.client = client;
- instructionStreamLock = new ReentrantLock();
- uuid = UUID.randomUUID();
-
- }
-
- public GuacamoleClient getClient() throws GuacamoleException {
- return client;
- }
-
- public ReentrantLock getInstructionStreamLock() {
- return instructionStreamLock;
- }
-
- public UUID getUUID() {
- return uuid;
- }
+ public void connect(Configuration config) throws GuacamoleException;
+ public void disconnect() throws GuacamoleException;
}
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java
new file mode 100644
index 000000000..3d586ff41
--- /dev/null
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleTunnel.java
@@ -0,0 +1,77 @@
+
+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.util.UUID;
+import java.util.concurrent.locks.ReentrantLock;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.io.GuacamoleReader;
+import net.sourceforge.guacamole.net.GuacamoleSocket;
+import net.sourceforge.guacamole.io.GuacamoleWriter;
+
+public class GuacamoleTunnel {
+
+ private UUID uuid;
+ private GuacamoleSocket socket;
+
+ private ReentrantLock readerLock;
+ private ReentrantLock writerLock;
+
+ public GuacamoleTunnel(GuacamoleSocket socket) throws GuacamoleException {
+
+ this.socket = socket;
+ uuid = UUID.randomUUID();
+
+ readerLock = new ReentrantLock();
+ writerLock = new ReentrantLock();
+
+ }
+
+ public GuacamoleReader acquireReader() {
+ readerLock.lock();
+ return socket.getReader();
+ }
+
+ public void releaseReader() {
+ readerLock.unlock();
+ }
+
+ public boolean hasQueuedReaderThreads() {
+ return readerLock.hasQueuedThreads();
+ }
+
+ public GuacamoleWriter acquireWriter() {
+ writerLock.lock();
+ return socket.getWriter();
+ }
+
+ public void releaseWriter() {
+ writerLock.unlock();
+ }
+
+ public boolean hasQueuedWriterThreads() {
+ return writerLock.hasQueuedThreads();
+ }
+
+ public UUID getUUID() {
+ return uuid;
+ }
+
+}
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java
new file mode 100644
index 000000000..15feafb34
--- /dev/null
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/net/TCPGuacamoleSocket.java
@@ -0,0 +1,95 @@
+
+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.io.GuacamoleReader;
+import net.sourceforge.guacamole.io.ReaderGuacamoleReader;
+import net.sourceforge.guacamole.io.WriterGuacamoleWriter;
+import net.sourceforge.guacamole.io.GuacamoleWriter;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+
+import java.io.InputStreamReader;
+
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import net.sourceforge.guacamole.GuacamoleException;
+
+
+public class TCPGuacamoleSocket extends AbstractGuacamoleSocket {
+
+ private GuacamoleReader reader;
+ private GuacamoleWriter writer;
+
+ private static final int SOCKET_TIMEOUT = 15000;
+ private Socket sock;
+
+ public TCPGuacamoleSocket(String hostname, int port) throws GuacamoleException {
+
+ try {
+
+ // Get address
+ SocketAddress address = new InetSocketAddress(
+ InetAddress.getByName(hostname),
+ port
+ );
+
+ // Connect with timeout
+ sock = new Socket();
+ sock.connect(address, SOCKET_TIMEOUT);
+
+ // Set read timeout
+ sock.setSoTimeout(SOCKET_TIMEOUT);
+
+ // On successful connect, retrieve I/O streams
+ reader = new ReaderGuacamoleReader(new InputStreamReader(sock.getInputStream()));
+ writer = new WriterGuacamoleWriter(new OutputStreamWriter(sock.getOutputStream()));
+
+ }
+ catch (IOException e) {
+ throw new GuacamoleException(e);
+ }
+
+ }
+
+ @Override
+ public void disconnect() throws GuacamoleException {
+ try {
+ sock.close();
+ }
+ catch (IOException e) {
+ throw new GuacamoleException(e);
+ }
+ }
+
+ @Override
+ public GuacamoleReader getReader() {
+ return reader;
+ }
+
+ @Override
+ public GuacamoleWriter getWriter() {
+ return writer;
+ }
+
+
+}
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java
similarity index 96%
rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java
rename to guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java
index b086cf1ac..7e4362590 100644
--- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/Configuration.java
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/Configuration.java
@@ -1,5 +1,5 @@
-package net.sourceforge.guacamole.net;
+package net.sourceforge.guacamole.protocol;
import java.util.HashMap;
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java
similarity index 98%
rename from guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java
rename to guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java
index d6d3e9c62..153b9e20f 100644
--- a/guacamole-common/src/main/java/net/sourceforge/guacamole/GuacamoleInstruction.java
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/protocol/GuacamoleInstruction.java
@@ -1,5 +1,5 @@
-package net.sourceforge.guacamole;
+package net.sourceforge.guacamole.protocol;
import java.util.HashMap;
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java
similarity index 95%
rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java
rename to guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java
index 7cd90d93a..dcaaf394d 100644
--- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/GuacamoleSession.java
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleSession.java
@@ -1,5 +1,5 @@
-package net.sourceforge.guacamole.net;
+package net.sourceforge.guacamole.servlet;
/*
* Guacamole - Clientless Remote Desktop
@@ -19,11 +19,11 @@ package net.sourceforge.guacamole.net;
* along with this program. If not, see .
*/
-import net.sourceforge.guacamole.net.tunnel.GuacamoleTunnel;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.http.HttpSession;
import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.net.GuacamoleTunnel;
public class GuacamoleSession {
diff --git a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java
similarity index 90%
rename from guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java
rename to guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java
index 92ee60505..7848b2431 100644
--- a/guacamole-common/src/main/java/net/sourceforge/guacamole/net/tunnel/GuacamoleTunnelServlet.java
+++ b/guacamole-common/src/main/java/net/sourceforge/guacamole/servlet/GuacamoleTunnelServlet.java
@@ -1,4 +1,4 @@
-package net.sourceforge.guacamole.net.tunnel;
+package net.sourceforge.guacamole.servlet;
/*
* Guacamole - Clientless Remote Desktop
@@ -18,20 +18,21 @@ package net.sourceforge.guacamole.net.tunnel;
* along with this program. If not, see .
*/
+import net.sourceforge.guacamole.net.GuacamoleTunnel;
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;
+import net.sourceforge.guacamole.io.GuacamoleReader;
+import net.sourceforge.guacamole.net.GuacamoleSocket;
+import net.sourceforge.guacamole.io.GuacamoleWriter;
public abstract class GuacamoleTunnelServlet extends HttpServlet {
@@ -127,8 +128,8 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet {
if (tunnel == null)
throw new GuacamoleException("No such tunnel.");
- ReentrantLock instructionStreamLock = tunnel.getInstructionStreamLock();
- instructionStreamLock.lock();
+ // Obtain exclusive read access
+ GuacamoleReader reader = tunnel.acquireReader();
try {
@@ -139,12 +140,9 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet {
Writer out = response.getWriter();
- // Query new update from server
- GuacamoleClient client = tunnel.getClient();
-
// For all messages, until another stream is ready (we send at least one message)
char[] message;
- while ((message = client.read()) != null) {
+ while ((message = reader.read()) != null) {
// Get message output bytes
out.write(message, 0, message.length);
@@ -152,7 +150,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet {
response.flushBuffer();
// No more messages another stream can take over
- if (instructionStreamLock.hasQueuedThreads())
+ if (tunnel.hasQueuedReaderThreads())
break;
}
@@ -175,7 +173,7 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet {
throw new GuacamoleException("I/O error writing to servlet output stream.", e);
}
finally {
- instructionStreamLock.unlock();
+ tunnel.releaseReader();
}
}
@@ -199,19 +197,22 @@ public abstract class GuacamoleTunnelServlet extends HttpServlet {
// Send data
try {
- GuacamoleClient client = tunnel.getClient();
+ GuacamoleWriter writer = tunnel.acquireWriter();
Reader input = request.getReader();
char[] buffer = new char[8192];
int length;
while ((length = input.read(buffer, 0, buffer.length)) != -1)
- client.write(buffer, 0, length);
+ writer.write(buffer, 0, length);
}
catch (IOException e) {
throw new GuacamoleException("I/O Error sending data to server: " + e.getMessage(), e);
}
+ finally {
+ tunnel.releaseWriter();
+ }
}