This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 509234891c4399f2d27fe9448646ae175b34731f
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Apr 30 14:36:52 2021 +0100

    Refactor server end point creation to WsSession
    
    The is an interim step towards the fix for BZ 65262
---
 java/org/apache/tomcat/websocket/WsSession.java    | 185 +++++++++++++++++++++
 .../tomcat/websocket/WsWebSocketContainer.java     |   6 +-
 .../tomcat/websocket/server/UpgradeUtil.java       |  16 +-
 .../websocket/server/WsHttpUpgradeHandler.java     |   8 +-
 4 files changed, 192 insertions(+), 23 deletions(-)

diff --git a/java/org/apache/tomcat/websocket/WsSession.java 
b/java/org/apache/tomcat/websocket/WsSession.java
index 1f85100..073a4d6 100644
--- a/java/org/apache/tomcat/websocket/WsSession.java
+++ b/java/org/apache/tomcat/websocket/WsSession.java
@@ -30,6 +30,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
+import javax.websocket.ClientEndpointConfig;
 import javax.websocket.CloseReason;
 import javax.websocket.CloseReason.CloseCode;
 import javax.websocket.CloseReason.CloseCodes;
@@ -53,6 +54,7 @@ import org.apache.tomcat.InstanceManager;
 import org.apache.tomcat.InstanceManagerBindings;
 import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.websocket.pojo.PojoEndpointServer;
 
 public class WsSession implements Session {
 
@@ -101,6 +103,186 @@ public class WsSession implements Session {
     private volatile long lastActiveWrite = System.currentTimeMillis();
     private Map<FutureToSendHandler, FutureToSendHandler> futures = new 
ConcurrentHashMap<>();
 
+
+    /**
+     * Creates a new WebSocket session for communication between the provided
+     * client and remote end points. The result of
+     * {@link Thread#getContextClassLoader()} at the time this constructor is
+     * called will be used when calling
+     * {@link Endpoint#onClose(Session, CloseReason)}.
+     *
+     * @param localEndpoint        The end point managed by this code
+     * @param wsRemoteEndpoint     The other / remote end point
+     * @param wsWebSocketContainer The container that created this session
+     * @param negotiatedExtensions The agreed extensions to use for this 
session
+     * @param subProtocol          The agreed sub-protocol to use for this
+     *                             session
+     * @param pathParameters       The path parameters associated with the
+     *                             request that initiated this session or
+     *                             <code>null</code> if this is a client 
session
+     * @param secure               Was this session initiated over a secure
+     *                             connection?
+     * @param clientEndpointConfig The configuration information for the client
+     *                             end point
+     * @throws DeploymentException if an invalid encode is specified
+     */
+    public WsSession(Endpoint localEndpoint,
+            WsRemoteEndpointImplBase wsRemoteEndpoint,
+            WsWebSocketContainer wsWebSocketContainer,
+            List<Extension> negotiatedExtensions, String subProtocol, 
Map<String, String> pathParameters,
+            boolean secure, ClientEndpointConfig clientEndpointConfig) throws 
DeploymentException {
+        this.localEndpoint = localEndpoint;
+        this.wsRemoteEndpoint = wsRemoteEndpoint;
+        this.wsRemoteEndpoint.setSession(this);
+        this.remoteEndpointAsync = new WsRemoteEndpointAsync(wsRemoteEndpoint);
+        this.remoteEndpointBasic = new WsRemoteEndpointBasic(wsRemoteEndpoint);
+        this.webSocketContainer = wsWebSocketContainer;
+        applicationClassLoader = 
Thread.currentThread().getContextClassLoader();
+        
wsRemoteEndpoint.setSendTimeout(wsWebSocketContainer.getDefaultAsyncSendTimeout());
+        this.maxBinaryMessageBufferSize = 
webSocketContainer.getDefaultMaxBinaryMessageBufferSize();
+        this.maxTextMessageBufferSize = 
webSocketContainer.getDefaultMaxTextMessageBufferSize();
+        this.maxIdleTimeout = 
webSocketContainer.getDefaultMaxSessionIdleTimeout();
+        this.requestUri = null;
+        this.requestParameterMap = Collections.emptyMap();
+        this.queryString = null;
+        this.userPrincipal = null;
+        this.httpSessionId = null;
+        this.negotiatedExtensions = negotiatedExtensions;
+        if (subProtocol == null) {
+            this.subProtocol = "";
+        } else {
+            this.subProtocol = subProtocol;
+        }
+        this.pathParameters = pathParameters;
+        this.secure = secure;
+        this.wsRemoteEndpoint.setEncoders(clientEndpointConfig);
+        this.endpointConfig = clientEndpointConfig;
+
+        this.userProperties.putAll(endpointConfig.getUserProperties());
+        this.id = Long.toHexString(ids.getAndIncrement());
+
+        InstanceManager instanceManager = 
webSocketContainer.getInstanceManager();
+        if (instanceManager == null) {
+            instanceManager = 
InstanceManagerBindings.get(applicationClassLoader);
+        }
+        if (instanceManager != null) {
+            try {
+                instanceManager.newInstance(localEndpoint);
+            } catch (Exception e) {
+                throw new 
DeploymentException(sm.getString("wsSession.instanceNew"), e);
+            }
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug(sm.getString("wsSession.created", id));
+        }
+    }
+
+
+    /**
+     * Creates a new WebSocket session for communication between the provided
+     * server and remote end points. The result of
+     * {@link Thread#getContextClassLoader()} at the time this constructor is
+     * called will be used when calling
+     * {@link Endpoint#onClose(Session, CloseReason)}.
+     *
+     * @param wsRemoteEndpoint     The other / remote end point
+     * @param wsWebSocketContainer The container that created this session
+     * @param requestUri           The URI used to connect to this end point or
+     *                             <code>null</code> is this is a client 
session
+     * @param requestParameterMap  The parameters associated with the request
+     *                             that initiated this session or
+     *                             <code>null</code> if this is a client 
session
+     * @param queryString          The query string associated with the request
+     *                             that initiated this session or
+     *                             <code>null</code> if this is a client 
session
+     * @param userPrincipal        The principal associated with the request
+     *                             that initiated this session or
+     *                             <code>null</code> if this is a client 
session
+     * @param httpSessionId        The HTTP session ID associated with the
+     *                             request that initiated this session or
+     *                             <code>null</code> if this is a client 
session
+     * @param negotiatedExtensions The agreed extensions to use for this 
session
+     * @param subProtocol          The agreed sub-protocol to use for this
+     *                             session
+     * @param pathParameters       The path parameters associated with the
+     *                             request that initiated this session or
+     *                             <code>null</code> if this is a client 
session
+     * @param secure               Was this session initiated over a secure
+     *                             connection?
+     * @param serverEndpointConfig The configuration information for the server
+     *                             end point
+     * @throws DeploymentException if an invalid encode is specified
+     */
+    public WsSession(WsRemoteEndpointImplBase wsRemoteEndpoint,
+            WsWebSocketContainer wsWebSocketContainer,
+            URI requestUri, Map<String, List<String>> requestParameterMap,
+            String queryString, Principal userPrincipal, String httpSessionId,
+            List<Extension> negotiatedExtensions, String subProtocol, 
Map<String, String> pathParameters,
+            boolean secure, ServerEndpointConfig serverEndpointConfig) throws 
DeploymentException {
+
+        try {
+            Class<?> clazz = serverEndpointConfig.getEndpointClass();
+            if (Endpoint.class.isAssignableFrom(clazz)) {
+                this.localEndpoint = (Endpoint) 
serverEndpointConfig.getConfigurator().getEndpointInstance(clazz);
+            } else {
+                this.localEndpoint = new PojoEndpointServer(pathParameters);
+            }
+        } catch (InstantiationException e) {
+            throw new 
DeploymentException(sm.getString("wsSession.instanceNew"), e);
+        }
+
+        this.wsRemoteEndpoint = wsRemoteEndpoint;
+        this.wsRemoteEndpoint.setSession(this);
+        this.remoteEndpointAsync = new WsRemoteEndpointAsync(wsRemoteEndpoint);
+        this.remoteEndpointBasic = new WsRemoteEndpointBasic(wsRemoteEndpoint);
+        this.webSocketContainer = wsWebSocketContainer;
+        applicationClassLoader = 
Thread.currentThread().getContextClassLoader();
+        
wsRemoteEndpoint.setSendTimeout(wsWebSocketContainer.getDefaultAsyncSendTimeout());
+        this.maxBinaryMessageBufferSize = 
webSocketContainer.getDefaultMaxBinaryMessageBufferSize();
+        this.maxTextMessageBufferSize = 
webSocketContainer.getDefaultMaxTextMessageBufferSize();
+        this.maxIdleTimeout = 
webSocketContainer.getDefaultMaxSessionIdleTimeout();
+        this.requestUri = requestUri;
+        if (requestParameterMap == null) {
+            this.requestParameterMap = Collections.emptyMap();
+        } else {
+            this.requestParameterMap = requestParameterMap;
+        }
+        this.queryString = queryString;
+        this.userPrincipal = userPrincipal;
+        this.httpSessionId = httpSessionId;
+        this.negotiatedExtensions = negotiatedExtensions;
+        if (subProtocol == null) {
+            this.subProtocol = "";
+        } else {
+            this.subProtocol = subProtocol;
+        }
+        this.pathParameters = pathParameters;
+        this.secure = secure;
+        this.wsRemoteEndpoint.setEncoders(serverEndpointConfig);
+        this.endpointConfig = serverEndpointConfig;
+
+        this.userProperties.putAll(endpointConfig.getUserProperties());
+        this.id = Long.toHexString(ids.getAndIncrement());
+
+        InstanceManager instanceManager = 
webSocketContainer.getInstanceManager();
+        if (instanceManager == null) {
+            instanceManager = 
InstanceManagerBindings.get(applicationClassLoader);
+        }
+        if (instanceManager != null) {
+            try {
+                instanceManager.newInstance(localEndpoint);
+            } catch (Exception e) {
+                throw new 
DeploymentException(sm.getString("wsSession.instanceNew"), e);
+            }
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug(sm.getString("wsSession.created", id));
+        }
+    }
+
+
     /**
      * Creates a new WebSocket session for communication between the two
      * provided end points. The result of {@link 
Thread#getContextClassLoader()}
@@ -135,7 +317,10 @@ public class WsSession implements Session {
      * @param endpointConfig       The configuration information for the
      *                             endpoint
      * @throws DeploymentException if an invalid encode is specified
+     *
+     * @deprecated  Unused. This will be removed in Tomcat 10.1
      */
+    @Deprecated
     public WsSession(Endpoint localEndpoint,
             WsRemoteEndpointImplBase wsRemoteEndpoint,
             WsWebSocketContainer wsWebSocketContainer,
diff --git a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 
b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
index dcde690..8c568cb 100644
--- a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
+++ b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
@@ -505,10 +505,8 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
         // Switch to WebSocket
         WsRemoteEndpointImplClient wsRemoteEndpointClient = new 
WsRemoteEndpointImplClient(channel);
 
-        WsSession wsSession = new WsSession(endpoint, wsRemoteEndpointClient,
-                this, null, null, null, null, null, extensionsAgreed,
-                subProtocol, Collections.<String,String>emptyMap(), secure,
-                clientEndpointConfiguration);
+        WsSession wsSession = new WsSession(endpoint, wsRemoteEndpointClient, 
this, extensionsAgreed, subProtocol,
+                Collections.<String,String>emptyMap(), secure, 
clientEndpointConfiguration);
 
         WsFrameClient wsFrameClient = new WsFrameClient(response, channel,
                 wsSession, transformation);
diff --git a/java/org/apache/tomcat/websocket/server/UpgradeUtil.java 
b/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
index d1ed9cc..1f8cb32 100644
--- a/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
+++ b/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
@@ -31,7 +31,6 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.websocket.Endpoint;
 import javax.websocket.Extension;
 import javax.websocket.HandshakeResponse;
 import javax.websocket.server.ServerEndpointConfig;
@@ -44,7 +43,6 @@ import org.apache.tomcat.websocket.Transformation;
 import org.apache.tomcat.websocket.TransformationFactory;
 import org.apache.tomcat.websocket.Util;
 import org.apache.tomcat.websocket.WsHandshakeResponse;
-import org.apache.tomcat.websocket.pojo.PojoEndpointServer;
 
 public class UpgradeUtil {
 
@@ -215,21 +213,9 @@ public class UpgradeUtil {
             }
         }
 
-        Endpoint ep;
-        try {
-            Class<?> clazz = sec.getEndpointClass();
-            if (Endpoint.class.isAssignableFrom(clazz)) {
-                ep = (Endpoint) 
sec.getConfigurator().getEndpointInstance(clazz);
-            } else {
-                ep = new PojoEndpointServer(pathParams);
-            }
-        } catch (InstantiationException e) {
-            throw new ServletException(e);
-        }
-
         WsHttpUpgradeHandler wsHandler =
                 req.upgrade(WsHttpUpgradeHandler.class);
-        wsHandler.preInit(ep, perSessionServerEndpointConfig, sc, wsRequest,
+        wsHandler.preInit(perSessionServerEndpointConfig, sc, wsRequest,
                 negotiatedExtensionsPhase2, subProtocol, transformation, 
pathParams,
                 req.isSecure());
 
diff --git a/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java 
b/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
index 414f9bc..eebbdca 100644
--- a/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
+++ b/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
@@ -82,12 +82,11 @@ public class WsHttpUpgradeHandler implements 
InternalHttpUpgradeHandler {
     }
 
 
-    public void preInit(Endpoint ep, ServerEndpointConfig serverEndpointConfig,
+    public void preInit(ServerEndpointConfig serverEndpointConfig,
             WsServerContainer wsc, WsHandshakeRequest handshakeRequest,
             List<Extension> negotiatedExtensionsPhase2, String subProtocol,
             Transformation transformation, Map<String,String> pathParameters,
             boolean secure) {
-        this.ep = ep;
         this.serverEndpointConfig = serverEndpointConfig;
         this.webSocketContainer = wsc;
         this.handshakeRequest = handshakeRequest;
@@ -101,7 +100,7 @@ public class WsHttpUpgradeHandler implements 
InternalHttpUpgradeHandler {
 
     @Override
     public void init(WebConnection connection) {
-        if (ep == null) {
+        if (serverEndpointConfig == null) {
             throw new IllegalStateException(
                     sm.getString("wsHttpUpgradeHandler.noPreInit"));
         }
@@ -120,13 +119,14 @@ public class WsHttpUpgradeHandler implements 
InternalHttpUpgradeHandler {
         t.setContextClassLoader(applicationClassLoader);
         try {
             wsRemoteEndpointServer = new 
WsRemoteEndpointImplServer(socketWrapper, upgradeInfo, webSocketContainer);
-            wsSession = new WsSession(ep, wsRemoteEndpointServer,
+            wsSession = new WsSession(wsRemoteEndpointServer,
                     webSocketContainer, handshakeRequest.getRequestURI(),
                     handshakeRequest.getParameterMap(),
                     handshakeRequest.getQueryString(),
                     handshakeRequest.getUserPrincipal(), httpSessionId,
                     negotiatedExtensions, subProtocol, pathParameters, secure,
                     serverEndpointConfig);
+            ep = wsSession.getLocal();
             wsFrame = new WsFrameServer(socketWrapper, upgradeInfo, wsSession, 
transformation,
                     applicationClassLoader);
             // WsFrame adds the necessary final transformations. Copy the

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

Reply via email to