diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/resource/BasicResource.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/resource/BasicResource.java
index ebf1892ab..6c0fe335a 100644
--- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/resource/BasicResource.java
+++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/resource/BasicResource.java
@@ -46,6 +46,7 @@ public class BasicResource extends AuthenticatingHttpServlet {
int index = Integer.parseInt(indexString);
String name = request.getParameter("name");
String tunnelUUID = request.getParameter("uuid");
+ String mimetype = request.getParameter("mimetype");
// Get session
GuacamoleSession session;
@@ -68,6 +69,9 @@ public class BasicResource extends AuthenticatingHttpServlet {
if (name != null)
response.setHeader("Content-Disposition", "attachment; filename=" + name);
+ // If mimetype provided, reflect back
+ response.setContentType(mimetype);
+
// Get output stream and pipe
OutputStream out = response.getOutputStream();
GuacamoleResourcePipe resourcePipe = tunnel.getResourcePipe(index);
diff --git a/guacamole/src/main/webapp/WEB-INF/web.xml b/guacamole/src/main/webapp/WEB-INF/web.xml
index 0837d5f11..94d79fd38 100644
--- a/guacamole/src/main/webapp/WEB-INF/web.xml
+++ b/guacamole/src/main/webapp/WEB-INF/web.xml
@@ -88,4 +88,13 @@
/resource
+
+ mp3
+ audio/mpeg
+
+
+ ogg
+ audio/ogg
+
+
diff --git a/guacamole/src/main/webapp/scripts/interface.js b/guacamole/src/main/webapp/scripts/interface.js
index 88224a2bd..8900b8e7b 100644
--- a/guacamole/src/main/webapp/scripts/interface.js
+++ b/guacamole/src/main/webapp/scripts/interface.js
@@ -62,6 +62,9 @@ var GuacamoleUI = {
};
+// Supported mimetypes
+GuacamoleUI.supportedAudio = {};
+
// Constant UI initialization and behavior
(function() {
@@ -485,6 +488,33 @@ var GuacamoleUI = {
GuacamoleUI.eventTarget.style.top = window.pageYOffset + "px";
});
+ function testAudio(url, mimetype) {
+
+ // If browser says we can't play it, don't try
+ var audio = new Audio();
+ if (!audio.canPlayType(mimetype))
+ return;
+
+ // Otherwise, test
+ audio.src = url;
+
+ // On error, explicitly unsupported
+ audio.addEventListener("error", function() {
+ GuacamoleUI.supportedAudio[mimetype] = false;
+ });
+
+ // On successful play, explicitly supported
+ audio.addEventListener("ended", function() {
+ GuacamoleUI.supportedAudio[mimetype] = true;
+ });
+
+ audio.play();
+
+ }
+
+ testAudio("sounds/silence.mp3", "audio/mpeg");
+ testAudio("sounds/silence.ogg", "audio/ogg");
+
})();
// Tie UI events / behavior to a specific Guacamole client
@@ -792,9 +822,10 @@ GuacamoleUI.attach = function(guac) {
// Start download
GuacamoleUI.download.src =
- "resource?index=" + index
- + "&name=" + name
- + "&uuid=" + uuid;
+ "resource?index=" + index
+ + "&name=" + name
+ + "&uuid=" + uuid
+ + "&mimetype=" + mimetypes[0];
}
@@ -805,6 +836,64 @@ GuacamoleUI.attach = function(guac) {
}
+ // Audio resource
+ else if (uri.substring(0, 8) == "audio://") {
+
+ // Create audio playing object
+ var audio = new Audio();
+
+ // Determine a supported mimetype
+ var mimetype = null;
+ for (var i=0; i