You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2022/03/03 17:01:37 UTC

[tomcat] 01/01: First pass at implementing per session user properties using a proxy

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

markt pushed a commit to branch websocket-userproperties-proxy
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit e61e9ad4ece051df45d4144c16c557a58b2a9286
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Mar 3 17:00:45 2022 +0000

    First pass at implementing per session user properties using a proxy
    
    Compared to wrapping this has the benefit that the user can still cast
    their ServerEndpointConfig instance to the original implementation class
    and access implementation specfic methods.
---
 build.properties.default                           |  9 +++
 build.xml                                          | 22 ++++++
 .../tomcat/websocket/server/UpgradeUtil.java       | 21 +++++-
 .../server/WsPerSessionServerEndpointConfig.java   | 84 ----------------------
 .../WsPerSessionUserPropertiesMethodFilter.java    | 29 ++++++++
 .../WsPerSessionUserPropertiesMethodHandler.java   | 42 +++++++++++
 res/checkstyle/checkstyle.xml                      |  2 +-
 res/checkstyle/org-import-control.xml              |  1 +
 8 files changed, 123 insertions(+), 87 deletions(-)

diff --git a/build.properties.default b/build.properties.default
index d5bdf0e..773ba42 100644
--- a/build.properties.default
+++ b/build.properties.default
@@ -217,6 +217,15 @@ commons-daemon.native.src.loc.2=${base-commons.loc.2}/daemon/source/commons-daem
 commons-daemon.native.win.loc.1=${base-commons.loc.1}/daemon/binaries/windows/commons-daemon-${commons-daemon.version}-bin-windows.zip
 commons-daemon.native.win.loc.2=${base-commons.loc.2}/daemon/binaries/windows/commons-daemon-${commons-daemon.version}-bin-windows.zip
 
+# ----- Javassist 3.28.0-GA or later -----
+javassist.version=3.28.0-GA
+javassist.checksum.enabled=true
+javassist.checksum.algorithm=MD5|SHA-1
+javassist.checksum.value=1a2dd8c76321cef26cc2669fe70a2557|9a958811a88381bb159cc2f5ed79c34a45c4af7a
+javassist.home=${base.path}/javassist-${javassist.version}
+javassist.jar=${javassist.home}/javassist-${javassist.version}.jar
+javassist.loc=${base-maven.loc}/org/javassist/javassist/${javassist.version}/javassist-${javassist.version}.jar
+
 # ----- JUnit Unit Test Suite, version 4.11 or later -----
 junit.version=4.13.2
 junit.checksum.enabled=true
diff --git a/build.xml b/build.xml
index fb5c56a..a448531 100644
--- a/build.xml
+++ b/build.xml
@@ -220,6 +220,7 @@
     <pathelement location="${jaxrpc-lib.jar}"/>
     <pathelement location="${wsdl4j-lib.jar}"/>
     <pathelement location="${migration-lib.jar}"/>
+    <pathelement location="${javassist.jar}"/>
   </path>
 
   <path id="tomcat.classpath">
@@ -1492,6 +1493,17 @@
     </delete>
     <copy file="${migration-lib.jar}" todir="${tomcat.build}/lib"/>
 
+    <!-- Delete all other versions of Javassist and copy the current one -->
+    <local name="javassist.jar.filename" />
+    <basename property="javassist.jar.filename" file="${javassist.jar}"/>
+    <delete verbose="true">
+      <fileset dir="${tomcat.build}/lib">
+        <include name="javassist-*.jar"/>
+        <exclude name="${javassist.jar.filename}"/>
+      </fileset>
+    </delete>
+    <copy file="${javassist.jar}" todir="${tomcat.build}/lib"/>
+
     <!-- Delete all other versions of OpenSSL support for Tomcat and copy the current one -->
     <!-- After module release
     <local name="openssl-lib.jar.filename" />
@@ -3162,6 +3174,16 @@ skip.installer property in build.properties" />
       <param name="checksum.value" value="${migration-lib.checksum.value}"/>
     </antcall>
 
+    <!-- Javassist -->
+    <antcall target="downloadfile">
+      <param name="sourcefile" value="${javassist.loc}"/>
+      <param name="destfile" value="${javassist.jar}"/>
+      <param name="destdir" value="${javassist.home}"/>
+      <param name="checksum.enabled" value="${javassist.checksum.enabled}"/>
+      <param name="checksum.algorithm" value="${javassist.checksum.algorithm}"/>
+      <param name="checksum.value" value="${javassist.checksum.value}"/>
+    </antcall>
+
   </target>
 
   <target name="download-test-compile"
diff --git a/java/org/apache/tomcat/websocket/server/UpgradeUtil.java b/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
index de6c352..9b96334 100644
--- a/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
+++ b/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
@@ -17,6 +17,7 @@
 package org.apache.tomcat.websocket.server;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -37,6 +38,9 @@ import jakarta.websocket.Extension;
 import jakarta.websocket.HandshakeResponse;
 import jakarta.websocket.server.ServerEndpointConfig;
 
+import javassist.util.proxy.MethodFilter;
+import javassist.util.proxy.ProxyFactory;
+
 import org.apache.tomcat.util.codec.binary.Base64;
 import org.apache.tomcat.util.res.StringManager;
 import org.apache.tomcat.util.security.ConcurrentMessageDigest;
@@ -54,6 +58,8 @@ public class UpgradeUtil {
     private static final byte[] WS_ACCEPT =
             "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(
                     StandardCharsets.ISO_8859_1);
+    private static final MethodFilter PER_SESSION_USER_PROPERTIES_METHOD_FILTER =
+            new WsPerSessionUserPropertiesMethodFilter();
 
     private UpgradeUtil() {
         // Utility class. Hide default constructor.
@@ -219,8 +225,19 @@ public class UpgradeUtil {
             }
         }
 
-        WsPerSessionServerEndpointConfig perSessionServerEndpointConfig =
-                new WsPerSessionServerEndpointConfig(sec);
+        ProxyFactory factory = new ProxyFactory();
+        factory.setSuperclass(sec.getClass());
+        factory.setFilter(PER_SESSION_USER_PROPERTIES_METHOD_FILTER);
+
+        ServerEndpointConfig perSessionServerEndpointConfig;
+        try {
+            perSessionServerEndpointConfig = (ServerEndpointConfig) factory.create(
+                    new Class<?>[0], new Object[0], new WsPerSessionUserPropertiesMethodHandler(sec));
+        } catch (NoSuchMethodException | IllegalArgumentException | InstantiationException | IllegalAccessException
+                | InvocationTargetException e) {
+            // Should never happen
+            throw new IllegalStateException(e);
+        }
 
         WsHandshakeRequest wsRequest = new WsHandshakeRequest(req, pathParams);
         WsHandshakeResponse wsResponse = new WsHandshakeResponse();
diff --git a/java/org/apache/tomcat/websocket/server/WsPerSessionServerEndpointConfig.java b/java/org/apache/tomcat/websocket/server/WsPerSessionServerEndpointConfig.java
deleted file mode 100644
index 07452e9..0000000
--- a/java/org/apache/tomcat/websocket/server/WsPerSessionServerEndpointConfig.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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 java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import jakarta.websocket.Decoder;
-import jakarta.websocket.Encoder;
-import jakarta.websocket.Extension;
-import jakarta.websocket.server.ServerEndpointConfig;
-
-/**
- * Wraps the provided {@link ServerEndpointConfig} and provides a per session
- * view - the difference being that the map returned by {@link
- * #getUserProperties()} is unique to this instance rather than shared with the
- * wrapped {@link ServerEndpointConfig}.
- */
-class WsPerSessionServerEndpointConfig implements ServerEndpointConfig {
-
-    private final ServerEndpointConfig perEndpointConfig;
-    private final Map<String,Object> perSessionUserProperties =
-            new ConcurrentHashMap<>();
-
-    WsPerSessionServerEndpointConfig(ServerEndpointConfig perEndpointConfig) {
-        this.perEndpointConfig = perEndpointConfig;
-        perSessionUserProperties.putAll(perEndpointConfig.getUserProperties());
-    }
-
-    @Override
-    public List<Class<? extends Encoder>> getEncoders() {
-        return perEndpointConfig.getEncoders();
-    }
-
-    @Override
-    public List<Class<? extends Decoder>> getDecoders() {
-        return perEndpointConfig.getDecoders();
-    }
-
-    @Override
-    public Map<String,Object> getUserProperties() {
-        return perSessionUserProperties;
-    }
-
-    @Override
-    public Class<?> getEndpointClass() {
-        return perEndpointConfig.getEndpointClass();
-    }
-
-    @Override
-    public String getPath() {
-        return perEndpointConfig.getPath();
-    }
-
-    @Override
-    public List<String> getSubprotocols() {
-        return perEndpointConfig.getSubprotocols();
-    }
-
-    @Override
-    public List<Extension> getExtensions() {
-        return perEndpointConfig.getExtensions();
-    }
-
-    @Override
-    public Configurator getConfigurator() {
-        return perEndpointConfig.getConfigurator();
-    }
-}
diff --git a/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodFilter.java b/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodFilter.java
new file mode 100644
index 0000000..991ca17
--- /dev/null
+++ b/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodFilter.java
@@ -0,0 +1,29 @@
+/*
+ * 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 java.lang.reflect.Method;
+
+import javassist.util.proxy.MethodFilter;
+
+public class WsPerSessionUserPropertiesMethodFilter implements MethodFilter {
+
+    @Override
+    public boolean isHandled(Method method) {
+        return method.getName().equals("getUserProperties") & method.getParameterCount() == 0;
+    }
+}
diff --git a/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodHandler.java b/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodHandler.java
new file mode 100644
index 0000000..76f0d0c
--- /dev/null
+++ b/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodHandler.java
@@ -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 java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import jakarta.websocket.server.ServerEndpointConfig;
+
+import javassist.util.proxy.MethodHandler;
+
+public class WsPerSessionUserPropertiesMethodHandler implements MethodHandler {
+
+    private final Map<String,Object> perSessionUserProperties = new ConcurrentHashMap<>();
+
+
+    public WsPerSessionUserPropertiesMethodHandler(ServerEndpointConfig perEndpointConfig) {
+        perSessionUserProperties.putAll(perEndpointConfig.getUserProperties());
+    }
+
+
+    @Override
+    public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
+        return perSessionUserProperties;
+    }
+
+}
diff --git a/res/checkstyle/checkstyle.xml b/res/checkstyle/checkstyle.xml
index ed16bc3..3aa631e 100644
--- a/res/checkstyle/checkstyle.xml
+++ b/res/checkstyle/checkstyle.xml
@@ -69,7 +69,7 @@
         <property name="illegalPkgs" value="sun,junit.framework"/>
     </module>
     <module name="ImportOrder">
-        <property name="groups" value="java,javax,jakarta,org.hamcrest,org.junit,org,async,jsp2,util"/>
+        <property name="groups" value="java,javax,jakarta,javassist,org.hamcrest,org.junit,org,async,jsp2,util"/>
         <property name="ordered" value="true"/>
         <property name="separated" value="true"/>
         <property name="option" value="above"/>
diff --git a/res/checkstyle/org-import-control.xml b/res/checkstyle/org-import-control.xml
index 29ea88f..3320e38 100644
--- a/res/checkstyle/org-import-control.xml
+++ b/res/checkstyle/org-import-control.xml
@@ -188,6 +188,7 @@
         <allow pkg="jakarta.servlet"/>
         <allow pkg="org.apache.coyote.http11.upgrade"/>
         <allow pkg="org.apache.tomcat.websocket"/>
+        <allow pkg="javassist.util.proxy"/>
       </subpackage>
     </subpackage>
   </subpackage>

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


Re: [tomcat] 01/01: First pass at implementing per session user properties using a proxy

Posted by Mark Thomas <ma...@apache.org>.
Sorry. Wring repo. I've removed this branch and pushed it to my fork.

Mark


On 03/03/2022 17:01, markt@apache.org wrote:
> This is an automated email from the ASF dual-hosted git repository.
> 
> markt pushed a commit to branch websocket-userproperties-proxy
> in repository https://gitbox.apache.org/repos/asf/tomcat.git
> 
> commit e61e9ad4ece051df45d4144c16c557a58b2a9286
> Author: Mark Thomas <ma...@apache.org>
> AuthorDate: Thu Mar 3 17:00:45 2022 +0000
> 
>      First pass at implementing per session user properties using a proxy
>      
>      Compared to wrapping this has the benefit that the user can still cast
>      their ServerEndpointConfig instance to the original implementation class
>      and access implementation specfic methods.
> ---
>   build.properties.default                           |  9 +++
>   build.xml                                          | 22 ++++++
>   .../tomcat/websocket/server/UpgradeUtil.java       | 21 +++++-
>   .../server/WsPerSessionServerEndpointConfig.java   | 84 ----------------------
>   .../WsPerSessionUserPropertiesMethodFilter.java    | 29 ++++++++
>   .../WsPerSessionUserPropertiesMethodHandler.java   | 42 +++++++++++
>   res/checkstyle/checkstyle.xml                      |  2 +-
>   res/checkstyle/org-import-control.xml              |  1 +
>   8 files changed, 123 insertions(+), 87 deletions(-)
> 
> diff --git a/build.properties.default b/build.properties.default
> index d5bdf0e..773ba42 100644
> --- a/build.properties.default
> +++ b/build.properties.default
> @@ -217,6 +217,15 @@ commons-daemon.native.src.loc.2=${base-commons.loc.2}/daemon/source/commons-daem
>   commons-daemon.native.win.loc.1=${base-commons.loc.1}/daemon/binaries/windows/commons-daemon-${commons-daemon.version}-bin-windows.zip
>   commons-daemon.native.win.loc.2=${base-commons.loc.2}/daemon/binaries/windows/commons-daemon-${commons-daemon.version}-bin-windows.zip
>   
> +# ----- Javassist 3.28.0-GA or later -----
> +javassist.version=3.28.0-GA
> +javassist.checksum.enabled=true
> +javassist.checksum.algorithm=MD5|SHA-1
> +javassist.checksum.value=1a2dd8c76321cef26cc2669fe70a2557|9a958811a88381bb159cc2f5ed79c34a45c4af7a
> +javassist.home=${base.path}/javassist-${javassist.version}
> +javassist.jar=${javassist.home}/javassist-${javassist.version}.jar
> +javassist.loc=${base-maven.loc}/org/javassist/javassist/${javassist.version}/javassist-${javassist.version}.jar
> +
>   # ----- JUnit Unit Test Suite, version 4.11 or later -----
>   junit.version=4.13.2
>   junit.checksum.enabled=true
> diff --git a/build.xml b/build.xml
> index fb5c56a..a448531 100644
> --- a/build.xml
> +++ b/build.xml
> @@ -220,6 +220,7 @@
>       <pathelement location="${jaxrpc-lib.jar}"/>
>       <pathelement location="${wsdl4j-lib.jar}"/>
>       <pathelement location="${migration-lib.jar}"/>
> +    <pathelement location="${javassist.jar}"/>
>     </path>
>   
>     <path id="tomcat.classpath">
> @@ -1492,6 +1493,17 @@
>       </delete>
>       <copy file="${migration-lib.jar}" todir="${tomcat.build}/lib"/>
>   
> +    <!-- Delete all other versions of Javassist and copy the current one -->
> +    <local name="javassist.jar.filename" />
> +    <basename property="javassist.jar.filename" file="${javassist.jar}"/>
> +    <delete verbose="true">
> +      <fileset dir="${tomcat.build}/lib">
> +        <include name="javassist-*.jar"/>
> +        <exclude name="${javassist.jar.filename}"/>
> +      </fileset>
> +    </delete>
> +    <copy file="${javassist.jar}" todir="${tomcat.build}/lib"/>
> +
>       <!-- Delete all other versions of OpenSSL support for Tomcat and copy the current one -->
>       <!-- After module release
>       <local name="openssl-lib.jar.filename" />
> @@ -3162,6 +3174,16 @@ skip.installer property in build.properties" />
>         <param name="checksum.value" value="${migration-lib.checksum.value}"/>
>       </antcall>
>   
> +    <!-- Javassist -->
> +    <antcall target="downloadfile">
> +      <param name="sourcefile" value="${javassist.loc}"/>
> +      <param name="destfile" value="${javassist.jar}"/>
> +      <param name="destdir" value="${javassist.home}"/>
> +      <param name="checksum.enabled" value="${javassist.checksum.enabled}"/>
> +      <param name="checksum.algorithm" value="${javassist.checksum.algorithm}"/>
> +      <param name="checksum.value" value="${javassist.checksum.value}"/>
> +    </antcall>
> +
>     </target>
>   
>     <target name="download-test-compile"
> diff --git a/java/org/apache/tomcat/websocket/server/UpgradeUtil.java b/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
> index de6c352..9b96334 100644
> --- a/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
> +++ b/java/org/apache/tomcat/websocket/server/UpgradeUtil.java
> @@ -17,6 +17,7 @@
>   package org.apache.tomcat.websocket.server;
>   
>   import java.io.IOException;
> +import java.lang.reflect.InvocationTargetException;
>   import java.nio.charset.StandardCharsets;
>   import java.util.ArrayList;
>   import java.util.Collections;
> @@ -37,6 +38,9 @@ import jakarta.websocket.Extension;
>   import jakarta.websocket.HandshakeResponse;
>   import jakarta.websocket.server.ServerEndpointConfig;
>   
> +import javassist.util.proxy.MethodFilter;
> +import javassist.util.proxy.ProxyFactory;
> +
>   import org.apache.tomcat.util.codec.binary.Base64;
>   import org.apache.tomcat.util.res.StringManager;
>   import org.apache.tomcat.util.security.ConcurrentMessageDigest;
> @@ -54,6 +58,8 @@ public class UpgradeUtil {
>       private static final byte[] WS_ACCEPT =
>               "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(
>                       StandardCharsets.ISO_8859_1);
> +    private static final MethodFilter PER_SESSION_USER_PROPERTIES_METHOD_FILTER =
> +            new WsPerSessionUserPropertiesMethodFilter();
>   
>       private UpgradeUtil() {
>           // Utility class. Hide default constructor.
> @@ -219,8 +225,19 @@ public class UpgradeUtil {
>               }
>           }
>   
> -        WsPerSessionServerEndpointConfig perSessionServerEndpointConfig =
> -                new WsPerSessionServerEndpointConfig(sec);
> +        ProxyFactory factory = new ProxyFactory();
> +        factory.setSuperclass(sec.getClass());
> +        factory.setFilter(PER_SESSION_USER_PROPERTIES_METHOD_FILTER);
> +
> +        ServerEndpointConfig perSessionServerEndpointConfig;
> +        try {
> +            perSessionServerEndpointConfig = (ServerEndpointConfig) factory.create(
> +                    new Class<?>[0], new Object[0], new WsPerSessionUserPropertiesMethodHandler(sec));
> +        } catch (NoSuchMethodException | IllegalArgumentException | InstantiationException | IllegalAccessException
> +                | InvocationTargetException e) {
> +            // Should never happen
> +            throw new IllegalStateException(e);
> +        }
>   
>           WsHandshakeRequest wsRequest = new WsHandshakeRequest(req, pathParams);
>           WsHandshakeResponse wsResponse = new WsHandshakeResponse();
> diff --git a/java/org/apache/tomcat/websocket/server/WsPerSessionServerEndpointConfig.java b/java/org/apache/tomcat/websocket/server/WsPerSessionServerEndpointConfig.java
> deleted file mode 100644
> index 07452e9..0000000
> --- a/java/org/apache/tomcat/websocket/server/WsPerSessionServerEndpointConfig.java
> +++ /dev/null
> @@ -1,84 +0,0 @@
> -/*
> - * 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 java.util.List;
> -import java.util.Map;
> -import java.util.concurrent.ConcurrentHashMap;
> -
> -import jakarta.websocket.Decoder;
> -import jakarta.websocket.Encoder;
> -import jakarta.websocket.Extension;
> -import jakarta.websocket.server.ServerEndpointConfig;
> -
> -/**
> - * Wraps the provided {@link ServerEndpointConfig} and provides a per session
> - * view - the difference being that the map returned by {@link
> - * #getUserProperties()} is unique to this instance rather than shared with the
> - * wrapped {@link ServerEndpointConfig}.
> - */
> -class WsPerSessionServerEndpointConfig implements ServerEndpointConfig {
> -
> -    private final ServerEndpointConfig perEndpointConfig;
> -    private final Map<String,Object> perSessionUserProperties =
> -            new ConcurrentHashMap<>();
> -
> -    WsPerSessionServerEndpointConfig(ServerEndpointConfig perEndpointConfig) {
> -        this.perEndpointConfig = perEndpointConfig;
> -        perSessionUserProperties.putAll(perEndpointConfig.getUserProperties());
> -    }
> -
> -    @Override
> -    public List<Class<? extends Encoder>> getEncoders() {
> -        return perEndpointConfig.getEncoders();
> -    }
> -
> -    @Override
> -    public List<Class<? extends Decoder>> getDecoders() {
> -        return perEndpointConfig.getDecoders();
> -    }
> -
> -    @Override
> -    public Map<String,Object> getUserProperties() {
> -        return perSessionUserProperties;
> -    }
> -
> -    @Override
> -    public Class<?> getEndpointClass() {
> -        return perEndpointConfig.getEndpointClass();
> -    }
> -
> -    @Override
> -    public String getPath() {
> -        return perEndpointConfig.getPath();
> -    }
> -
> -    @Override
> -    public List<String> getSubprotocols() {
> -        return perEndpointConfig.getSubprotocols();
> -    }
> -
> -    @Override
> -    public List<Extension> getExtensions() {
> -        return perEndpointConfig.getExtensions();
> -    }
> -
> -    @Override
> -    public Configurator getConfigurator() {
> -        return perEndpointConfig.getConfigurator();
> -    }
> -}
> diff --git a/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodFilter.java b/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodFilter.java
> new file mode 100644
> index 0000000..991ca17
> --- /dev/null
> +++ b/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodFilter.java
> @@ -0,0 +1,29 @@
> +/*
> + * 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 java.lang.reflect.Method;
> +
> +import javassist.util.proxy.MethodFilter;
> +
> +public class WsPerSessionUserPropertiesMethodFilter implements MethodFilter {
> +
> +    @Override
> +    public boolean isHandled(Method method) {
> +        return method.getName().equals("getUserProperties") & method.getParameterCount() == 0;
> +    }
> +}
> diff --git a/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodHandler.java b/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodHandler.java
> new file mode 100644
> index 0000000..76f0d0c
> --- /dev/null
> +++ b/java/org/apache/tomcat/websocket/server/WsPerSessionUserPropertiesMethodHandler.java
> @@ -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 java.lang.reflect.Method;
> +import java.util.Map;
> +import java.util.concurrent.ConcurrentHashMap;
> +
> +import jakarta.websocket.server.ServerEndpointConfig;
> +
> +import javassist.util.proxy.MethodHandler;
> +
> +public class WsPerSessionUserPropertiesMethodHandler implements MethodHandler {
> +
> +    private final Map<String,Object> perSessionUserProperties = new ConcurrentHashMap<>();
> +
> +
> +    public WsPerSessionUserPropertiesMethodHandler(ServerEndpointConfig perEndpointConfig) {
> +        perSessionUserProperties.putAll(perEndpointConfig.getUserProperties());
> +    }
> +
> +
> +    @Override
> +    public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
> +        return perSessionUserProperties;
> +    }
> +
> +}
> diff --git a/res/checkstyle/checkstyle.xml b/res/checkstyle/checkstyle.xml
> index ed16bc3..3aa631e 100644
> --- a/res/checkstyle/checkstyle.xml
> +++ b/res/checkstyle/checkstyle.xml
> @@ -69,7 +69,7 @@
>           <property name="illegalPkgs" value="sun,junit.framework"/>
>       </module>
>       <module name="ImportOrder">
> -        <property name="groups" value="java,javax,jakarta,org.hamcrest,org.junit,org,async,jsp2,util"/>
> +        <property name="groups" value="java,javax,jakarta,javassist,org.hamcrest,org.junit,org,async,jsp2,util"/>
>           <property name="ordered" value="true"/>
>           <property name="separated" value="true"/>
>           <property name="option" value="above"/>
> diff --git a/res/checkstyle/org-import-control.xml b/res/checkstyle/org-import-control.xml
> index 29ea88f..3320e38 100644
> --- a/res/checkstyle/org-import-control.xml
> +++ b/res/checkstyle/org-import-control.xml
> @@ -188,6 +188,7 @@
>           <allow pkg="jakarta.servlet"/>
>           <allow pkg="org.apache.coyote.http11.upgrade"/>
>           <allow pkg="org.apache.tomcat.websocket"/>
> +        <allow pkg="javassist.util.proxy"/>
>         </subpackage>
>       </subpackage>
>     </subpackage>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
> 

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