Author: markt
Date: Fri Jun 28 17:10:27 2013
New Revision: 1497851

URL: http://svn.apache.org/r1497851
Log:
WebSocket 1.0, section 7.2
Connections created under an authenticated HTTP session must be closed when the 
HTTP session ends.

Added:
    tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSessionListener.java 
  (with props)
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/WsSci.java
    tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java

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=1497851&r1=1497850&r2=1497851&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java Fri Jun 28 
17:10:27 2013
@@ -523,7 +523,7 @@ public class WsSession implements Sessio
     }
 
 
-    protected String getHttpSessionId() {
+    public String getHttpSessionId() {
         return httpSessionId;
     }
 

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=1497851&r1=1497850&r2=1497851&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java Fri 
Jun 28 17:10:27 2013
@@ -345,10 +345,9 @@ public class WsWebSocketContainer
     }
 
 
-    protected void registerSession(Object endpointInstance,
-            WsSession wsSession) {
+    protected void registerSession(Endpoint endpoint, WsSession wsSession) {
 
-        Class<?> endpointClazz = endpointInstance.getClass();
+        Class<?> endpointClazz = endpoint.getClass();
 
         if (!wsSession.isOpen()) {
             // The session was closed during onOpen. No need to register it.
@@ -369,10 +368,9 @@ public class WsWebSocketContainer
     }
 
 
-    protected void unregisterSession(Object endpointInstance,
-            WsSession wsSession) {
+    protected void unregisterSession(Endpoint endpoint, WsSession wsSession) {
 
-        Class<?> endpointClazz = endpointInstance.getClass();
+        Class<?> endpointClazz = endpoint.getClass();
 
         synchronized (endPointSessionMapLock) {
             Set<WsSession> wsSessions = endpointSessionMap.get(endpointClazz);

Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSci.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSci.java?rev=1497851&r1=1497850&r2=1497851&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSci.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSci.java Fri Jun 28 
17:10:27 2013
@@ -126,12 +126,15 @@ public class WsSci implements ServletCon
 
 
     static WsServerContainer init(ServletContext servletContext) {
+
         WsServerContainer sc = WsServerContainer.getServerContainer();
         sc.setServletContext(servletContext);
 
         servletContext.setAttribute(
                 Constants.SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE, sc);
 
+        servletContext.addListener(new WsSessionListener(sc));
+
         return sc;
     }
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java?rev=1497851&r1=1497850&r2=1497851&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java 
Fri Jun 28 17:10:27 2013
@@ -16,11 +16,13 @@
  */
 package org.apache.tomcat.websocket.server;
 
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.EnumSet;
 import java.util.Map;
+import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.WeakHashMap;
@@ -29,8 +31,11 @@ import java.util.concurrent.ConcurrentHa
 import javax.servlet.DispatcherType;
 import javax.servlet.FilterRegistration;
 import javax.servlet.ServletContext;
+import javax.websocket.CloseReason;
+import javax.websocket.CloseReason.CloseCodes;
 import javax.websocket.DeploymentException;
 import javax.websocket.Encoder;
+import javax.websocket.Endpoint;
 import javax.websocket.server.ServerContainer;
 import javax.websocket.server.ServerEndpoint;
 import javax.websocket.server.ServerEndpointConfig;
@@ -62,7 +67,10 @@ public class WsServerContainer extends W
     private static final Object classLoaderContainerMapLock = new Object();
     private static final StringManager sm =
             StringManager.getManager(Constants.PACKAGE_NAME);
-
+    private static final CloseReason AUTHENTICATED_HTTP_SESSION_CLOSED =
+            new CloseReason(CloseCodes.VIOLATED_POLICY,
+                    "This connection was established under an authenticated " +
+                    "HTTP session that has ended.");
 
     public static WsServerContainer getServerContainer() {
         ClassLoader tccl = Thread.currentThread().getContextClassLoader();
@@ -92,6 +100,8 @@ public class WsServerContainer extends W
     private final ConcurrentHashMap<Integer,SortedSet<TemplatePathMatch>>
             configTemplateMatchMap = new ConcurrentHashMap<>();
     private volatile boolean addAllowed = true;
+    private final ConcurrentHashMap<String,Set<WsSession>> 
authenticatedSessions =
+            new ConcurrentHashMap<>();
 
     private WsServerContainer() {
         // Hide default constructor
@@ -307,9 +317,13 @@ public class WsServerContainer extends W
      * Overridden to make it visible to other classes in this package.
      */
     @Override
-    protected void registerSession(Object endpointInstance,
-            WsSession wsSession) {
-        super.registerSession(endpointInstance, wsSession);
+    protected void registerSession(Endpoint endpoint, WsSession wsSession) {
+        super.registerSession(endpoint, wsSession);
+        if (wsSession.getUserPrincipal() != null &&
+                wsSession.getHttpSessionId() != null) {
+            registerAuthenticatedSession(wsSession,
+                    wsSession.getHttpSessionId());
+        }
     }
 
 
@@ -319,12 +333,49 @@ public class WsServerContainer extends W
      * Overridden to make it visible to other classes in this package.
      */
     @Override
-    protected void unregisterSession(Object endpointInstance,
-            WsSession wsSession) {
-        super.unregisterSession(endpointInstance, wsSession);
+    protected void unregisterSession(Endpoint endpoint, WsSession wsSession) {
+        if (wsSession.getUserPrincipal() != null &&
+                wsSession.getHttpSessionId() != null) {
+            unregisterAuthenticatedSession(wsSession,
+                    wsSession.getHttpSessionId());
+        }
+        super.unregisterSession(endpoint, wsSession);
     }
 
 
+    private void registerAuthenticatedSession(WsSession wsSession,
+            String httpSessionId) {
+        Set<WsSession> wsSessions = authenticatedSessions.get(httpSessionId);
+        if (wsSession == null) {
+            wsSessions = Collections.newSetFromMap(
+                     new ConcurrentHashMap<WsSession,Boolean>());
+             authenticatedSessions.putIfAbsent(httpSessionId, wsSessions);
+             wsSessions = authenticatedSessions.get(httpSessionId);
+        }
+        wsSessions.add(wsSession);
+    }
+
+
+    private void unregisterAuthenticatedSession(WsSession wsSession,
+            String httpSessionId) {
+        Set<WsSession> wsSessions = authenticatedSessions.get(httpSessionId);
+        wsSessions.remove(wsSession);
+    }
+
+
+    public void closeAuthenticatedSession(String httpSessionId) {
+        Set<WsSession> wsSessions = 
authenticatedSessions.remove(httpSessionId);
+
+        for (WsSession wsSession : wsSessions) {
+            try {
+                wsSession.close(AUTHENTICATED_HTTP_SESSION_CLOSED);
+            } catch (IOException e) {
+                // Any IOExceptions during close will have been caught and the
+                // onError method called.
+            }
+        }
+    }
+
     private static void validateEncoders(Class<? extends Encoder>[] encoders)
             throws DeploymentException {
 

Added: 
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSessionListener.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSessionListener.java?rev=1497851&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSessionListener.java 
(added)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSessionListener.java 
Fri Jun 28 17:10:27 2013
@@ -0,0 +1,42 @@
+/*
+ * 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.server;
+
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+public class WsSessionListener implements HttpSessionListener{
+
+    private final WsServerContainer wsServerContainer;
+
+
+    public WsSessionListener(WsServerContainer wsServerContainer) {
+        this.wsServerContainer = wsServerContainer;
+    }
+
+
+    @Override
+    public void sessionCreated(HttpSessionEvent se) {
+        // NO-OP
+    }
+
+
+    @Override
+    public void sessionDestroyed(HttpSessionEvent se) {
+        wsServerContainer.closeAuthenticatedSession(se.getSession().getId());
+    }
+}

Propchange: 
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsSessionListener.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to