From 4334cf7d7641da7de7a1c01e4f56c303dc530d6c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 2 Mar 2014 19:26:55 -0800 Subject: [PATCH] Use servlet to retrieve clipboard state. --- .../guacamole/net/basic/CaptureClipboard.java | 79 +++++++++++++++++++ guacamole/src/main/webapp/WEB-INF/web.xml | 11 +++ guacamole/src/main/webapp/client.xhtml | 1 + .../src/main/webapp/scripts/client-ui.js | 8 +- guacamole/src/main/webapp/scripts/service.js | 25 ++++++ 5 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 guacamole/src/main/java/org/glyptodon/guacamole/net/basic/CaptureClipboard.java diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/CaptureClipboard.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/CaptureClipboard.java new file mode 100644 index 000000000..0aaec2f8b --- /dev/null +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/CaptureClipboard.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013 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.net.basic; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.glyptodon.guacamole.GuacamoleException; +import org.glyptodon.guacamole.GuacamoleServerException; +import org.glyptodon.guacamole.net.auth.UserContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Servlet which dumps the current contents of the clipboard. + * + * @author Michael Jumper + */ +public class CaptureClipboard extends AuthenticatingHttpServlet { + + /** + * Logger for this class. + */ + private Logger logger = LoggerFactory.getLogger(CaptureClipboard.class); + + /** + * The amount of time to wait for clipboard changes, in milliseconds. + */ + private static final int CLIPBOARD_TIMEOUT = 250; + + @Override + protected void authenticatedService( + UserContext context, + HttpServletRequest request, HttpServletResponse response) + throws GuacamoleException { + + // Get clipboard + final HttpSession session = request.getSession(true); + final ClipboardState clipboard = getClipboardState(session); + + // FIXME: Don't do this + try { + Thread.sleep(CLIPBOARD_TIMEOUT); + } + catch (InterruptedException e) { /* ignore */ } + + // Send clipboard contents + try { + response.setContentType("text/plain"); + response.getWriter().print(clipboard.getContents()); + } + catch (IOException e) { + throw new GuacamoleServerException("Unable to send clipboard contents", e); + } + + } + +} diff --git a/guacamole/src/main/webapp/WEB-INF/web.xml b/guacamole/src/main/webapp/WEB-INF/web.xml index 3f6fb6ec6..12d25d1ca 100644 --- a/guacamole/src/main/webapp/WEB-INF/web.xml +++ b/guacamole/src/main/webapp/WEB-INF/web.xml @@ -59,6 +59,17 @@ /logout + + + Clipboard state servlet. + Clipboard + org.glyptodon.guacamole.net.basic.CaptureClipboard + + + Clipboard + /clipboard + + Connection creation servlet. diff --git a/guacamole/src/main/webapp/client.xhtml b/guacamole/src/main/webapp/client.xhtml index 16bf7ba2a..1ed96f7cd 100644 --- a/guacamole/src/main/webapp/client.xhtml +++ b/guacamole/src/main/webapp/client.xhtml @@ -66,6 +66,7 @@ + diff --git a/guacamole/src/main/webapp/scripts/client-ui.js b/guacamole/src/main/webapp/scripts/client-ui.js index 52beedb80..f3cff081d 100644 --- a/guacamole/src/main/webapp/scripts/client-ui.js +++ b/guacamole/src/main/webapp/scripts/client-ui.js @@ -985,16 +985,16 @@ GuacUI.Client.attach = function(guac) { // Set local clipboard contents on cut document.body.addEventListener("cut", function handle_cut(e) { - /* STUB */ e.preventDefault(); - e.clipboardData.setData("text/plain", "STUB: CUT"); + var data = GuacamoleService.Clipboard.get(); + e.clipboardData.setData("text/plain", data); }, false); // Set local clipboard contents on copy document.body.addEventListener("copy", function handle_copy(e) { - /* STUB */ e.preventDefault(); - e.clipboardData.setData("text/plain", "STUB: COPY"); + var data = GuacamoleService.Clipboard.get(); + e.clipboardData.setData("text/plain", data); }, false); // Set remote clipboard contents on paste diff --git a/guacamole/src/main/webapp/scripts/service.js b/guacamole/src/main/webapp/scripts/service.js index 0e0e46973..9a2efc833 100644 --- a/guacamole/src/main/webapp/scripts/service.js +++ b/guacamole/src/main/webapp/scripts/service.js @@ -1410,3 +1410,28 @@ GuacamoleService.Protocols = { } }; + +/** + * Collection of service functions which deal with the clipboard state. Each + * function makes an explicit HTTP query to the server, and parses the response. + */ +GuacamoleService.Clipboard = { + + "get" : function(parameters) { + + // Construct request URL + var list_url = "clipboard"; + if (parameters) list_url += "?" + parameters; + + // Get permission list + var xhr = new XMLHttpRequest(); + xhr.open("GET", list_url, false); + xhr.send(null); + + // Handle response + GuacamoleService.handleResponse(xhr); + return xhr.responseText; + + } + +};