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

davsclaus pushed a commit to branch backport/25367-to-camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 846c3469ddc75b0ffa21833a19a1080553a5ba85
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu Aug 6 12:35:23 2026 +0200

    CAMEL-24360: camel-undertow - use UndertowHeaderFilterStrategy as the 
endpoint default
    
    UndertowEndpoint defaulted its headerFilterStrategy to the base
    HttpHeaderFilterStrategy and pushed it into the lazily created binding,
    overwriting the UndertowHeaderFilterStrategy the binding's constructor had
    installed. This made the undertow-specific filtering (websocket.* prefix
    filtering from CAMEL-23588, HttpString header-name validation) inert on
    endpoint-configured routes.
    
    The endpoint now defaults to UndertowHeaderFilterStrategy. Rest DSL 
consumers
    are unchanged (UndertowComponent already assigns 
UndertowRestHeaderFilterStrategy).
    Endpoints that configure headerFilterStrategy or undertowHttpBinding 
explicitly
    keep their existing behaviour.
    
    Adds UndertowEndpointTest cases and a 4.22 upgrade-guide entry.
    
    Closes #25367
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 components/camel-undertow/pom.xml                  | 11 +++++++
 .../camel/component/undertow/UndertowEndpoint.java |  3 +-
 .../component/undertow/UndertowEndpointTest.java   | 34 ++++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_18.adoc    | 31 ++++++++++++++++++++
 4 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/components/camel-undertow/pom.xml 
b/components/camel-undertow/pom.xml
index be86a3e878f0..be05b384a442 100644
--- a/components/camel-undertow/pom.xml
+++ b/components/camel-undertow/pom.xml
@@ -139,6 +139,17 @@
             <artifactId>junit-jupiter</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <version>${awaitility-version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.eclipse.jetty.http2</groupId>
             <artifactId>jetty-http2-client</artifactId>
diff --git 
a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
 
b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
index 1edcadeaf1d4..3cd6cc3ff99e 100644
--- 
a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
+++ 
b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
@@ -39,7 +39,6 @@ import org.apache.camel.cloud.ServiceDefinition;
 import org.apache.camel.component.undertow.UndertowConstants.EventType;
 import org.apache.camel.component.undertow.handlers.CamelWebSocketHandler;
 import org.apache.camel.component.undertow.spi.UndertowSecurityProvider;
-import org.apache.camel.http.base.HttpHeaderFilterStrategy;
 import org.apache.camel.http.base.cookie.CookieHandler;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.HeaderFilterStrategy;
@@ -85,7 +84,7 @@ public class UndertowEndpoint extends DefaultEndpoint
     @UriParam(label = "advanced")
     private AccessLogReceiver accessLogReceiver;
     @UriParam(label = "advanced")
-    private HeaderFilterStrategy headerFilterStrategy = new 
HttpHeaderFilterStrategy();
+    private HeaderFilterStrategy headerFilterStrategy = new 
UndertowHeaderFilterStrategy();
     @UriParam(label = "security")
     private SSLContextParameters sslContextParameters;
     @UriParam(label = "consumer")
diff --git 
a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowEndpointTest.java
 
b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowEndpointTest.java
index 817a13a9da7f..75a8be7ffd02 100644
--- 
a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowEndpointTest.java
+++ 
b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowEndpointTest.java
@@ -18,9 +18,12 @@ package org.apache.camel.component.undertow;
 
 import java.net.URI;
 
+import org.apache.camel.http.base.HttpHeaderFilterStrategy;
+import org.apache.camel.spi.HeaderFilterStrategy;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 public class UndertowEndpointTest {
@@ -47,4 +50,35 @@ public class UndertowEndpointTest {
         endpoint.setHttpURI(withSlash);
         assertEquals(withSlash, endpoint.getHttpURI());
     }
+
+    @Test
+    void defaultHeaderFilterStrategyIsUndertowSpecific() {
+        
assertThat(endpoint.getHeaderFilterStrategy()).isInstanceOf(UndertowHeaderFilterStrategy.class);
+    }
+
+    @Test
+    void defaultBindingKeepsUndertowHeaderFilterStrategy() {
+        // the endpoint pushes its own strategy into the lazily created 
binding, so the endpoint default
+        // decides which strategy the binding ends up running
+        
assertThat(endpoint.getUndertowHttpBinding()).isInstanceOf(DefaultUndertowHttpBinding.class);
+        HeaderFilterStrategy strategy
+                = ((DefaultUndertowHttpBinding) 
endpoint.getUndertowHttpBinding()).getHeaderFilterStrategy();
+        assertThat(strategy).isInstanceOf(UndertowHeaderFilterStrategy.class);
+
+        // the undertow-specific prefixes added by CAMEL-23588 must therefore 
be in effect
+        
assertThat(strategy.applyFilterToExternalHeaders(UndertowConstants.CONNECTION_KEY,
 "aValue", null)).isTrue();
+        
assertThat(strategy.applyFilterToExternalHeaders(UndertowConstants.CONNECTION_KEY_LIST,
 "aValue", null)).isTrue();
+        
assertThat(strategy.applyFilterToExternalHeaders(UndertowConstants.SEND_TO_ALL, 
"aValue", null)).isTrue();
+        
assertThat(strategy.applyFilterToCamelHeaders(UndertowConstants.CONNECTION_KEY, 
"aValue", null)).isTrue();
+    }
+
+    @Test
+    void explicitHeaderFilterStrategyIsHandedToTheBinding() {
+        HeaderFilterStrategy custom = new HttpHeaderFilterStrategy();
+        endpoint.setHeaderFilterStrategy(custom);
+
+        
assertThat(endpoint.getUndertowHttpBinding()).isInstanceOf(DefaultUndertowHttpBinding.class);
+        assertThat(((DefaultUndertowHttpBinding) 
endpoint.getUndertowHttpBinding()).getHeaderFilterStrategy())
+                .isSameAs(custom);
+    }
 }
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
index d4b1db300808..573898a6e355 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
@@ -1298,6 +1298,37 @@ Routes that intentionally relied on undertow mapping 
`websocket.*` wire
 headers in or out can supply a custom `headerFilterStrategy` endpoint option
 to restore the previous behaviour.
 
+=== camel-undertow - UndertowHeaderFilterStrategy is now the endpoint default
+
+`UndertowEndpoint` defaulted its `headerFilterStrategy` to the base
+`HttpHeaderFilterStrategy`, and pushed that strategy into the 
`DefaultUndertowHttpBinding`
+it creates lazily, overwriting the `UndertowHeaderFilterStrategy` that the 
binding installs
+in its own constructor. The undertow-specific filtering was therefore not 
applied on
+endpoint-configured routes.
+
+The endpoint now defaults to `UndertowHeaderFilterStrategy`, which makes two 
already
+documented behaviours take effect:
+
+* The legacy `websocket.*` Exchange-header prefix, added to the in and out 
filters in
+  4.14.8 / 4.18.3 / 4.21.0 (see above), is now filtered at the undertow
+  transport boundary as described there.
+* Header names that undertow does not accept (those for which
+  `io.undertow.util.HttpString.tryFromString` returns `null`) are skipped when 
mapping
+  external headers in, rather than being mapped onto the message.
+
+Ordinary application headers are unaffected, and Rest DSL consumers already 
used an
+undertow-specific strategy (`UndertowRestHeaderFilterStrategy`) so their 
behaviour does not
+change. Routes that relied on `websocket.*` headers crossing the undertow 
boundary in either
+direction, and routes that relied on undertow-invalid header names being 
mapped, can restore
+the previous behaviour by configuring `headerFilterStrategy` explicitly on the 
endpoint:
+
+[source,java]
+----
+from("undertow:http://0.0.0.0:8080/foo?headerFilterStrategy=#myStrategy";)
+----
+
+Routes that already supply a custom `headerFilterStrategy` or a custom 
`undertowHttpBinding`
+are unaffected.
 
 === camel-aws2-sqs
 

Reply via email to