This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch backport/25367-to-camel-4.14.x in repository https://gitbox.apache.org/repos/asf/camel.git
commit 8f9daa957fe7928a13290fb00de526316c66f48f 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_14.adoc | 31 ++++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/components/camel-undertow/pom.xml b/components/camel-undertow/pom.xml index f13a94bf1e4a..843fda26542b 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_14.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc index 146640138815..2895ddb52ca9 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_14.adoc @@ -1129,6 +1129,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
