mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUAC-442: Tie new WebSocket implementation into authentication layer. Generalize tunnel requests.
This commit is contained in:
		| @@ -42,66 +42,9 @@ public class BasicGuacamoleTunnelServlet extends GuacamoleHTTPTunnelServlet { | ||||
|      */ | ||||
|     private static final Logger logger = LoggerFactory.getLogger(BasicGuacamoleTunnelServlet.class); | ||||
|  | ||||
|     /** | ||||
|      * All supported identifier types. | ||||
|      */ | ||||
|     public static enum IdentifierType { | ||||
|  | ||||
|         /** | ||||
|          * The unique identifier of a connection. | ||||
|          */ | ||||
|         CONNECTION("c/"), | ||||
|  | ||||
|         /** | ||||
|          * The unique identifier of a connection group. | ||||
|          */ | ||||
|         CONNECTION_GROUP("g/"); | ||||
|          | ||||
|         /** | ||||
|          * The prefix which precedes an identifier of this type. | ||||
|          */ | ||||
|         final String PREFIX; | ||||
|          | ||||
|         /** | ||||
|          * Defines an IdentifierType having the given prefix. | ||||
|          * @param prefix The prefix which will precede any identifier of this | ||||
|          *               type, thus differentiating it from other identifier | ||||
|          *               types. | ||||
|          */ | ||||
|         IdentifierType(String prefix) { | ||||
|             PREFIX = prefix; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Given an identifier, determines the corresponding identifier type. | ||||
|          *  | ||||
|          * @param identifier The identifier whose type should be identified. | ||||
|          * @return The identified identifier type. | ||||
|          */ | ||||
|         static IdentifierType getType(String identifier) { | ||||
|  | ||||
|             // If null, no known identifier | ||||
|             if (identifier == null) | ||||
|                 return null; | ||||
|  | ||||
|             // Connection identifiers | ||||
|             if (identifier.startsWith(CONNECTION.PREFIX)) | ||||
|                 return CONNECTION; | ||||
|              | ||||
|             // Connection group identifiers | ||||
|             if (identifier.startsWith(CONNECTION_GROUP.PREFIX)) | ||||
|                 return CONNECTION_GROUP; | ||||
|              | ||||
|             // Otherwise, unknown | ||||
|             return null; | ||||
|              | ||||
|         } | ||||
|          | ||||
|     }; | ||||
|      | ||||
|     @Override | ||||
|     protected GuacamoleTunnel doConnect(HttpServletRequest request) throws GuacamoleException { | ||||
|         return BasicTunnelRequestUtility.createTunnel(request); | ||||
|         return BasicTunnelRequestUtility.createTunnel(new HTTPTunnelRequest(request)); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -22,9 +22,8 @@ | ||||
|  | ||||
| package org.glyptodon.guacamole.net.basic; | ||||
|  | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import java.util.List; | ||||
| import javax.servlet.http.HttpSession; | ||||
| import org.glyptodon.guacamole.GuacamoleClientException; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| @@ -63,63 +62,6 @@ public class BasicTunnelRequestUtility { | ||||
|      */ | ||||
|     private static final Logger logger = LoggerFactory.getLogger(BasicTunnelRequestUtility.class); | ||||
|  | ||||
|     /** | ||||
|      * All supported identifier types. | ||||
|      */ | ||||
|     private static enum IdentifierType { | ||||
|  | ||||
|         /** | ||||
|          * The unique identifier of a connection. | ||||
|          */ | ||||
|         CONNECTION("c/"), | ||||
|  | ||||
|         /** | ||||
|          * The unique identifier of a connection group. | ||||
|          */ | ||||
|         CONNECTION_GROUP("g/"); | ||||
|          | ||||
|         /** | ||||
|          * The prefix which precedes an identifier of this type. | ||||
|          */ | ||||
|         final String PREFIX; | ||||
|          | ||||
|         /** | ||||
|          * Defines an IdentifierType having the given prefix. | ||||
|          * @param prefix The prefix which will precede any identifier of this | ||||
|          *               type, thus differentiating it from other identifier | ||||
|          *               types. | ||||
|          */ | ||||
|         IdentifierType(String prefix) { | ||||
|             PREFIX = prefix; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Given an identifier, determines the corresponding identifier type. | ||||
|          *  | ||||
|          * @param identifier The identifier whose type should be identified. | ||||
|          * @return The identified identifier type. | ||||
|          */ | ||||
|         static IdentifierType getType(String identifier) { | ||||
|  | ||||
|             // If null, no known identifier | ||||
|             if (identifier == null) | ||||
|                 return null; | ||||
|  | ||||
|             // Connection identifiers | ||||
|             if (identifier.startsWith(CONNECTION.PREFIX)) | ||||
|                 return CONNECTION; | ||||
|              | ||||
|             // Connection group identifiers | ||||
|             if (identifier.startsWith(CONNECTION_GROUP.PREFIX)) | ||||
|                 return CONNECTION_GROUP; | ||||
|              | ||||
|             // Otherwise, unknown | ||||
|             return null; | ||||
|              | ||||
|         } | ||||
|          | ||||
|     }; | ||||
|      | ||||
|     /** | ||||
|      * Notifies all listeners in the given collection that a tunnel has been | ||||
|      * connected. | ||||
| @@ -200,18 +142,21 @@ public class BasicTunnelRequestUtility { | ||||
|  | ||||
|     } | ||||
|  | ||||
|      | ||||
|     /** | ||||
|      * Creates a new tunnel using the parameters and credentials present in | ||||
|      * the given request. | ||||
|      *  | ||||
|      * @param request The HttpServletRequest describing the tunnel to create. | ||||
|      * @param request The request describing the tunnel to create. | ||||
|      * @return The created tunnel, or null if the tunnel could not be created. | ||||
|      * @throws GuacamoleException If an error occurs while creating the tunnel. | ||||
|      */ | ||||
|     public static GuacamoleTunnel createTunnel(HttpServletRequest request) | ||||
|     public static GuacamoleTunnel createTunnel(TunnelRequest request) | ||||
|             throws GuacamoleException { | ||||
|  | ||||
|         HttpSession httpSession = request.getSession(true); | ||||
|         HttpSession httpSession = request.getSession(); | ||||
|         if (httpSession == null) | ||||
|             throw new GuacamoleSecurityException("Cannot connect - user not logged in."); | ||||
|  | ||||
|         // Get listeners | ||||
|         final SessionListenerCollection listeners; | ||||
| @@ -225,7 +170,7 @@ public class BasicTunnelRequestUtility { | ||||
|  | ||||
|         // Get ID of connection | ||||
|         String id = request.getParameter("id"); | ||||
|         IdentifierType id_type = IdentifierType.getType(id); | ||||
|         TunnelRequest.IdentifierType id_type = TunnelRequest.IdentifierType.getType(id); | ||||
|  | ||||
|         // Do not continue if unable to determine type | ||||
|         if (id_type == null) | ||||
| @@ -266,14 +211,14 @@ public class BasicTunnelRequestUtility { | ||||
|             info.setOptimalResolution(Integer.parseInt(dpi)); | ||||
|  | ||||
|         // Add audio mimetypes | ||||
|         String[] audio_mimetypes = request.getParameterValues("audio"); | ||||
|         List<String> audio_mimetypes = request.getParameterValues("audio"); | ||||
|         if (audio_mimetypes != null) | ||||
|             info.getAudioMimetypes().addAll(Arrays.asList(audio_mimetypes)); | ||||
|             info.getAudioMimetypes().addAll(audio_mimetypes); | ||||
|  | ||||
|         // Add video mimetypes | ||||
|         String[] video_mimetypes = request.getParameterValues("video"); | ||||
|         List<String> video_mimetypes = request.getParameterValues("video"); | ||||
|         if (video_mimetypes != null) | ||||
|             info.getVideoMimetypes().addAll(Arrays.asList(video_mimetypes)); | ||||
|             info.getVideoMimetypes().addAll(video_mimetypes); | ||||
|  | ||||
|         // Create connected socket from identifier | ||||
|         GuacamoleSocket socket; | ||||
| @@ -295,7 +240,7 @@ public class BasicTunnelRequestUtility { | ||||
|  | ||||
|                 // Connect socket | ||||
|                 socket = connection.connect(info); | ||||
|                 logger.info("Successful connection from {} to \"{}\".", request.getRemoteAddr(), id); | ||||
|                 logger.info("Successful connection from to \"{}\".", id); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
| @@ -315,7 +260,7 @@ public class BasicTunnelRequestUtility { | ||||
|  | ||||
|                 // Connect socket | ||||
|                 socket = group.connect(info); | ||||
|                 logger.info("Successful connection from {} to group \"{}\".", request.getRemoteAddr(), id); | ||||
|                 logger.info("Successful connection to group \"{}\".", id); | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,67 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 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.util.Arrays; | ||||
| import java.util.List; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpSession; | ||||
|  | ||||
| /** | ||||
|  * HTTP-specific implementation of TunnelRequest. | ||||
|  * | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public class HTTPTunnelRequest implements TunnelRequest { | ||||
|  | ||||
|     /** | ||||
|      * The wrapped HttpServletRequest. | ||||
|      */ | ||||
|     private final HttpServletRequest request; | ||||
|  | ||||
|     /** | ||||
|      * Creates a TunnelRequest implementation which delegates parameter and | ||||
|      * session retrieval to the given HttpServletRequest. | ||||
|      * | ||||
|      * @param request The HttpServletRequest to wrap. | ||||
|      */ | ||||
|     public HTTPTunnelRequest(HttpServletRequest request) { | ||||
|         this.request = request; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public HttpSession getSession() { | ||||
|         return request.getSession(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getParameter(String name) { | ||||
|         return request.getParameter(name); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<String> getParameterValues(String name) { | ||||
|         return Arrays.asList(request.getParameterValues(name)); | ||||
|     } | ||||
|      | ||||
| } | ||||
| @@ -0,0 +1,118 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 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.util.List; | ||||
| import javax.servlet.http.HttpSession; | ||||
|  | ||||
| /** | ||||
|  * Request interface which provides only the functions absolutely required | ||||
|  * to retrieve and connect to a tunnel. | ||||
|  * | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public interface TunnelRequest { | ||||
|  | ||||
|     /** | ||||
|      * All supported identifier types. | ||||
|      */ | ||||
|     public static enum IdentifierType { | ||||
|  | ||||
|         /** | ||||
|          * The unique identifier of a connection. | ||||
|          */ | ||||
|         CONNECTION("c/"), | ||||
|  | ||||
|         /** | ||||
|          * The unique identifier of a connection group. | ||||
|          */ | ||||
|         CONNECTION_GROUP("g/"); | ||||
|          | ||||
|         /** | ||||
|          * The prefix which precedes an identifier of this type. | ||||
|          */ | ||||
|         final String PREFIX; | ||||
|          | ||||
|         /** | ||||
|          * Defines an IdentifierType having the given prefix. | ||||
|          * @param prefix The prefix which will precede any identifier of this | ||||
|          *               type, thus differentiating it from other identifier | ||||
|          *               types. | ||||
|          */ | ||||
|         IdentifierType(String prefix) { | ||||
|             PREFIX = prefix; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Given an identifier, determines the corresponding identifier type. | ||||
|          *  | ||||
|          * @param identifier The identifier whose type should be identified. | ||||
|          * @return The identified identifier type. | ||||
|          */ | ||||
|         static IdentifierType getType(String identifier) { | ||||
|  | ||||
|             // If null, no known identifier | ||||
|             if (identifier == null) | ||||
|                 return null; | ||||
|  | ||||
|             // Connection identifiers | ||||
|             if (identifier.startsWith(CONNECTION.PREFIX)) | ||||
|                 return CONNECTION; | ||||
|              | ||||
|             // Connection group identifiers | ||||
|             if (identifier.startsWith(CONNECTION_GROUP.PREFIX)) | ||||
|                 return CONNECTION_GROUP; | ||||
|              | ||||
|             // Otherwise, unknown | ||||
|             return null; | ||||
|              | ||||
|         } | ||||
|          | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Returns the current HTTP session, or null if no session yet exists. | ||||
|      * | ||||
|      * @return The current HTTP session, or null if no session yet exists. | ||||
|      */ | ||||
|     public HttpSession getSession(); | ||||
|  | ||||
|     /** | ||||
|      * Returns the value of the parameter having the given name. | ||||
|      * | ||||
|      * @param name The name of the parameter to return. | ||||
|      * @return The value of the parameter having the given name, or null | ||||
|      *         if no such parameter was specified. | ||||
|      */ | ||||
|     public String getParameter(String name); | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of all values specified for the given parameter. | ||||
|      * | ||||
|      * @param name The name of the parameter to return. | ||||
|      * @return All values of the parameter having the given name , or null | ||||
|      *         if no such parameter was specified. | ||||
|      */ | ||||
|     public List<String> getParameterValues(String name); | ||||
|      | ||||
| } | ||||
| @@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletRequest; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.GuacamoleTunnel; | ||||
| import org.glyptodon.guacamole.net.basic.BasicTunnelRequestUtility; | ||||
| import org.glyptodon.guacamole.net.basic.HTTPTunnelRequest; | ||||
|  | ||||
| /** | ||||
|  * Tunnel servlet implementation which uses WebSocket as a tunnel backend, | ||||
| @@ -37,7 +38,7 @@ public class BasicGuacamoleWebSocketTunnelServlet extends GuacamoleWebSocketTunn | ||||
|     @Override | ||||
|     protected GuacamoleTunnel doConnect(HttpServletRequest request) | ||||
|             throws GuacamoleException { | ||||
|         return BasicTunnelRequestUtility.createTunnel(request); | ||||
|         return BasicTunnelRequestUtility.createTunnel(new HTTPTunnelRequest(request)); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,102 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 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.websocket.jsr; | ||||
|  | ||||
| import java.util.Map; | ||||
| import javax.websocket.EndpointConfig; | ||||
| import javax.websocket.HandshakeResponse; | ||||
| import javax.websocket.Session; | ||||
| import javax.websocket.server.HandshakeRequest; | ||||
| import javax.websocket.server.ServerEndpoint; | ||||
| import javax.websocket.server.ServerEndpointConfig; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.GuacamoleTunnel; | ||||
| import org.glyptodon.guacamole.net.basic.BasicTunnelRequestUtility; | ||||
|  | ||||
| /** | ||||
|  * Tunnel implementation which uses WebSocket as a tunnel backend, rather than | ||||
|  * HTTP, properly parsing connection IDs included in the connection request. | ||||
|  */ | ||||
| @ServerEndpoint(value        = "/websocket-tunnel", | ||||
|                 subprotocols = {"guacamole"}, | ||||
|                 configurator = BasicGuacamoleWebSocketTunnelEndpoint.Configurator.class) | ||||
| public class BasicGuacamoleWebSocketTunnelEndpoint extends GuacamoleWebSocketTunnelEndpoint { | ||||
|  | ||||
|     /** | ||||
|      * Unique string which shall be used to store the GuacamoleTunnel | ||||
|      * associated with a WebSocket connection. | ||||
|      */ | ||||
|     private static final String TUNNEL_USER_PROPERTY = "WS_GUAC_TUNNEL"; | ||||
|  | ||||
|     /** | ||||
|      * Unique string which shall be used to store any GuacamoleException that | ||||
|      * occurs while retrieving the tunnel during the handshake. | ||||
|      */ | ||||
|     private static final String ERROR_USER_PROPERTY = "WS_GUAC_TUNNEL_ERROR"; | ||||
|  | ||||
|     /** | ||||
|      * Configurator implementation which stores the requested GuacamoleTunnel | ||||
|      * within the user properties. The GuacamoleTunnel will be later retrieved | ||||
|      * during the connection process. | ||||
|      */ | ||||
|     public static class Configurator extends ServerEndpointConfig.Configurator { | ||||
|  | ||||
|         @Override | ||||
|         public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) { | ||||
|  | ||||
|             super.modifyHandshake(config, request, response); | ||||
|              | ||||
|             // Attempt tunnel creation | ||||
|             Map<String, Object> userProperties = config.getUserProperties(); | ||||
|             userProperties.clear(); | ||||
|             try { | ||||
|  | ||||
|                 // Store new tunnel within user properties | ||||
|                 GuacamoleTunnel tunnel = BasicTunnelRequestUtility.createTunnel(new WebSocketTunnelRequest(request)); | ||||
|                 if (tunnel != null) | ||||
|                     userProperties.put(TUNNEL_USER_PROPERTY, tunnel); | ||||
|  | ||||
|             } | ||||
|             catch (GuacamoleException e) { | ||||
|                 userProperties.put(ERROR_USER_PROPERTY, e); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|          | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     protected GuacamoleTunnel createTunnel(Session session, EndpointConfig config) throws GuacamoleException { | ||||
|  | ||||
|         // Throw any error that occurred during tunnel creation | ||||
|         Map<String, Object> userProperties = config.getUserProperties(); | ||||
|         GuacamoleException tunnelError = (GuacamoleException) userProperties.get(ERROR_USER_PROPERTY); | ||||
|         if (tunnelError != null) | ||||
|             throw tunnelError; | ||||
|  | ||||
|         // Return created tunnel, if any | ||||
|         return (GuacamoleTunnel) userProperties.get(TUNNEL_USER_PROPERTY); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,82 @@ | ||||
| /* | ||||
|  * Copyright (C) 2014 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.websocket.jsr; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import javax.servlet.http.HttpSession; | ||||
| import javax.websocket.server.HandshakeRequest; | ||||
| import org.glyptodon.guacamole.net.basic.TunnelRequest; | ||||
|  | ||||
| /** | ||||
|  * WebSocket-specific implementation of TunnelRequest. | ||||
|  * | ||||
|  * @author Michael Jumper | ||||
|  */ | ||||
| public class WebSocketTunnelRequest implements TunnelRequest { | ||||
|  | ||||
|     /** | ||||
|      * The wrapped HandshakeRequest. | ||||
|      */ | ||||
|     private final HandshakeRequest request; | ||||
|  | ||||
|     /** | ||||
|      * All parameters passed via HTTP to the WebSocket handshake. | ||||
|      */ | ||||
|     private final Map<String, List<String>> handshakeParameters; | ||||
|      | ||||
|     /** | ||||
|      * Creates a TunnelRequest implementation which delegates parameter and | ||||
|      * session retrieval to the given HandshakeRequest. | ||||
|      * | ||||
|      * @param request The HandshakeRequest to wrap. | ||||
|      */ | ||||
|     public WebSocketTunnelRequest(HandshakeRequest request) { | ||||
|         this.request = request; | ||||
|         this.handshakeParameters = request.getParameterMap(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public HttpSession getSession() { | ||||
|         return (HttpSession) request.getHttpSession(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getParameter(String name) { | ||||
|  | ||||
|         // Pull list of values, if present | ||||
|         List<String> values = getParameterValues(name); | ||||
|         if (values == null || values.isEmpty()) | ||||
|             return null; | ||||
|  | ||||
|         // Return first parameter value arbitrarily | ||||
|         return values.get(0); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<String> getParameterValues(String name) { | ||||
|         return handshakeParameters.get(name); | ||||
|     } | ||||
|      | ||||
| } | ||||
| @@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletRequest; | ||||
| import org.glyptodon.guacamole.GuacamoleException; | ||||
| import org.glyptodon.guacamole.net.GuacamoleTunnel; | ||||
| import org.glyptodon.guacamole.net.basic.BasicTunnelRequestUtility; | ||||
| import org.glyptodon.guacamole.net.basic.HTTPTunnelRequest; | ||||
|  | ||||
| /** | ||||
|  * Tunnel servlet implementation which uses WebSocket as a tunnel backend, | ||||
| @@ -37,7 +38,7 @@ public class BasicGuacamoleWebSocketTunnelServlet extends GuacamoleWebSocketTunn | ||||
|     @Override | ||||
|     protected GuacamoleTunnel doConnect(HttpServletRequest request) | ||||
|             throws GuacamoleException { | ||||
|         return BasicTunnelRequestUtility.createTunnel(request); | ||||
|         return BasicTunnelRequestUtility.createTunnel(new HTTPTunnelRequest(request)); | ||||
|     }; | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user