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

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


The following commit(s) were added to refs/heads/main by this push:
     new 571e164d59 WeSocket client's shouldn't request extensions they can't 
support
571e164d59 is described below

commit 571e164d5932635966735a51008ac95ce4d0d1d9
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                            |  6 ++++++
 3 files changed, 39 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 faef999e71..840538da00 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;
@@ -666,8 +667,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;
@@ -949,7 +962,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 f649693daf..f61de0ce57 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -267,6 +267,12 @@
         port information. (markt)
       </add>
       <!-- Entries for backport and removal before 12.0.0-M1 below this line 
-->
+      <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>
   <subsection name="Web applications">


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

Reply via email to