Author: markt Date: Tue Mar 19 13:00:43 2013 New Revision: 1458263 URL: http://svn.apache.org/r1458263 Log: Implement modifyHandshake() call Based on a patch by Nick Williams
Added: tomcat/trunk/java/org/apache/tomcat/websocket/WsHandshakeResponse.java (with props) tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java - copied, changed from r1458192, tomcat/trunk/java/org/apache/tomcat/websocket/WsRequest.java Removed: tomcat/trunk/java/org/apache/tomcat/websocket/WsRequest.java Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServlet.java Added: tomcat/trunk/java/org/apache/tomcat/websocket/WsHandshakeResponse.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsHandshakeResponse.java?rev=1458263&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsHandshakeResponse.java (added) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsHandshakeResponse.java Tue Mar 19 13:00:43 2013 @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.websocket; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.websocket.HandshakeResponse; + +/** + * Represents the response to a WebSocket handshake. + */ +public class WsHandshakeResponse implements HandshakeResponse { + + private final Map<String,List<String>> headers; + + + public WsHandshakeResponse() { + this(new HashMap<String,List<String>>()); + } + + + public WsHandshakeResponse(Map<String,List<String>> headers) { + this.headers = headers; + } + + + @Override + public Map<String,List<String>> getHeaders() { + return headers; + } +} Propchange: tomcat/trunk/java/org/apache/tomcat/websocket/WsHandshakeResponse.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java?rev=1458263&r1=1458262&r2=1458263&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java Tue Mar 19 13:00:43 2013 @@ -61,7 +61,11 @@ public class WsSession implements Sessio private final RemoteEndpoint.Basic remoteEndpointBasic; private final ClassLoader applicationClassLoader; private final WsWebSocketContainer webSocketContainer; - private final WsRequest request; + private final URI requestUri; + private final Map<String,List<String>> requestParameterMap; + private final String queryString; + private final Principal userPrincipal; + private final String subProtocol; private final Map<String,String> pathParameters; private final boolean secure; @@ -93,9 +97,11 @@ public class WsSession implements Sessio public WsSession(Endpoint localEndpoint, WsRemoteEndpointImplBase wsRemoteEndpoint, WsWebSocketContainer wsWebSocketContainer, - WsRequest request, String subProtocol, + URI requestUri, Map<String,List<String>> requestParameterMap, + String queryString, Principal userPrincipal, String subProtocol, Map<String,String> pathParameters, - boolean secure, List<Class<? extends Encoder>> encoders) + boolean secure, List<Class<? extends Encoder>> encoders, + Map<String,Object> userProperties) throws DeploymentException { this.localEndpoint = localEndpoint; this.wsRemoteEndpoint = wsRemoteEndpoint; @@ -112,12 +118,20 @@ public class WsSession implements Sessio webSocketContainer.getDefaultMaxTextMessageBufferSize(); this.maxIdleTimeout = webSocketContainer.getDefaultMaxSessionIdleTimeout(); - this.request = request; + this.requestUri = requestUri; + if (requestParameterMap == null) { + this.requestParameterMap = Collections.EMPTY_MAP; + } else { + this.requestParameterMap = requestParameterMap; + } + this.queryString = queryString; + this.userPrincipal = userPrincipal; this.subProtocol = subProtocol; this.pathParameters = pathParameters; this.secure = secure; this.wsRemoteEndpoint.setEncoders(encoders); + this.userProperties.putAll(userProperties); this.id = Long.toHexString(ids.getAndIncrement()); } @@ -369,37 +383,25 @@ public class WsSession implements Sessio @Override public URI getRequestURI() { - if (request == null) { - return null; - } - return request.getRequestURI(); + return requestUri; } @Override public Map<String,List<String>> getRequestParameterMap() { - if (request == null) { - return Collections.EMPTY_MAP; - } - return request.getRequestParameterMap(); + return requestParameterMap; } @Override public String getQueryString() { - if (request == null) { - return null; - } - return request.getQueryString(); + return queryString; } @Override public Principal getUserPrincipal() { - if (request == null) { - return null; - } - return request.getUserPrincipal(); + return userPrincipal; } Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java?rev=1458263&r1=1458262&r2=1458263&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java Tue Mar 19 13:00:43 2013 @@ -239,8 +239,10 @@ public class WsWebSocketContainer WsSession wsSession = new WsSession(endpoint, wsRemoteEndpointClient, - this, null, subProtocol, Collections.EMPTY_MAP, false, - clientEndpointConfiguration.getEncoders()); + this, null, null, null, null, subProtocol, + Collections.EMPTY_MAP, false, + clientEndpointConfiguration.getEncoders(), + clientEndpointConfiguration.getUserProperties()); endpoint.onOpen(wsSession, clientEndpointConfiguration); registerSession(endpoint.getClass(), wsSession); @@ -554,21 +556,6 @@ public class WsWebSocketContainer this.defaultAsyncTimeout = timeout; } - private static class WsHandshakeResponse implements HandshakeResponse { - - private final Map<String,List<String>> headers; - - public WsHandshakeResponse(Map<String,List<String>> headers) { - this.headers = headers; - } - - @Override - public Map<String,List<String>> getHeaders() { - return headers; - } - } - - // ----------------------------------------------- BackgroundProcess methods @Override Copied: tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java (from r1458192, tomcat/trunk/java/org/apache/tomcat/websocket/WsRequest.java) URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java?p2=tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java&p1=tomcat/trunk/java/org/apache/tomcat/websocket/WsRequest.java&r1=1458192&r2=1458263&rev=1458263&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsRequest.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsHandshakeRequest.java Tue Mar 19 13:00:43 2013 @@ -14,44 +14,126 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.tomcat.websocket; +package org.apache.tomcat.websocket.server; import java.net.URI; +import java.net.URISyntaxException; import java.security.Principal; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.http.HttpServletRequest; +import javax.websocket.server.HandshakeRequest; /** * Represents the request that this session was opened under. */ -public class WsRequest { +public class WsHandshakeRequest implements HandshakeRequest { + + private volatile HttpServletRequest request; - private final URI requestURI; - private final Map<String,List<String>> parameterMap; - private final String queryString; - private final Principal userPrincipal; - - public WsRequest(URI requestURI, Map<String,List<String>> parameterMap, - String queryString, Principal userPrincipal) { - this.requestURI = requestURI; - this.parameterMap = parameterMap; - this.queryString = queryString; - this.userPrincipal = userPrincipal; + public WsHandshakeRequest(HttpServletRequest request) { + this.request = request; } + @Override public URI getRequestURI() { + validate(); + // Calculate every time as only likely to be zero or one calls + String queryString = request.getQueryString(); + + StringBuffer sb = request.getRequestURL(); + if (queryString != null) { + sb.append("?"); + sb.append(queryString); + } + URI requestURI; + try { + requestURI = new URI(sb.toString()); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e); + } + return requestURI; } - public Map<String,List<String>> getRequestParameterMap() { - return parameterMap; + @Override + public Map<String,List<String>> getParameterMap() { + validate(); + + Map<String,String[]> originalParameters = request.getParameterMap(); + Map<String,List<String>> newParameters = + new HashMap<>(originalParameters.size()); + for (Entry<String,String[]> entry : originalParameters.entrySet()) { + newParameters.put(entry.getKey(), + Collections.unmodifiableList( + Arrays.asList(entry.getValue()))); + } + + return Collections.unmodifiableMap(newParameters); } + @Override public String getQueryString() { - return queryString; + validate(); + return request.getQueryString(); } + @Override public Principal getUserPrincipal() { - return userPrincipal; + validate(); + return request.getUserPrincipal(); + } + + @Override + public Map<String,List<String>> getHeaders() { + validate(); + + Map<String,List<String>> newHeaders = new HashMap<>(); + + Enumeration<String> headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + + newHeaders.put(headerName, Collections.unmodifiableList( + Collections.list(request.getHeaders(headerName)))); + } + + return Collections.unmodifiableMap(newHeaders); + } + + @Override + public boolean isUserInRole(String role) { + validate(); + return request.isUserInRole(role); + } + + @Override + public Object getHttpSession() { + validate(); + return request.getSession(false); + } + + /** + * Called when the HandshakeRequest is no longer required. Since an instance + * of this class retains a reference to the current HttpServletRequest that + * reference needs to be cleared as the HttpServletRequest may be reused. + * + * There is no reason for instances of this class to be accessed once the + * handshake has been completed. + */ + void finished() { + request = null; + } + + private void validate() { + if (request == null) { + throw new IllegalStateException(); + } } } Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java?rev=1458263&r1=1458262&r2=1458263&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java Tue Mar 19 13:00:43 2013 @@ -36,7 +36,6 @@ import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.res.StringManager; import org.apache.tomcat.websocket.WsIOException; -import org.apache.tomcat.websocket.WsRequest; import org.apache.tomcat.websocket.WsSession; /** @@ -53,7 +52,7 @@ public class WsProtocolHandler implement private final EndpointConfig endpointConfig; private final ClassLoader applicationClassLoader; private final WsServerContainer webSocketContainer; - private final WsRequest request; + private final WsHandshakeRequest handshakeRequest; private final String subProtocol; private final Map<String,String> pathParameters; private final boolean secure; @@ -62,12 +61,13 @@ public class WsProtocolHandler implement public WsProtocolHandler(Endpoint ep, EndpointConfig endpointConfig, - WsServerContainer wsc, WsRequest request, String subProtocol, - Map<String,String> pathParameters, boolean secure) { + WsServerContainer wsc, WsHandshakeRequest handshakeRequest, + String subProtocol, Map<String,String> pathParameters, + boolean secure) { this.ep = ep; this.endpointConfig = endpointConfig; this.webSocketContainer = wsc; - this.request = request; + this.handshakeRequest = handshakeRequest; this.subProtocol = subProtocol; this.pathParameters = pathParameters; this.secure = secure; @@ -96,8 +96,12 @@ public class WsProtocolHandler implement WsRemoteEndpointImplServer wsRemoteEndpointServer = new WsRemoteEndpointImplServer(sos, webSocketContainer); wsSession = new WsSession(ep, wsRemoteEndpointServer, - webSocketContainer, request, subProtocol, pathParameters, - secure, endpointConfig.getEncoders()); + webSocketContainer, handshakeRequest.getRequestURI(), + handshakeRequest.getParameterMap(), + handshakeRequest.getQueryString(), + handshakeRequest.getUserPrincipal(), subProtocol, + pathParameters, secure, endpointConfig.getEncoders(), + endpointConfig.getUserProperties()); WsFrameServer wsFrame = new WsFrameServer( sis, wsSession); Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServlet.java?rev=1458263&r1=1458262&r2=1458263&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServlet.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServlet.java Tue Mar 19 13:00:43 2013 @@ -17,16 +17,12 @@ package org.apache.tomcat.websocket.server; import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -45,7 +41,7 @@ import javax.websocket.server.ServerEndp import javax.xml.bind.DatatypeConverter; import org.apache.tomcat.websocket.Constants; -import org.apache.tomcat.websocket.WsRequest; +import org.apache.tomcat.websocket.WsHandshakeResponse; import org.apache.tomcat.websocket.pojo.PojoEndpointServer; /** @@ -145,42 +141,22 @@ public class WsServlet extends HttpServl } catch (InstantiationException | IllegalAccessException e) { throw new ServletException(e); } - WsRequest wsRequest = createWsRequest(req); - HttpUpgradeHandler wsHandler = new WsProtocolHandler(ep, sec, sc, - wsRequest, subProtocol, pathParameters, req.isSecure()); - req.upgrade(wsHandler); - } - - - private WsRequest createWsRequest(HttpServletRequest req) - throws ServletException { - - String queryString = req.getQueryString(); - - StringBuffer sb = req.getRequestURL(); - if (queryString != null) { - sb.append("?"); - sb.append(queryString); - } - URI requestURI; - try { - requestURI = new URI(sb.toString()); - } catch (URISyntaxException e) { - throw new ServletException(e); - } - Map<String,String[]> originalParameters = req.getParameterMap(); - Map<String,List<String>> newParameters = new HashMap<>(); - for (Entry<String,String[]> entry : originalParameters.entrySet()) { - newParameters.put(entry.getKey(), - Collections.unmodifiableList( - Arrays.asList(entry.getValue()))); + WsHandshakeRequest wsRequest = new WsHandshakeRequest(req); + WsHandshakeResponse wsResponse = new WsHandshakeResponse(); + sec.getConfigurator().modifyHandshake(sec, wsRequest, wsResponse); + + // Add any additional headers + for (Entry<String,List<String>> entry : + wsResponse.getHeaders().entrySet()) { + for (String headerValue: entry.getValue()) { + resp.addHeader(entry.getKey(), headerValue); + } } - Map<String,List<String>> parameterMap = - Collections.unmodifiableMap(newParameters); - return new WsRequest(requestURI, parameterMap, queryString, - req.getUserPrincipal()); + HttpUpgradeHandler wsHandler = new WsProtocolHandler(ep, sec, sc, + wsRequest, subProtocol, pathParameters, req.isSecure()); + req.upgrade(wsHandler); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org