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

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


The following commit(s) were added to refs/heads/11.0.x by this push:
     new 5a31ff16ef WeSocket client's shouldn't request extensions they can't 
support
5a31ff16ef is described below

commit 5a31ff16ef5f4ab1d1773f3c5399c9238839d069
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jul 25 08:40:04 2025 +0100

    WeSocket client's shouldn't request extensions they can't support
    
    Align the WebSocket extension handling for WebSocket client connections
    with WebSocket server connections. The WebSocket client now only
    includes an extension requested by an endpoint in the opening handshake
    if the WebSocket client supports that extension.
---
 .../tomcat/websocket/TransformationFactory.java       | 17 +++++++++++++++++
 .../apache/tomcat/websocket/WsWebSocketContainer.java | 19 ++++++++++++++++---
 webapps/docs/changelog.xml                            | 10 ++++++++++
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/java/org/apache/tomcat/websocket/TransformationFactory.java 
b/java/org/apache/tomcat/websocket/TransformationFactory.java
index c94a813e11..b5a4ba3078 100644
--- a/java/org/apache/tomcat/websocket/TransformationFactory.java
+++ b/java/org/apache/tomcat/websocket/TransformationFactory.java
@@ -16,9 +16,12 @@
  */
 package org.apache.tomcat.websocket;
 
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import jakarta.websocket.Extension;
 
@@ -54,4 +57,18 @@ public class TransformationFactory {
     public void registerExtension(String name, TransformationBuilder builder) {
         builders.put(name, builder);
     }
+
+
+    public Set<String> getInstalledExtensionNames() {
+        return new HashSet<>(builders.keySet());
+    }
+
+
+    public Set<Extension> getInstalledExtensions() {
+        Set<Extension> result = new HashSet<>();
+        for (String extensionName : builders.keySet()) {
+            result.add(new WsExtension(extensionName));
+        }
+        return Collections.unmodifiableSet(result);
+    }
 }
diff --git a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java 
b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
index db73393d7d..d261ba336f 100644
--- a/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
+++ b/java/org/apache/tomcat/websocket/WsWebSocketContainer.java
@@ -34,6 +34,7 @@ import java.util.Base64;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -663,8 +664,20 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
         }
 
         // WebSocket extensions
-        if (extensions != null && !extensions.isEmpty()) {
-            headers.put(Constants.WS_EXTENSIONS_HEADER_NAME, 
generateExtensionHeaders(extensions));
+        if (extensions != null) {
+            // Filter the requested extensions to remove any that are not 
supported by the client container.
+            Set<String> installed = 
TransformationFactory.getInstance().getInstalledExtensionNames();
+            List<Extension> availableExtensions = new ArrayList<>(extensions);
+            Iterator<Extension> availableExtensionsIter = 
availableExtensions.iterator();
+            while (availableExtensionsIter.hasNext()) {
+                Extension e = availableExtensionsIter.next();
+                if (!installed.contains(e.getName())) {
+                    availableExtensionsIter.remove();
+                }
+            }
+            if (!availableExtensions.isEmpty()) {
+                headers.put(Constants.WS_EXTENSIONS_HEADER_NAME, 
generateExtensionHeaders(availableExtensions));
+            }
         }
 
         return headers;
@@ -946,7 +959,7 @@ public class WsWebSocketContainer implements 
WebSocketContainer, BackgroundProce
      */
     @Override
     public Set<Extension> getInstalledExtensions() {
-        return Collections.emptySet();
+        return TransformationFactory.getInstance().getInstalledExtensions();
     }
 
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 367f10c13d..6dd8653def 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -130,6 +130,16 @@
       </update>
     </changelog>
   </subsection>
+  <subsection name="WebSocket">
+    <changelog>
+      <fix>
+        Align the WebSocket extension handling for WebSocket client connections
+        with WebSocket server connections. The WebSocket client now only
+        includes an extension requested by an endpoint in the opening handshake
+        if the WebSocket client supports that extension. (markt)
+      </fix>
+    </changelog>
+  </subsection>
 </section>
 <section name="Tomcat 11.0.9 (markt)" rtext="2025-07-04">
   <subsection name="Catalina">


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

Reply via email to