Skip to content

CAMEL-24360: camel-undertow - use UndertowHeaderFilterStrategy as the endpoint default - #25367

Open
oscerd wants to merge 1 commit into
apache:mainfrom
oscerd:fix/CAMEL-24360
Open

CAMEL-24360: camel-undertow - use UndertowHeaderFilterStrategy as the endpoint default#25367
oscerd wants to merge 1 commit into
apache:mainfrom
oscerd:fix/CAMEL-24360

Conversation

@oscerd

@oscerd oscerd commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Description

DefaultUndertowHttpBinding installs an UndertowHeaderFilterStrategy in its constructor:

public DefaultUndertowHttpBinding(boolean useStreaming) {
    this.headerFilterStrategy = new UndertowHeaderFilterStrategy();
    ...
}

but UndertowEndpoint defaulted its own field to the base HttpHeaderFilterStrategy and pushed that into the binding when creating it lazily, overwriting what the binding had just set:

private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();   // line 88

public UndertowHttpBinding getUndertowHttpBinding() {
    if (undertowHttpBinding == null) {
        undertowHttpBinding = new DefaultUndertowHttpBinding(useStreaming);
        undertowHttpBinding.setHeaderFilterStrategy(getHeaderFilterStrategy());        // overwrites it
        ...

Unless the user supplied a custom binding or a custom headerFilterStrategy, the binding ran the base strategy and the undertow-specific filtering never executed.

Impact

Two behaviours documented as shipped were inert on endpoint-configured routes:

  • the legacy websocket.* Exchange-header prefix added to the in/out filters by CAMEL-23588 (released in 4.14.8 / 4.18.3 / 4.21.0 and described in the 4.18 upgrade guide);
  • the io.undertow.util.HttpString.tryFromString header-name validation in UndertowHeaderFilterStrategy.applyFilterToExternalHeaders, which skips header names undertow does not accept.

Documentation and runtime behaviour had therefore diverged since CAMEL-23588.

Fix

UndertowEndpoint now defaults to UndertowHeaderFilterStrategy, so both take effect.

  • Rest DSL consumers are unchanged: UndertowComponent already assigns UndertowRestHeaderFilterStrategy, which extends UndertowHeaderFilterStrategy.
  • Endpoints configuring headerFilterStrategy or undertowHttpBinding explicitly keep their behaviour.
  • Ordinary application headers are unaffected; the two added filters are narrow.

The now-unused HttpHeaderFilterStrategy import is removed. No generated metadata changes, since the catalog records only the HeaderFilterStrategy interface and not the default implementation class.

Changes

  • UndertowEndpoint - default strategy, unused import
  • UndertowEndpointTest - three cases: the endpoint default is undertow-specific; the lazily created binding keeps it and actually filters UndertowConstants.CONNECTION_KEY / CONNECTION_KEY_LIST / SEND_TO_ALL; an explicitly configured strategy still reaches the binding
  • 4.22 upgrade-guide entry, including how to restore the previous behaviour

Testing

  • camel-undertow module build green: 191 tests pass, 0 failures, 1 skipped. The websocket suites (UndertowWsConsumerRouteTest, UndertowWsTwoRoutesToSameEndpointSendToAllHeaderTest, ...) all still pass, since the producer reads those headers via in.getHeader(...), which does not go through the HeaderFilterStrategy.
  • Full reactor build from root (mvn clean install -DskipTests) green, no regenerated-artifact drift.

Backport

UndertowEndpoint line 88 and DefaultUndertowHttpBinding line 86 are identical on main, camel-4.18.x and camel-4.14.x, so this should be backported to both LTS lines (with the matching 4.18 / 4.14 upgrade-guide entries doc-synced back to main per the backport policy). Backporting matters here because CAMEL-23588 shipped on those branches and its documented effect is what this restores.


Claude Code on behalf of oscerd

… endpoint default

DefaultUndertowHttpBinding installs an UndertowHeaderFilterStrategy in its
constructor, but UndertowEndpoint defaulted its own headerFilterStrategy to the
base HttpHeaderFilterStrategy and pushed that into the binding when lazily
creating it, overwriting the undertow-specific strategy. Unless the user
supplied a custom binding or a custom headerFilterStrategy, the binding ran the
base strategy and the undertow-specific filtering never executed.

Two behaviours that are documented as shipped were therefore inert on
endpoint-configured routes:

  * the legacy websocket.* Exchange-header prefix added to the in and out
    filters by CAMEL-23588 (4.14.8 / 4.18.3 / 4.21.0);
  * the io.undertow.util.HttpString.tryFromString header-name validation in
    UndertowHeaderFilterStrategy.applyFilterToExternalHeaders, which skips
    header names undertow does not accept.

The endpoint now defaults to UndertowHeaderFilterStrategy, so both take effect.
Rest DSL consumers are unchanged: UndertowComponent already assigns
UndertowRestHeaderFilterStrategy, which extends UndertowHeaderFilterStrategy.
Endpoints that configure headerFilterStrategy or undertowHttpBinding explicitly
keep their existing behaviour.

Adds three UndertowEndpointTest cases covering the endpoint default, the
strategy the lazily created binding ends up running together with the websocket
prefixes actually being filtered, and an explicitly configured strategy still
reaching the binding. Adds a 4.22 upgrade-guide entry describing the change and
how to restore the previous behaviour.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrea Cosentino <ancosen@gmail.com>
@oscerd
oscerd requested review from davsclaus and gnodet August 5, 2026 22:40
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-undertow
  • docs

ℹ️ Dependent modules were not tested because the total number of affected modules exceeded the threshold (50). Use the test-dependents label to force testing all dependents.


🔬 Scalpel shadow comparison — Scalpel: 39 tested, 28 compile-only — current: 38 all tested

Maveniverse Scalpel detected 67 affected modules (current approach: 38).

⚠️ Modules only in Scalpel (29)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

Skip-tests mode would test 39 modules (2 direct + 37 downstream), skip tests for 28 (generated code, meta-modules)

Modules Scalpel would test (39)
  • camel-a2a
  • camel-consul
  • camel-cxf-rest
  • camel-cxf-soap
  • camel-cxf-spring-rest
  • camel-cxf-spring-soap
  • camel-cxf-spring-transport
  • camel-cxf-transport
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-jsonpath
  • camel-knative-http
  • camel-launcher-container
  • camel-lra
  • camel-mcp-server
  • camel-micrometer-observability
  • camel-micrometer-prometheus
  • camel-oauth
  • camel-observability-services
  • camel-openapi-validator
  • camel-opentelemetry
  • camel-opentelemetry2
  • camel-platform-http-main
  • camel-platform-http-vertx
  • camel-rest-openapi
  • camel-slack
  • camel-soap
  • camel-telemetry
  • camel-telemetry-dev
  • camel-undertow
  • camel-undertow-spring-security
  • camel-vertx-http
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
  • camel-zookeeper
  • docs
Modules with tests skipped (28)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-lucene
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-csimple-maven-plugin
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

Build reactor — dependencies compiled but only changed modules were tested (67 modules)
  • Camel :: AI :: A2A
  • Camel :: AI :: MCP Server
  • Camel :: All Components Sync point
  • Camel :: Assembly
  • Camel :: CXF :: REST
  • Camel :: CXF :: REST :: Spring
  • Camel :: CXF :: SOAP
  • Camel :: CXF :: SOAP :: Spring
  • Camel :: CXF :: Transport
  • Camel :: CXF :: Transport :: Spring
  • Camel :: Catalog :: CSimple Maven Plugin (deprecated)
  • Camel :: Catalog :: Camel Catalog
  • Camel :: Catalog :: Camel Report Maven Plugin
  • Camel :: Catalog :: Camel Route Parser
  • Camel :: Catalog :: Console
  • Camel :: Catalog :: Dummy Component
  • Camel :: Catalog :: Lucene (deprecated)
  • Camel :: Catalog :: Maven
  • Camel :: Catalog :: Suggest
  • Camel :: Common Telemetry
  • Camel :: Component DSL
  • Camel :: Consul
  • Camel :: Coverage
  • Camel :: Docs
  • Camel :: Endpoint DSL
  • Camel :: Endpoint DSL :: Support
  • Camel :: Integration Tests
  • Camel :: JBang :: Core
  • Camel :: JBang :: Integration tests
  • Camel :: JBang :: MCP
  • Camel :: JBang :: Main
  • Camel :: JBang :: Plugin :: Edit
  • Camel :: JBang :: Plugin :: Generate
  • Camel :: JBang :: Plugin :: Kubernetes
  • Camel :: JBang :: Plugin :: MCP
  • Camel :: JBang :: Plugin :: Route Parser
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: JBang :: Plugin :: Testing
  • Camel :: JBang :: Plugin :: Validate
  • Camel :: JSon Path
  • Camel :: Kamelet Main
  • Camel :: Knative HTTP
  • Camel :: Launcher
  • Camel :: Launcher :: Container
  • Camel :: Long-Running-Action
  • Camel :: Micrometer :: Observability 2
  • Camel :: Micrometer :: Prometheus
  • Camel :: OAuth
  • Camel :: Observability Services
  • Camel :: OpenAPI :: Validator
  • Camel :: OpenTelemetry (deprecated)
  • Camel :: Opentelemetry 2
  • Camel :: Platform HTTP :: Main
  • Camel :: Platform HTTP :: Vert.x
  • Camel :: REST OpenApi
  • Camel :: SOAP
  • Camel :: Slack
  • Camel :: Telemetry :: Dev
  • Camel :: Undertow
  • Camel :: Undertow Spring Security
  • Camel :: Vert.x :: HTTP
  • Camel :: YAML DSL
  • Camel :: YAML DSL :: Deserializers
  • Camel :: YAML DSL :: Maven Plugins
  • Camel :: YAML DSL :: Validator
  • Camel :: YAML DSL :: Validator Maven Plugin
  • Camel :: Zookeeper

⚙️ View full build and test results

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant