From 167fdb5665582bd870854e77799966b656a2b543 Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Sat, 30 May 2026 16:49:36 -0400 Subject: [PATCH 1/8] CAMEL-23543: Centralize Camel* inbound/outbound header filtering in DefaultHeaderFilterStrategy - Default `inFilterStartsWith` and `outFilterStartsWith` to `CAMEL_FILTER_STARTS_WITH` in `DefaultHeaderFilterStrategy`, so all consumers and producers block `Camel*`, `camel*`, and `org.apache.camel.*` headers by default without per-component boilerplate - Extend `CAMEL_FILTER_STARTS_WITH` to include `org.apache.camel.` alongside `Camel` and `camel` - Remove now-redundant `setInFilterStartsWith` / `setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH)` calls from 20+ component-specific strategies - `ClassicJmsHeaderFilterStrategy` explicitly opts out (null) to preserve legacy pass-through behavior - `KafkaHeaderFilterStrategy` builds its array from the constant + `kafka.` via `Arrays.copyOf` - `Sns2` / `Sqs2` / `KnativeHttp` replace redundant regex patterns with a `getOutFilter().add("breadcrumbId")` set entry (SNS/SQS) or no extra filtering (Knative), relying on the default startsWith - Add tests verifying both directions filter by default; update 4.21 upgrade guide Co-Authored-By: Claude Sonnet 4.6 rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED --- .../aws2/sns/Sns2HeaderFilterStrategy.java | 5 +--- .../aws2/sqs/Sqs2HeaderFilterStrategy.java | 4 +-- .../ServiceBusHeaderFilterStrategy.java | 2 -- .../camel/coap/CoAPHeaderFilterStrategy.java | 2 -- .../cometd/CometdHeaderFilterStrategy.java | 2 -- .../cxf/jaxrs/CxfRsHeaderFilterStrategy.java | 3 -- .../header/CxfHeaderFilterStrategy.java | 3 -- .../GooglePubsubHeaderFilterStrategy.java | 2 -- .../http/base/HttpHeaderFilterStrategy.java | 4 --- .../http/common/HttpHeaderFilterStrategy.java | 4 --- .../iggy/IggyHeaderFilterStrategy.java | 2 -- .../jms/ClassicJmsHeaderFilterStrategy.java | 2 ++ .../jms/JmsHeaderFilterStrategy.java | 2 -- .../kafka/KafkaHeaderFilterStrategy.java | 10 +++++-- .../http/KnativeHttpHeaderFilterStrategy.java | 5 ---- .../mail/MailHeaderFilterStrategy.java | 2 -- .../nats/NatsHeaderFilterStrategy.java | 3 -- .../http/NettyHttpHeaderFilterStrategy.java | 4 --- .../sjms/SjmsHeaderFilterStrategy.java | 2 -- .../SpringRabbitMQHeaderFilterStrategy.java | 2 -- .../http/VertxHttpHeaderFilterStrategy.java | 4 --- .../VertxWebsocketHeaderFilterStrategy.java | 2 -- .../xmpp/XmppHeaderFilterStrategy.java | 3 -- .../impl/DefaultHeaderFilterStrategyTest.java | 28 +++++++++++++++++++ .../support/DefaultHeaderFilterStrategy.java | 14 +++++----- .../pages/camel-4x-upgrade-guide-4_21.adoc | 9 ++++++ 26 files changed, 55 insertions(+), 70 deletions(-) diff --git a/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java b/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java index fe85840d9ae9c..a3bea6c471caa 100644 --- a/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java +++ b/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java @@ -25,9 +25,6 @@ public Sns2HeaderFilterStrategy() { protected void initialize() { setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterPattern("(breadcrumbId|Camel|org\\.apache\\.camel)[\\.|a-z|A-z|0-9]*"); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); + getOutFilter().add("breadcrumbId"); } } diff --git a/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java b/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java index d6b460c53ecee..cc49308d90830 100644 --- a/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java +++ b/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java @@ -25,8 +25,6 @@ public Sqs2HeaderFilterStrategy() { protected void initialize() { setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterPattern("(breadcrumbId|Camel|org\\.apache\\.camel)[\\.|a-z|A-z|0-9]*"); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); + getOutFilter().add("breadcrumbId"); } } diff --git a/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java b/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java index 709c2ed532c45..22bd9abfb529a 100644 --- a/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java +++ b/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java @@ -40,8 +40,6 @@ public class ServiceBusHeaderFilterStrategy extends DefaultHeaderFilterStrategy public ServiceBusHeaderFilterStrategy() { super(); setLowerCase(true); - setOutFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); } @Override diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java index 827c14973796f..1c807073b636c 100644 --- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java +++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java @@ -28,7 +28,5 @@ public class CoAPHeaderFilterStrategy extends DefaultHeaderFilterStrategy { public CoAPHeaderFilterStrategy() { setLowerCase(true); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java index 3c6c6d89532bb..6294cd688b7e6 100644 --- a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java +++ b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java @@ -22,7 +22,5 @@ public class CometdHeaderFilterStrategy extends DefaultHeaderFilterStrategy { public CometdHeaderFilterStrategy() { setLowerCase(true); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java b/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java index 422e1d3144bcc..ca0f793209e39 100644 --- a/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java +++ b/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java @@ -33,9 +33,6 @@ protected void initialize() { // Support to filter the Content-Type case insensitive setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } diff --git a/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java b/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java index 921c45f94b5f0..7804af7a2ff27 100644 --- a/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java +++ b/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java @@ -95,9 +95,6 @@ protected void initialize() { messageHeaderFiltersMap = new HashMap<>(); addToMessageHeaderFilterMap(new SoapMessageHeaderFilter()); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } @SuppressWarnings("unchecked") diff --git a/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java b/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java index 8f75c1aa4fecb..bb8ee6bc72621 100644 --- a/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java +++ b/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java @@ -26,8 +26,6 @@ public GooglePubsubHeaderFilterStrategy() { public GooglePubsubHeaderFilterStrategy(boolean includeAllGoogleProperties) { setLowerCase(true); - setOutFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); // Filter authorization on both directions for security getOutFilter().add("authorization"); getInFilter().add("authorization"); diff --git a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java index 9249a9fd32590..70431c854b533 100644 --- a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java +++ b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java @@ -33,10 +33,6 @@ protected void initialize() { setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java index 2ca35f1d64db3..a40fae7b460e5 100644 --- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java +++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java @@ -36,10 +36,6 @@ protected void initialize() { setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java b/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java index 58bb0f746b7e8..742bf85250abb 100644 --- a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java +++ b/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java @@ -28,7 +28,5 @@ public class IggyHeaderFilterStrategy extends DefaultHeaderFilterStrategy { public IggyHeaderFilterStrategy() { setLowerCase(true); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java b/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java index 36d862a75a013..6aa04bdd53483 100644 --- a/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java +++ b/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java @@ -30,6 +30,8 @@ public ClassicJmsHeaderFilterStrategy() { public ClassicJmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { setLowerCase(true); + setInFilterStartsWith((String[]) null); // opt out: pass Camel headers inbound (legacy mode) + setOutFilterStartsWith((String[]) null); // opt out: pass Camel headers outbound (legacy mode) if (!includeAllJMSXProperties) { initialize(); } diff --git a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java index 6a290839767a0..aa3fcdb8c0ba2 100644 --- a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java +++ b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java @@ -26,8 +26,6 @@ public JmsHeaderFilterStrategy() { public JmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { setLowerCase(true); - setOutFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); if (!includeAllJMSXProperties) { initialize(); } diff --git a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java index d2b1fb49a8f9d..a2fb4f03899a5 100644 --- a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java +++ b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java @@ -16,6 +16,8 @@ */ package org.apache.camel.component.kafka; +import java.util.Arrays; + import org.apache.camel.support.DefaultHeaderFilterStrategy; public class KafkaHeaderFilterStrategy extends DefaultHeaderFilterStrategy { @@ -30,8 +32,10 @@ protected void initialize() { setLowerCase(true); - // filter headers beginning with "Camel" or "org.apache.camel" or "kafka." - setOutFilterStartsWith("Camel", "camel", "org.apache.camel.", "kafka."); - setInFilterStartsWith("Camel", "camel", "org.apache.camel.", "kafka."); + // filter headers beginning with Camel-internal prefixes and "kafka." + String[] kafkaFilterStartsWith = Arrays.copyOf(CAMEL_FILTER_STARTS_WITH, CAMEL_FILTER_STARTS_WITH.length + 1); + kafkaFilterStartsWith[CAMEL_FILTER_STARTS_WITH.length] = "kafka."; + setOutFilterStartsWith(kafkaFilterStartsWith); + setInFilterStartsWith(kafkaFilterStartsWith); } } diff --git a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java index 2e54bd56b435e..5d10d09d4aa43 100644 --- a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java +++ b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java @@ -28,10 +28,5 @@ protected final void initialize() { HttpUtil.addCommonFilters(getOutFilter()); setLowerCase(true); - - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterPattern("(?i)(Camel|org\\.apache\\.camel)[\\.|a-z|A-z|0-9]*"); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java index c92548a6ac5e4..a4813e9fe49e7 100644 --- a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java +++ b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java @@ -28,8 +28,6 @@ public MailHeaderFilterStrategy() { protected void initialize() { setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); // on the inbound path also filter the Camel-internal mail.smtp.* / mail.smtps.* namespace so an // external mail message cannot inject JavaMail session properties (CAMEL-23522) String[] inFilter = Arrays.copyOf(CAMEL_FILTER_STARTS_WITH, CAMEL_FILTER_STARTS_WITH.length + 2); diff --git a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java index 9997b3a666237..282f8aca1312e 100644 --- a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java +++ b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java @@ -26,9 +26,6 @@ public NatsHeaderFilterStrategy() { protected void initialize() { setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java index 12b81b0b19910..89ffee2a923bb 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java @@ -36,9 +36,5 @@ protected void initialize() { setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java index 56d89d009a813..d1764d757770c 100644 --- a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java +++ b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java @@ -26,8 +26,6 @@ public SjmsHeaderFilterStrategy() { public SjmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { setLowerCase(true); - setOutFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(DefaultHeaderFilterStrategy.CAMEL_FILTER_STARTS_WITH); if (!includeAllJMSXProperties) { initialize(); } diff --git a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java index 41bd5bcebc6ff..7959a1b55cabd 100644 --- a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java +++ b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java @@ -29,8 +29,6 @@ protected void initialize() { this.getOutFilter().add("content-length"); this.getOutFilter().add("content-type"); this.setLowerCase(true); - this.setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - this.setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java index 734eeea1ff036..f5f5a853a2520 100644 --- a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java +++ b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java @@ -33,10 +33,6 @@ protected void initialize() { setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - // must ignore case for Http based transports - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java index 232de276eb633..49b187ce01e57 100644 --- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java +++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java @@ -28,7 +28,5 @@ public class VertxWebsocketHeaderFilterStrategy extends DefaultHeaderFilterStrat public VertxWebsocketHeaderFilterStrategy() { setLowerCase(true); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java index cd2b78b25c42a..e2ea0ab059183 100644 --- a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java +++ b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java @@ -26,9 +26,6 @@ public XmppHeaderFilterStrategy() { protected void initialize() { setLowerCase(true); - // filter headers begin with "Camel" or "org.apache.camel" - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); - setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java index 73324480c25b0..7ddb554e3d107 100644 --- a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java @@ -212,6 +212,34 @@ public void testInStartsWith() { assertTrue(comp.applyFilterToExternalHeaders("camelJETTYSession", "true", exchange)); } + @Test + public void testInStartsWithDefaultFiltering() { + DefaultHeaderFilterStrategy comp = new DefaultHeaderFilterStrategy(); + + Exchange exchange = new DefaultExchange(context); + + assertFalse(comp.applyFilterToExternalHeaders("foo", "bar", exchange)); + assertFalse(comp.applyFilterToExternalHeaders("content-type", "text/plain", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("CamelVersion", "4.21", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("camelJettySession", "true", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("CAMELFooBar", "x", exchange)); // lowerCase=true catches mixed-case + assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel.foo", "x", exchange)); + } + + @Test + public void testOutStartsWithDefaultFiltering() { + DefaultHeaderFilterStrategy comp = new DefaultHeaderFilterStrategy(); + + Exchange exchange = new DefaultExchange(context); + + assertFalse(comp.applyFilterToCamelHeaders("foo", "bar", exchange)); + assertFalse(comp.applyFilterToCamelHeaders("content-type", "text/plain", exchange)); + assertTrue(comp.applyFilterToCamelHeaders("CamelVersion", "4.21", exchange)); + assertTrue(comp.applyFilterToCamelHeaders("camelJettySession", "true", exchange)); + assertTrue(comp.applyFilterToCamelHeaders("CAMELFooBar", "x", exchange)); // lowerCase=true catches mixed-case + assertTrue(comp.applyFilterToCamelHeaders("org.apache.camel.foo", "x", exchange)); + } + @Test public void testInStartsWithLowerCase() { DefaultHeaderFilterStrategy comp = new DefaultHeaderFilterStrategy(); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java index 88fabe5f1932a..8b7f05dd1c736 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java @@ -50,23 +50,23 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy { public static final Pattern CAMEL_FILTER_PATTERN = Pattern.compile("(?i)Camel[.a-zA-z0-9]*"); /** - * A filter pattern for keys starting with Camel, or camel. + * A filter pattern for keys starting with Camel, camel, or org.apache.camel.. */ - public static final String[] CAMEL_FILTER_STARTS_WITH = new String[] { "Camel", "camel" }; + public static final String[] CAMEL_FILTER_STARTS_WITH = new String[] { "Camel", "camel", "org.apache.camel." }; @Metadata(javaType = "java.lang.String", description = "Sets the in direction filter set. The in direction is referred to copying headers from an external message to a Camel message." + " Multiple patterns can be separated by comma") private Set inFilter; private Pattern inFilterPattern; - private String[] inFilterStartsWith; + private String[] inFilterStartsWith = CAMEL_FILTER_STARTS_WITH; @Metadata(javaType = "java.lang.String", description = "Sets the out direction filter set. The out direction is referred to copying headers from a Camel message to an external message." + " Multiple patterns can be separated by comma") private Set outFilter; private Pattern outFilterPattern; - private String[] outFilterStartsWith; + private String[] outFilterStartsWith = CAMEL_FILTER_STARTS_WITH; @Metadata(label = "advanced", defaultValue = "true", description = "Whether header names should be converted to lower case before checking it with the filter Set. This ensures that all variations of header names will be taken into account." @@ -377,7 +377,7 @@ private boolean doFiltering(Direction direction, String headerName, Object heade } private boolean tryPattern(String headerName, String lower, Pattern pattern) { - // optimize if its the default pattern as we know the pattern is to check for keys starting with Camel + // optimize if it's the default pattern as we know the pattern is to check for keys starting with Camel if (pattern == CAMEL_FILTER_PATTERN) { boolean match = headerName.startsWith("Camel") || headerName.startsWith("camel"); if (match) { @@ -392,8 +392,8 @@ private boolean tryPattern(String headerName, String lower, Pattern pattern) { return true; } } - } else if (pattern.matcher(headerName).matches()) { - return true; + } else { + return pattern.matcher(headerName).matches(); } return false; } diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc index fa6b65448c7bb..0e1a4ae58b04e 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc @@ -69,6 +69,15 @@ your own code or tooling, add `org.jspecify:jspecify` explicitly to your project The `org.apache.camel.support.DefaultHeaderFilterStrategy` changed default setting for lowercase from `false` to `true`. +The `DefaultHeaderFilterStrategy` now blocks headers whose names start with `Camel`, `camel`, or +`org.apache.camel.` (case-insensitive) by default in both the inbound (external to Camel) and outbound +(Camel to external) directions. The `CAMEL_FILTER_STARTS_WITH` constant has been updated to include +`org.apache.camel.`. Previously this required each component to explicitly call +`setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH)` and `setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH)`. +Users who configure `DefaultHeaderFilterStrategy` directly and need these headers to pass through +must now explicitly opt out by calling `setInFilterStartsWith((String[]) null)` and/or +`setOutFilterStartsWith((String[]) null)`, or by supplying a custom filter array. + ==== Error Registry SPI changes The `ErrorRegistry` SPI has been enhanced to capture rich exchange data snapshots at error time, From 95d51d8b698db1e6f64127e141ab0862ecbb1d58 Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Sat, 30 May 2026 17:29:27 -0400 Subject: [PATCH 2/8] CAMEL-23543: Fix review findings and remove redundant header filter strategy subclasses - DefaultHeaderFilterStrategy: use .clone() on field initializers so each instance gets its own array copy; mutating the public CAMEL_FILTER_STARTS_WITH constant no longer corrupts all instances - Change CAMEL_FILTER_STARTS_WITH from "org.apache.camel." to "org.apache.camel" (no trailing dot) so the bare prefix "org.apache.camel" is also blocked - Update deprecated CAMEL_FILTER_PATTERN regex and its fast-path in tryPattern to cover the org.apache.camel namespace consistently - Remove redundant setLowerCase(true) calls from HTTP strategies (lowerCase=true is already the field-initializer default) - Fix HttpBridgeMultipartRouteTest inner strategy: remove setLowerCase(true) and the now-redundant setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH) call - Add ClassicJmsHeaderFilterStrategyTest to directly assert Camel headers pass through in both directions in legacy mode (opt-out via null startsWith) - Expand upgrade guide to cover subclass authors, not just direct instantiators; add pointer to ClassicJmsHeaderFilterStrategy as a worked opt-out example - Remove six no-op header filter strategy subclasses whose only body was setLowerCase(true), which is now the default: CoAPHeaderFilterStrategy, CometdHeaderFilterStrategy, IggyHeaderFilterStrategy, NatsHeaderFilterStrategy, VertxWebsocketHeaderFilterStrategy, XmppHeaderFilterStrategy. Update all callers to instantiate DefaultHeaderFilterStrategy directly. Delete associated test files. Co-Authored-By: Claude Sonnet 4.6 rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED --- .../org/apache/camel/coap/CoAPEndpoint.java | 3 +- .../camel/coap/CoAPHeaderFilterStrategy.java | 32 ------- .../coap/CoAPHeaderFilterStrategyTest.java | 84 ------------------- .../camel/component/cometd/CometdBinding.java | 3 +- .../cometd/CometdHeaderFilterStrategy.java | 26 ------ .../http/base/HttpHeaderFilterStrategy.java | 3 - .../http/common/HttpHeaderFilterStrategy.java | 3 - .../camel/component/iggy/IggyEndpoint.java | 3 +- .../iggy/IggyHeaderFilterStrategy.java | 32 ------- .../iggy/IggyHeaderFilterStrategyTest.java | 53 ------------ .../jetty/HttpBridgeMultipartRouteTest.java | 2 - .../ClassicJmsHeaderFilterStrategyTest.java | 70 ++++++++++++++++ .../component/nats/NatsConfiguration.java | 3 +- .../nats/NatsHeaderFilterStrategy.java | 31 ------- .../nats/NatsHeaderFilterStrategyTest.java | 53 ------------ .../websocket/VertxWebsocketEndpoint.java | 3 +- .../VertxWebsocketHeaderFilterStrategy.java | 32 ------- ...ertxWebsocketHeaderFilterStrategyTest.java | 53 ------------ .../camel/component/xmpp/XmppBinding.java | 3 +- .../camel/component/xmpp/XmppEndpoint.java | 3 +- .../xmpp/XmppHeaderFilterStrategy.java | 31 ------- .../xmpp/XmppHeaderFilterStrategyTest.java | 53 ------------ .../impl/DefaultHeaderFilterStrategyTest.java | 6 +- .../support/DefaultHeaderFilterStrategy.java | 18 ++-- .../pages/camel-4x-upgrade-guide-4_21.adoc | 14 +++- 25 files changed, 108 insertions(+), 509 deletions(-) delete mode 100644 components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java delete mode 100644 components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderFilterStrategyTest.java delete mode 100644 components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java delete mode 100644 components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java delete mode 100644 components/camel-iggy/src/test/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategyTest.java create mode 100644 components/camel-jms/src/test/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategyTest.java delete mode 100644 components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java delete mode 100644 components/camel-nats/src/test/java/org/apache/camel/component/nats/NatsHeaderFilterStrategyTest.java delete mode 100644 components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java delete mode 100644 components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategyTest.java delete mode 100644 components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java delete mode 100644 components/camel-xmpp/src/test/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategyTest.java diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java index ae5d8697682b3..74909335fad77 100644 --- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java +++ b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPEndpoint.java @@ -45,6 +45,7 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.support.jsse.ClientAuthentication; import org.apache.camel.support.jsse.KeyManagersParameters; import org.apache.camel.support.jsse.SSLContextParameters; @@ -281,7 +282,7 @@ public void setClient(CoapClient client) { @Override public HeaderFilterStrategy getHeaderFilterStrategy() { if (headerFilterStrategy == null) { - headerFilterStrategy = new CoAPHeaderFilterStrategy(); + headerFilterStrategy = new DefaultHeaderFilterStrategy(); } return headerFilterStrategy; } diff --git a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java b/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java deleted file mode 100644 index 1c807073b636c..0000000000000 --- a/components/camel-coap/src/main/java/org/apache/camel/coap/CoAPHeaderFilterStrategy.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.coap; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -/** - * Default header filter strategy for CoAP endpoints. - *

- * Filters out Camel internal headers (starting with "Camel" or "camel") in both directions to prevent external CoAP - * clients from injecting internal Camel headers via query parameters. - */ -public class CoAPHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public CoAPHeaderFilterStrategy() { - setLowerCase(true); - } -} diff --git a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderFilterStrategyTest.java b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderFilterStrategyTest.java deleted file mode 100644 index c6460a2994e67..0000000000000 --- a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPHeaderFilterStrategyTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.coap; - -import org.apache.camel.Exchange; -import org.apache.camel.RoutesBuilder; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.component.mock.MockEndpoint; -import org.eclipse.californium.core.CoapClient; -import org.eclipse.californium.core.CoapResponse; -import org.eclipse.californium.core.coap.MediaTypeRegistry; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -/** - * Test that the default {@link CoAPHeaderFilterStrategy} prevents external CoAP clients from injecting internal Camel - * headers via query parameters. - */ -public class CoAPHeaderFilterStrategyTest extends CoAPTestSupport { - - @Test - void testCamelHeadersAreFilteredFromQueryParameters() throws Exception { - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedMessageCount(1); - - // Send a CoAP request with a Camel-prefixed query parameter that should be filtered - CoapClient client = createClient("/test?CamelHttpMethod=DELETE&safeParam=hello"); - CoapResponse response = client.post("body", MediaTypeRegistry.TEXT_PLAIN); - - mock.assertIsSatisfied(); - - Exchange exchange = mock.getReceivedExchanges().get(0); - // CamelHttpMethod should be filtered out by the header filter strategy - assertNull(exchange.getIn().getHeader("CamelHttpMethod"), - "Camel-prefixed header should be filtered from external CoAP query parameters"); - // Non-Camel headers should pass through - assertEquals("hello", exchange.getIn().getHeader("safeParam"), - "Non-Camel headers should be allowed through"); - } - - @Test - void testCamelLowercaseHeadersAreFiltered() throws Exception { - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedMessageCount(1); - - CoapClient client = createClient("/test?camelInternal=secret&allowed=value"); - CoapResponse response = client.post("body", MediaTypeRegistry.TEXT_PLAIN); - - mock.assertIsSatisfied(); - - Exchange exchange = mock.getReceivedExchanges().get(0); - assertNull(exchange.getIn().getHeader("camelInternal"), - "Lowercase camel-prefixed header should be filtered"); - assertEquals("value", exchange.getIn().getHeader("allowed"), - "Non-Camel headers should be allowed through"); - } - - @Override - protected RoutesBuilder createRouteBuilder() { - return new RouteBuilder() { - @Override - public void configure() { - fromF("coap://localhost:%d/test", PORT.getPort()) - .to("mock:result"); - } - }; - } -} diff --git a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java index 7e104a212d1c1..00399024a29b3 100644 --- a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java +++ b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java @@ -25,6 +25,7 @@ import org.apache.camel.Exchange; import org.apache.camel.Message; import org.apache.camel.spi.HeaderFilterStrategy; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.spi.Metadata; import org.apache.camel.support.DefaultMessage; import org.cometd.bayeux.server.ServerChannel; @@ -57,7 +58,7 @@ public CometdBinding(BayeuxServerImpl bayeux) { } public CometdBinding(BayeuxServerImpl bayeux, boolean enableSessionHeader) { - this(bayeux, enableSessionHeader, new CometdHeaderFilterStrategy()); + this(bayeux, enableSessionHeader, new DefaultHeaderFilterStrategy()); } public CometdBinding(BayeuxServerImpl bayeux, boolean enableSessionHeader, HeaderFilterStrategy headerFilterStrategy) { diff --git a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java deleted file mode 100644 index 6294cd688b7e6..0000000000000 --- a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdHeaderFilterStrategy.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.cometd; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -public class CometdHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public CometdHeaderFilterStrategy() { - setLowerCase(true); - } -} diff --git a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java index 70431c854b533..dde1d72570ed3 100644 --- a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java +++ b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpHeaderFilterStrategy.java @@ -30,9 +30,6 @@ public HttpHeaderFilterStrategy() { protected void initialize() { final Set outFilter = getOutFilter(); HttpUtil.addCommonFilters(outFilter); - - setLowerCase(true); - } } diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java index a40fae7b460e5..d5c852822421e 100644 --- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java +++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpHeaderFilterStrategy.java @@ -33,9 +33,6 @@ public HttpHeaderFilterStrategy() { protected void initialize() { final Set outFilter = getOutFilter(); HttpUtil.addCommonFilters(outFilter); - - setLowerCase(true); - } } diff --git a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyEndpoint.java b/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyEndpoint.java index a37d8c957423a..90f8e8885c262 100644 --- a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyEndpoint.java +++ b/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyEndpoint.java @@ -32,6 +32,7 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.iggy.client.blocking.IggyBaseClient; import org.apache.iggy.consumergroup.ConsumerGroupDetails; import org.apache.iggy.identifier.ConsumerId; @@ -170,7 +171,7 @@ public ExecutorService createExecutor() { @Override public HeaderFilterStrategy getHeaderFilterStrategy() { if (headerFilterStrategy == null) { - headerFilterStrategy = new IggyHeaderFilterStrategy(); + headerFilterStrategy = new DefaultHeaderFilterStrategy(); } return headerFilterStrategy; } diff --git a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java b/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java deleted file mode 100644 index 742bf85250abb..0000000000000 --- a/components/camel-iggy/src/main/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategy.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.iggy; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -/** - * Default header filter strategy for Iggy endpoints. - *

- * Filters out Camel internal headers (starting with "Camel" or "camel") in both directions to prevent external Iggy - * message producers from injecting internal Camel headers via message user-headers. - */ -public class IggyHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public IggyHeaderFilterStrategy() { - setLowerCase(true); - } -} diff --git a/components/camel-iggy/src/test/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategyTest.java b/components/camel-iggy/src/test/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategyTest.java deleted file mode 100644 index 59a3a2d7303ee..0000000000000 --- a/components/camel-iggy/src/test/java/org/apache/camel/component/iggy/IggyHeaderFilterStrategyTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.iggy; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class IggyHeaderFilterStrategyTest { - - private final IggyHeaderFilterStrategy strategy = new IggyHeaderFilterStrategy(); - - @Test - void inboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("CamelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelFileName", "../../etc/passwd", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelBeanMethodName", "evilMethod", null)); - } - - @Test - void inboundLowercaseCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("camelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("camelfilename", "../../etc/passwd", null)); - } - - @Test - void outboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("camelHttpUri", "value", null)); - } - - @Test - void nonCamelHeadersPassThrough() { - assertFalse(strategy.applyFilterToExternalHeaders("Content-Type", "application/json", null)); - assertFalse(strategy.applyFilterToExternalHeaders("X-Request-Id", "abc-123", null)); - assertFalse(strategy.applyFilterToCamelHeaders("Content-Type", "application/json", null)); - } -} diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBridgeMultipartRouteTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBridgeMultipartRouteTest.java index eb62bf3a8a79a..1d2491a26ef82 100644 --- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBridgeMultipartRouteTest.java +++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBridgeMultipartRouteTest.java @@ -44,9 +44,7 @@ private static class MultipartHeaderFilterStrategy extends DefaultHeaderFilterSt } protected void initialize() { - setLowerCase(true); getOutFilter().add("content-length"); - setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH); } } diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategyTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategyTest.java new file mode 100644 index 0000000000000..1aa6ff24f76b5 --- /dev/null +++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategyTest.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jms; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verifies that {@link ClassicJmsHeaderFilterStrategy} opts out of the default Camel header filtering so that + * Camel-internal headers propagate across the JMS wire (legacy behaviour). + */ +public class ClassicJmsHeaderFilterStrategyTest { + + private final ClassicJmsHeaderFilterStrategy strategy = new ClassicJmsHeaderFilterStrategy(); + + @Test + void camelHeadersPassThroughInboundDirection() { + // In classic mode, Camel headers must NOT be blocked when arriving from JMS + assertFalse(strategy.applyFilterToExternalHeaders("CamelJmsDestination", "queue://foo", null), + "CamelJmsDestination must pass through inbound in classic mode"); + assertFalse(strategy.applyFilterToExternalHeaders("CamelFileName", "report.txt", null), + "CamelFileName must pass through inbound in classic mode"); + assertFalse(strategy.applyFilterToExternalHeaders("camelCorrelationId", "abc", null), + "camelCorrelationId must pass through inbound in classic mode"); + assertFalse(strategy.applyFilterToExternalHeaders("org.apache.camel.foo", "bar", null), + "org.apache.camel.foo must pass through inbound in classic mode"); + } + + @Test + void camelHeadersPassThroughOutboundDirection() { + // In classic mode, Camel headers must NOT be blocked when sent to JMS + assertFalse(strategy.applyFilterToCamelHeaders("CamelJmsDestination", "queue://foo", null), + "CamelJmsDestination must pass through outbound in classic mode"); + assertFalse(strategy.applyFilterToCamelHeaders("CamelFileName", "report.txt", null), + "CamelFileName must pass through outbound in classic mode"); + assertFalse(strategy.applyFilterToCamelHeaders("camelCorrelationId", "abc", null), + "camelCorrelationId must pass through outbound in classic mode"); + assertFalse(strategy.applyFilterToCamelHeaders("org.apache.camel.foo", "bar", null), + "org.apache.camel.foo must pass through outbound in classic mode"); + } + + @Test + void jmsProviderHeadersStillFiltered() { + // JMSXDeliveryCount and peers are filtered in both directions (provider-set, not user headers) + assertTrue(strategy.applyFilterToCamelHeaders("JMSXDeliveryCount", "1", null), + "JMSXDeliveryCount must be blocked outbound"); + } + + @Test + void nonCamelHeadersPassThrough() { + assertFalse(strategy.applyFilterToExternalHeaders("myApp-correlationId", "123", null)); + assertFalse(strategy.applyFilterToCamelHeaders("myApp-correlationId", "123", null)); + } +} diff --git a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java index 4db1cdef3ba31..e6fc221a2ccbd 100644 --- a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java +++ b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java @@ -26,6 +26,7 @@ import io.nats.client.api.ConsumerConfiguration; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.spi.Metadata; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriParams; import org.apache.camel.spi.UriPath; @@ -115,7 +116,7 @@ public class NatsConfiguration implements Cloneable { @UriParam(label = "advanced") private boolean traceConnection; @UriParam(label = "advanced") - private HeaderFilterStrategy headerFilterStrategy = new NatsHeaderFilterStrategy(); + private HeaderFilterStrategy headerFilterStrategy = new DefaultHeaderFilterStrategy(); public NatsConfiguration copy() { try { diff --git a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java deleted file mode 100644 index 282f8aca1312e..0000000000000 --- a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsHeaderFilterStrategy.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.nats; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -public class NatsHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public NatsHeaderFilterStrategy() { - initialize(); - } - - protected void initialize() { - setLowerCase(true); - } - -} diff --git a/components/camel-nats/src/test/java/org/apache/camel/component/nats/NatsHeaderFilterStrategyTest.java b/components/camel-nats/src/test/java/org/apache/camel/component/nats/NatsHeaderFilterStrategyTest.java deleted file mode 100644 index 96083045a0db8..0000000000000 --- a/components/camel-nats/src/test/java/org/apache/camel/component/nats/NatsHeaderFilterStrategyTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.nats; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class NatsHeaderFilterStrategyTest { - - private final NatsHeaderFilterStrategy strategy = new NatsHeaderFilterStrategy(); - - @Test - void inboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("CamelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelFileName", "../../etc/passwd", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelBeanMethodName", "evilMethod", null)); - } - - @Test - void inboundLowercaseCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("camelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("camelfilename", "../../etc/passwd", null)); - } - - @Test - void outboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("camelHttpUri", "value", null)); - } - - @Test - void nonCamelHeadersPassThrough() { - assertFalse(strategy.applyFilterToExternalHeaders("Content-Type", "application/json", null)); - assertFalse(strategy.applyFilterToExternalHeaders("X-Request-Id", "abc-123", null)); - assertFalse(strategy.applyFilterToCamelHeaders("Content-Type", "application/json", null)); - } -} diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java index 46439641d075d..7d6e1a383fdeb 100644 --- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java +++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java @@ -41,6 +41,7 @@ import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.URISupport; @@ -132,7 +133,7 @@ public VertxWebsocketConfiguration getConfiguration() { @Override public HeaderFilterStrategy getHeaderFilterStrategy() { if (headerFilterStrategy == null) { - headerFilterStrategy = new VertxWebsocketHeaderFilterStrategy(); + headerFilterStrategy = new DefaultHeaderFilterStrategy(); } return headerFilterStrategy; } diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java deleted file mode 100644 index 49b187ce01e57..0000000000000 --- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategy.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.vertx.websocket; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -/** - * Default header filter strategy for Vert.x WebSocket endpoints. - *

- * Filters out Camel internal headers (starting with "Camel" or "camel") in both directions to prevent external - * WebSocket clients from injecting internal Camel headers via query or path parameters. - */ -public class VertxWebsocketHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public VertxWebsocketHeaderFilterStrategy() { - setLowerCase(true); - } -} diff --git a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategyTest.java b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategyTest.java deleted file mode 100644 index 3f2d7f1ffc26f..0000000000000 --- a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHeaderFilterStrategyTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.vertx.websocket; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class VertxWebsocketHeaderFilterStrategyTest { - - private final VertxWebsocketHeaderFilterStrategy strategy = new VertxWebsocketHeaderFilterStrategy(); - - @Test - void inboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("CamelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelFileName", "../../etc/passwd", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelBeanMethodName", "evilMethod", null)); - } - - @Test - void inboundLowercaseCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("camelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("camelfilename", "../../etc/passwd", null)); - } - - @Test - void outboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("camelHttpUri", "value", null)); - } - - @Test - void nonCamelHeadersPassThrough() { - assertFalse(strategy.applyFilterToExternalHeaders("Content-Type", "application/json", null)); - assertFalse(strategy.applyFilterToExternalHeaders("X-Request-Id", "abc-123", null)); - assertFalse(strategy.applyFilterToCamelHeaders("Content-Type", "application/json", null)); - } -} diff --git a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppBinding.java b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppBinding.java index bf954eed19acb..b4862547c03f3 100644 --- a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppBinding.java +++ b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppBinding.java @@ -22,6 +22,7 @@ import org.apache.camel.Exchange; import org.apache.camel.spi.HeaderFilterStrategy; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.util.ObjectHelper; import org.jivesoftware.smack.packet.DefaultExtensionElement; import org.jivesoftware.smack.packet.ExtensionElement; @@ -43,7 +44,7 @@ public class XmppBinding { private HeaderFilterStrategy headerFilterStrategy; public XmppBinding() { - this.headerFilterStrategy = new XmppHeaderFilterStrategy(); + this.headerFilterStrategy = new DefaultHeaderFilterStrategy(); } public XmppBinding(HeaderFilterStrategy headerFilterStrategy) { diff --git a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppEndpoint.java b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppEndpoint.java index 41e635418a6b8..ccd0d62ee9ac1 100644 --- a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppEndpoint.java +++ b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppEndpoint.java @@ -34,6 +34,7 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; import org.apache.camel.support.DefaultEndpoint; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.StringHelper; import org.jivesoftware.smack.ConnectionConfiguration; @@ -102,7 +103,7 @@ public class XmppEndpoint extends DefaultEndpoint implements HeaderFilterStrateg @UriParam(label = "consumer", defaultValue = "10") private int connectionPollDelay = 10; @UriParam(label = "filter") - private HeaderFilterStrategy headerFilterStrategy = new XmppHeaderFilterStrategy(); + private HeaderFilterStrategy headerFilterStrategy = new DefaultHeaderFilterStrategy(); @UriParam(label = "advanced") private ConnectionConfiguration connectionConfig; diff --git a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java b/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java deleted file mode 100644 index e2ea0ab059183..0000000000000 --- a/components/camel-xmpp/src/main/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategy.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.xmpp; - -import org.apache.camel.support.DefaultHeaderFilterStrategy; - -public class XmppHeaderFilterStrategy extends DefaultHeaderFilterStrategy { - - public XmppHeaderFilterStrategy() { - initialize(); - } - - protected void initialize() { - setLowerCase(true); - } - -} diff --git a/components/camel-xmpp/src/test/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategyTest.java b/components/camel-xmpp/src/test/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategyTest.java deleted file mode 100644 index 64718e909210c..0000000000000 --- a/components/camel-xmpp/src/test/java/org/apache/camel/component/xmpp/XmppHeaderFilterStrategyTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.camel.component.xmpp; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class XmppHeaderFilterStrategyTest { - - private final XmppHeaderFilterStrategy strategy = new XmppHeaderFilterStrategy(); - - @Test - void inboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("CamelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelFileName", "../../etc/passwd", null)); - assertTrue(strategy.applyFilterToExternalHeaders("CamelBeanMethodName", "evilMethod", null)); - } - - @Test - void inboundLowercaseCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToExternalHeaders("camelHttpUri", "http://evil.example", null)); - assertTrue(strategy.applyFilterToExternalHeaders("camelfilename", "../../etc/passwd", null)); - } - - @Test - void outboundCamelHeadersAreFiltered() { - assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("camelHttpUri", "value", null)); - } - - @Test - void nonCamelHeadersPassThrough() { - assertFalse(strategy.applyFilterToExternalHeaders("Content-Type", "application/json", null)); - assertFalse(strategy.applyFilterToExternalHeaders("X-Request-Id", "abc-123", null)); - assertFalse(strategy.applyFilterToCamelHeaders("Content-Type", "application/json", null)); - } -} diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java index 7ddb554e3d107..243d9dbf2c76d 100644 --- a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java @@ -222,8 +222,9 @@ public void testInStartsWithDefaultFiltering() { assertFalse(comp.applyFilterToExternalHeaders("content-type", "text/plain", exchange)); assertTrue(comp.applyFilterToExternalHeaders("CamelVersion", "4.21", exchange)); assertTrue(comp.applyFilterToExternalHeaders("camelJettySession", "true", exchange)); - assertTrue(comp.applyFilterToExternalHeaders("CAMELFooBar", "x", exchange)); // lowerCase=true catches mixed-case + assertTrue(comp.applyFilterToExternalHeaders("CAMELFooBar", "x", exchange)); assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel.foo", "x", exchange)); + assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel", "x", exchange)); // exact prefix, no dot } @Test @@ -236,8 +237,9 @@ public void testOutStartsWithDefaultFiltering() { assertFalse(comp.applyFilterToCamelHeaders("content-type", "text/plain", exchange)); assertTrue(comp.applyFilterToCamelHeaders("CamelVersion", "4.21", exchange)); assertTrue(comp.applyFilterToCamelHeaders("camelJettySession", "true", exchange)); - assertTrue(comp.applyFilterToCamelHeaders("CAMELFooBar", "x", exchange)); // lowerCase=true catches mixed-case + assertTrue(comp.applyFilterToCamelHeaders("CAMELFooBar", "x", exchange)); assertTrue(comp.applyFilterToCamelHeaders("org.apache.camel.foo", "x", exchange)); + assertTrue(comp.applyFilterToCamelHeaders("org.apache.camel", "x", exchange)); // exact prefix, no dot } @Test diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java index 8b7f05dd1c736..137af3186cf9f 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java @@ -42,31 +42,32 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy { /** - * A filter pattern that only accepts keys starting with Camel. + * A filter pattern that only accepts keys starting with Camel or org.apache.camel. * * @deprecated use {@link #CAMEL_FILTER_STARTS_WITH} */ @Deprecated(since = "3.9.0") - public static final Pattern CAMEL_FILTER_PATTERN = Pattern.compile("(?i)Camel[.a-zA-z0-9]*"); + public static final Pattern CAMEL_FILTER_PATTERN + = Pattern.compile("(?i)(Camel|org\\.apache\\.camel)[.a-zA-Z0-9]*"); /** - * A filter pattern for keys starting with Camel, camel, or org.apache.camel.. + * A filter pattern for keys starting with Camel, camel, or org.apache.camel. */ - public static final String[] CAMEL_FILTER_STARTS_WITH = new String[] { "Camel", "camel", "org.apache.camel." }; + public static final String[] CAMEL_FILTER_STARTS_WITH = new String[] { "Camel", "camel", "org.apache.camel" }; @Metadata(javaType = "java.lang.String", description = "Sets the in direction filter set. The in direction is referred to copying headers from an external message to a Camel message." + " Multiple patterns can be separated by comma") private Set inFilter; private Pattern inFilterPattern; - private String[] inFilterStartsWith = CAMEL_FILTER_STARTS_WITH; + private String[] inFilterStartsWith = CAMEL_FILTER_STARTS_WITH.clone(); @Metadata(javaType = "java.lang.String", description = "Sets the out direction filter set. The out direction is referred to copying headers from a Camel message to an external message." + " Multiple patterns can be separated by comma") private Set outFilter; private Pattern outFilterPattern; - private String[] outFilterStartsWith = CAMEL_FILTER_STARTS_WITH; + private String[] outFilterStartsWith = CAMEL_FILTER_STARTS_WITH.clone(); @Metadata(label = "advanced", defaultValue = "true", description = "Whether header names should be converted to lower case before checking it with the filter Set. This ensures that all variations of header names will be taken into account." @@ -379,7 +380,8 @@ private boolean doFiltering(Direction direction, String headerName, Object heade private boolean tryPattern(String headerName, String lower, Pattern pattern) { // optimize if it's the default pattern as we know the pattern is to check for keys starting with Camel if (pattern == CAMEL_FILTER_PATTERN) { - boolean match = headerName.startsWith("Camel") || headerName.startsWith("camel"); + boolean match = headerName.startsWith("Camel") || headerName.startsWith("camel") + || headerName.startsWith("org.apache.camel"); if (match) { return true; } @@ -387,7 +389,7 @@ private boolean tryPattern(String headerName, String lower, Pattern pattern) { if (lower == null) { lower = headerName.toLowerCase(); } - match = lower.startsWith("camel"); + match = lower.startsWith("camel") || lower.startsWith("org.apache.camel"); if (match) { return true; } diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc index 0e1a4ae58b04e..8065b6ad161ca 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc @@ -70,13 +70,19 @@ your own code or tooling, add `org.jspecify:jspecify` explicitly to your project The `org.apache.camel.support.DefaultHeaderFilterStrategy` changed default setting for lowercase from `false` to `true`. The `DefaultHeaderFilterStrategy` now blocks headers whose names start with `Camel`, `camel`, or -`org.apache.camel.` (case-insensitive) by default in both the inbound (external to Camel) and outbound +`org.apache.camel` (case-insensitive) by default in both the inbound (external to Camel) and outbound (Camel to external) directions. The `CAMEL_FILTER_STARTS_WITH` constant has been updated to include -`org.apache.camel.`. Previously this required each component to explicitly call +`org.apache.camel`. Previously this required each component to explicitly call `setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH)` and `setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH)`. -Users who configure `DefaultHeaderFilterStrategy` directly and need these headers to pass through -must now explicitly opt out by calling `setInFilterStartsWith((String[]) null)` and/or + +This affects anyone who: + +* Configures `DefaultHeaderFilterStrategy` directly, OR +* Extends `DefaultHeaderFilterStrategy` in a custom component without explicitly calling `setInFilterStartsWith` or `setOutFilterStartsWith`. + +If these headers need to pass through, opt out by calling `setInFilterStartsWith((String[]) null)` and/or `setOutFilterStartsWith((String[]) null)`, or by supplying a custom filter array. +See `ClassicJmsHeaderFilterStrategy` for a worked example of the opt-out pattern. ==== Error Registry SPI changes From 74a375dca4e0be252791c14acb8c2e671296d601 Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Sun, 31 May 2026 14:13:08 -0400 Subject: [PATCH 3/8] CAMEL-23543: Address review comments from davsclaus - Remove org.apache.camel from CAMEL_FILTER_STARTS_WITH: this prefix was a Camel 1.x artifact; Camel 2+ uses Camel* syntax only - Add upgrade guide note listing the 6 removed header filter strategy classes and directing users to use DefaultHeaderFilterStrategy instead Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Adriano Machado <60320+ammachado@users.noreply.github.com> Signed-off-by: Adriano Machado <60320+ammachado@users.noreply.github.com> rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED --- .../camel/component/cometd/CometdBinding.java | 2 +- .../cxf/jaxrs/CxfRsHeaderFilterStrategy.java | 6 ------ .../component/nats/NatsConfiguration.java | 2 +- .../impl/DefaultHeaderFilterStrategyTest.java | 8 ++++---- .../support/DefaultHeaderFilterStrategy.java | 4 ++-- .../pages/camel-4x-upgrade-guide-4_21.adoc | 19 +++++++++++++++---- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java index 00399024a29b3..814954d262539 100644 --- a/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java +++ b/components/camel-cometd/src/main/java/org/apache/camel/component/cometd/CometdBinding.java @@ -25,8 +25,8 @@ import org.apache.camel.Exchange; import org.apache.camel.Message; import org.apache.camel.spi.HeaderFilterStrategy; -import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.spi.Metadata; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.support.DefaultMessage; import org.cometd.bayeux.server.ServerChannel; import org.cometd.bayeux.server.ServerMessage; diff --git a/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java b/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java index ca0f793209e39..d4ace48e77909 100644 --- a/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java +++ b/components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/CxfRsHeaderFilterStrategy.java @@ -26,14 +26,8 @@ public CxfRsHeaderFilterStrategy() { } protected void initialize() { - getOutFilter().add(CxfConstants.OPERATION_NAME.toLowerCase()); getOutFilter().add("Content-Type".toLowerCase()); - // Support to filter the Content-Type case insensitive - setLowerCase(true); - - } - } diff --git a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java index e6fc221a2ccbd..00b489098c7bf 100644 --- a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java +++ b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsConfiguration.java @@ -26,10 +26,10 @@ import io.nats.client.api.ConsumerConfiguration; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.spi.Metadata; -import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriParams; import org.apache.camel.spi.UriPath; +import org.apache.camel.support.DefaultHeaderFilterStrategy; import org.apache.camel.support.jsse.SSLContextParameters; import org.apache.camel.util.ObjectHelper; diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java index 243d9dbf2c76d..b2d2eb129f54b 100644 --- a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultHeaderFilterStrategyTest.java @@ -223,8 +223,8 @@ public void testInStartsWithDefaultFiltering() { assertTrue(comp.applyFilterToExternalHeaders("CamelVersion", "4.21", exchange)); assertTrue(comp.applyFilterToExternalHeaders("camelJettySession", "true", exchange)); assertTrue(comp.applyFilterToExternalHeaders("CAMELFooBar", "x", exchange)); - assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel.foo", "x", exchange)); - assertTrue(comp.applyFilterToExternalHeaders("org.apache.camel", "x", exchange)); // exact prefix, no dot + assertFalse(comp.applyFilterToExternalHeaders("org.apache.camel.foo", "x", exchange)); + assertFalse(comp.applyFilterToExternalHeaders("org.apache.camel", "x", exchange)); } @Test @@ -238,8 +238,8 @@ public void testOutStartsWithDefaultFiltering() { assertTrue(comp.applyFilterToCamelHeaders("CamelVersion", "4.21", exchange)); assertTrue(comp.applyFilterToCamelHeaders("camelJettySession", "true", exchange)); assertTrue(comp.applyFilterToCamelHeaders("CAMELFooBar", "x", exchange)); - assertTrue(comp.applyFilterToCamelHeaders("org.apache.camel.foo", "x", exchange)); - assertTrue(comp.applyFilterToCamelHeaders("org.apache.camel", "x", exchange)); // exact prefix, no dot + assertFalse(comp.applyFilterToCamelHeaders("org.apache.camel.foo", "x", exchange)); + assertFalse(comp.applyFilterToCamelHeaders("org.apache.camel", "x", exchange)); } @Test diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java index 137af3186cf9f..52c5c153b31a5 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java @@ -51,9 +51,9 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy { = Pattern.compile("(?i)(Camel|org\\.apache\\.camel)[.a-zA-Z0-9]*"); /** - * A filter pattern for keys starting with Camel, camel, or org.apache.camel. + * A filter pattern for keys starting with Camel or camel. */ - public static final String[] CAMEL_FILTER_STARTS_WITH = new String[] { "Camel", "camel", "org.apache.camel" }; + public static final String[] CAMEL_FILTER_STARTS_WITH = new String[] { "Camel", "camel" }; @Metadata(javaType = "java.lang.String", description = "Sets the in direction filter set. The in direction is referred to copying headers from an external message to a Camel message." diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc index 8065b6ad161ca..d838f681de3b2 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc @@ -69,10 +69,9 @@ your own code or tooling, add `org.jspecify:jspecify` explicitly to your project The `org.apache.camel.support.DefaultHeaderFilterStrategy` changed default setting for lowercase from `false` to `true`. -The `DefaultHeaderFilterStrategy` now blocks headers whose names start with `Camel`, `camel`, or -`org.apache.camel` (case-insensitive) by default in both the inbound (external to Camel) and outbound -(Camel to external) directions. The `CAMEL_FILTER_STARTS_WITH` constant has been updated to include -`org.apache.camel`. Previously this required each component to explicitly call +The `DefaultHeaderFilterStrategy` now blocks headers whose names start with `Camel` or `camel` +(case-insensitive) by default in both the inbound (external to Camel) and outbound +(Camel to external) directions. Previously this required each component to explicitly call `setInFilterStartsWith(CAMEL_FILTER_STARTS_WITH)` and `setOutFilterStartsWith(CAMEL_FILTER_STARTS_WITH)`. This affects anyone who: @@ -84,6 +83,18 @@ If these headers need to pass through, opt out by calling `setInFilterStartsWith `setOutFilterStartsWith((String[]) null)`, or by supplying a custom filter array. See `ClassicJmsHeaderFilterStrategy` for a worked example of the opt-out pattern. +The following component-specific header filter strategy classes have been removed because +`DefaultHeaderFilterStrategy` now provides equivalent behavior by default: + +* `CoAPHeaderFilterStrategy` +* `CometdHeaderFilterStrategy` +* `IggyHeaderFilterStrategy` +* `NatsHeaderFilterStrategy` +* `VertxWebsocketHeaderFilterStrategy` +* `XmppHeaderFilterStrategy` + +If your code references any of these classes directly, replace them with `DefaultHeaderFilterStrategy`. + ==== Error Registry SPI changes The `ErrorRegistry` SPI has been enhanced to capture rich exchange data snapshots at error time, From 8cf2ce0ee3268d38f7a195dc04d86eacc25fd10c Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Sun, 31 May 2026 16:13:44 -0400 Subject: [PATCH 4/8] CAMEL-23543: Remove redundant setLowerCase(true) calls and document opt-out DefaultHeaderFilterStrategy already defaults lowerCase to true; remove the redundant setLowerCase(true) calls from all subclasses. Also add upgrade guide note on setLowerCase(false) for users who need case-sensitive header matching. Co-Authored-By: Claude Sonnet 4.6 rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED --- .../camel/component/aws2/sns/Sns2HeaderFilterStrategy.java | 2 +- .../camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java | 2 +- .../azure/servicebus/ServiceBusHeaderFilterStrategy.java | 5 ----- .../cxf/transport/header/CxfHeaderFilterStrategy.java | 3 --- .../google/pubsub/GooglePubsubHeaderFilterStrategy.java | 1 - .../camel/http/base/HttpProtocolHeaderFilterStrategy.java | 2 -- .../camel/component/jms/ClassicJmsHeaderFilterStrategy.java | 1 - .../apache/camel/component/jms/JmsHeaderFilterStrategy.java | 1 - .../camel/component/kafka/KafkaHeaderFilterStrategy.java | 2 -- .../knative/http/KnativeHttpHeaderFilterStrategy.java | 2 -- .../camel/component/mail/MailHeaderFilterStrategy.java | 1 - .../component/netty/http/NettyHttpHeaderFilterStrategy.java | 3 --- .../camel/component/sjms/SjmsHeaderFilterStrategy.java | 1 - .../springrabbit/SpringRabbitMQHeaderFilterStrategy.java | 1 - .../component/vertx/http/VertxHttpHeaderFilterStrategy.java | 3 --- .../modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc | 2 ++ 16 files changed, 4 insertions(+), 28 deletions(-) diff --git a/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java b/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java index a3bea6c471caa..4ca1c14db9a02 100644 --- a/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java +++ b/components/camel-aws/camel-aws2-sns/src/main/java/org/apache/camel/component/aws2/sns/Sns2HeaderFilterStrategy.java @@ -19,12 +19,12 @@ import org.apache.camel.support.DefaultHeaderFilterStrategy; public class Sns2HeaderFilterStrategy extends DefaultHeaderFilterStrategy { + public Sns2HeaderFilterStrategy() { initialize(); } protected void initialize() { - setLowerCase(true); getOutFilter().add("breadcrumbId"); } } diff --git a/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java b/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java index cc49308d90830..9d829293f64a6 100644 --- a/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java +++ b/components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategy.java @@ -19,12 +19,12 @@ import org.apache.camel.support.DefaultHeaderFilterStrategy; public class Sqs2HeaderFilterStrategy extends DefaultHeaderFilterStrategy { + public Sqs2HeaderFilterStrategy() { initialize(); } protected void initialize() { - setLowerCase(true); getOutFilter().add("breadcrumbId"); } } diff --git a/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java b/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java index 22bd9abfb529a..8c55063402879 100644 --- a/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java +++ b/components/camel-azure/camel-azure-servicebus/src/main/java/org/apache/camel/component/azure/servicebus/ServiceBusHeaderFilterStrategy.java @@ -37,11 +37,6 @@ public class ServiceBusHeaderFilterStrategy extends DefaultHeaderFilterStrategy Date.class, UUID.class); - public ServiceBusHeaderFilterStrategy() { - super(); - setLowerCase(true); - } - @Override public boolean applyFilterToCamelHeaders(String headerName, Object headerValue, Exchange exchange) { return headerValue == null || !SUPPORTED_TYPES.contains(headerValue.getClass()) diff --git a/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java b/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java index 7804af7a2ff27..c44f7bd182668 100644 --- a/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java +++ b/components/camel-cxf/camel-cxf-transport/src/main/java/org/apache/camel/component/cxf/transport/header/CxfHeaderFilterStrategy.java @@ -89,12 +89,9 @@ protected void initialize() { // is passed to the other endpoint getInFilter().add("content-length".toLowerCase()); - setLowerCase(true); - // initialize message header filter map with default SOAP filter messageHeaderFiltersMap = new HashMap<>(); addToMessageHeaderFilterMap(new SoapMessageHeaderFilter()); - } @SuppressWarnings("unchecked") diff --git a/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java b/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java index bb8ee6bc72621..b58bd91c0adbf 100644 --- a/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java +++ b/components/camel-google/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubHeaderFilterStrategy.java @@ -25,7 +25,6 @@ public GooglePubsubHeaderFilterStrategy() { } public GooglePubsubHeaderFilterStrategy(boolean includeAllGoogleProperties) { - setLowerCase(true); // Filter authorization on both directions for security getOutFilter().add("authorization"); getInFilter().add("authorization"); diff --git a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java index d3a0db4f500d8..7b113bd2d3636 100644 --- a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java +++ b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java @@ -68,7 +68,5 @@ protected void initialize() { getInFilter().add("www-authenticate"); HttpUtil.addCommonFilters(getInFilter()); - - setLowerCase(true); } } diff --git a/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java b/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java index 6aa04bdd53483..fb2594711a02f 100644 --- a/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java +++ b/components/camel-jms/src/main/java/org/apache/camel/component/jms/ClassicJmsHeaderFilterStrategy.java @@ -29,7 +29,6 @@ public ClassicJmsHeaderFilterStrategy() { } public ClassicJmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { - setLowerCase(true); setInFilterStartsWith((String[]) null); // opt out: pass Camel headers inbound (legacy mode) setOutFilterStartsWith((String[]) null); // opt out: pass Camel headers outbound (legacy mode) if (!includeAllJMSXProperties) { diff --git a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java index aa3fcdb8c0ba2..dd6ee5787eee0 100644 --- a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java +++ b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsHeaderFilterStrategy.java @@ -25,7 +25,6 @@ public JmsHeaderFilterStrategy() { } public JmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { - setLowerCase(true); if (!includeAllJMSXProperties) { initialize(); } diff --git a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java index a2fb4f03899a5..e0a4044eea4a2 100644 --- a/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java +++ b/components/camel-kafka/src/main/java/org/apache/camel/component/kafka/KafkaHeaderFilterStrategy.java @@ -30,8 +30,6 @@ protected void initialize() { // filter out kafka record metadata getInFilter().add("org.apache.kafka.clients.producer.RecordMetadata"); - setLowerCase(true); - // filter headers beginning with Camel-internal prefixes and "kafka." String[] kafkaFilterStartsWith = Arrays.copyOf(CAMEL_FILTER_STARTS_WITH, CAMEL_FILTER_STARTS_WITH.length + 1); kafkaFilterStartsWith[CAMEL_FILTER_STARTS_WITH.length] = "kafka."; diff --git a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java index 5d10d09d4aa43..e39c808b25793 100644 --- a/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java +++ b/components/camel-knative/camel-knative-http/src/main/java/org/apache/camel/component/knative/http/KnativeHttpHeaderFilterStrategy.java @@ -26,7 +26,5 @@ public KnativeHttpHeaderFilterStrategy() { protected final void initialize() { HttpUtil.addCommonFilters(getOutFilter()); - - setLowerCase(true); } } diff --git a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java index a4813e9fe49e7..d368cbdd6aa1e 100644 --- a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java +++ b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailHeaderFilterStrategy.java @@ -27,7 +27,6 @@ public MailHeaderFilterStrategy() { } protected void initialize() { - setLowerCase(true); // on the inbound path also filter the Camel-internal mail.smtp.* / mail.smtps.* namespace so an // external mail message cannot inject JavaMail session properties (CAMEL-23522) String[] inFilter = Arrays.copyOf(CAMEL_FILTER_STARTS_WITH, CAMEL_FILTER_STARTS_WITH.length + 2); diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java index 89ffee2a923bb..239d5e846869a 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHeaderFilterStrategy.java @@ -33,8 +33,5 @@ public NettyHttpHeaderFilterStrategy() { protected void initialize() { HttpUtil.addCommonFilters(getOutFilter()); - - setLowerCase(true); - } } diff --git a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java index d1764d757770c..4a9169ed3add7 100644 --- a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java +++ b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsHeaderFilterStrategy.java @@ -25,7 +25,6 @@ public SjmsHeaderFilterStrategy() { } public SjmsHeaderFilterStrategy(boolean includeAllJMSXProperties) { - setLowerCase(true); if (!includeAllJMSXProperties) { initialize(); } diff --git a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java index 7959a1b55cabd..baa359cb8f5b0 100644 --- a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java +++ b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQHeaderFilterStrategy.java @@ -28,7 +28,6 @@ protected void initialize() { this.getOutFilter().add("content-encoding"); this.getOutFilter().add("content-length"); this.getOutFilter().add("content-type"); - this.setLowerCase(true); } } diff --git a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java index f5f5a853a2520..7ea588ef42abf 100644 --- a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java +++ b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHeaderFilterStrategy.java @@ -30,9 +30,6 @@ public VertxHttpHeaderFilterStrategy() { protected void initialize() { final Set outFilter = getOutFilter(); HttpUtil.addCommonFilters(outFilter); - - setLowerCase(true); - } } diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc index d838f681de3b2..39172c367c24b 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc @@ -68,6 +68,8 @@ and enable compile-time null checking with tools like NullAway. If you want to l your own code or tooling, add `org.jspecify:jspecify` explicitly to your project dependencies. The `org.apache.camel.support.DefaultHeaderFilterStrategy` changed default setting for lowercase from `false` to `true`. +If your application relies on case-sensitive header name matching (for example, two headers that differ only in +case such as `X-Foo` and `x-foo`), restore the previous behavior by calling `setLowerCase(false)` on your strategy. The `DefaultHeaderFilterStrategy` now blocks headers whose names start with `Camel` or `camel` (case-insensitive) by default in both the inbound (external to Camel) and outbound From 4e0a04cf95802e3591d31222baca8222169a997c Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:47:22 -0400 Subject: [PATCH 5/8] CAMEL-23543: Fixing failing tests rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED --- .../camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java | 1 - .../camel/component/jetty/HttpFilterNoCamelHeadersTest.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java b/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java index 1c21bd4698068..6f2dd922daa7a 100644 --- a/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java +++ b/components/camel-aws/camel-aws2-sqs/src/test/java/org/apache/camel/component/aws2/sqs/Sqs2HeaderFilterStrategyTest.java @@ -43,7 +43,6 @@ void inboundAllowsNonCamelHeaders() { @Test void outboundFiltersCamelAndBreadcrumbHeaders() { assertTrue(strategy.applyFilterToCamelHeaders("CamelHttpUri", "value", null)); - assertTrue(strategy.applyFilterToCamelHeaders("org.apache.camel.internal", "value", null)); assertTrue(strategy.applyFilterToCamelHeaders("breadcrumbId", "value", null)); } diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpFilterNoCamelHeadersTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpFilterNoCamelHeadersTest.java index 0ebe599be2886..d8f8acc39efe2 100644 --- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpFilterNoCamelHeadersTest.java +++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpFilterNoCamelHeadersTest.java @@ -39,7 +39,7 @@ public void testFilterCamelHeaders() throws Exception { getMockEndpoint("mock:result").expectedMessageCount(1); getMockEndpoint("mock:result").message(0).header("bar").isEqualTo(123); - getMockEndpoint("mock:result").message(0).header(Exchange.FILE_NAME).isEqualTo("test.txt"); + getMockEndpoint("mock:result").message(0).header(Exchange.FILE_NAME).isNull(); getMockEndpoint("mock:result").message(0).header("CamelDummy").isNull(); Exchange out = template.request("direct:start", new Processor() { From 1be7a11fe60e507cbb20317aa9bb75b7d9cee81e Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Mon, 1 Jun 2026 11:29:42 -0400 Subject: [PATCH 6/8] CAMEL-23543: Fix HttpProtocolHeaderFilterStrategy to preserve Camel headers in copyHeaders HttpProtocolHeaderFilterStrategy inherited the new default inFilterStartsWith (["Camel", "camel"]) from DefaultHeaderFilterStrategy, causing MessageHelper.copyHeaders in HttpProducer to silently drop Camel-prefixed headers (e.g. CamelFileName) from the request exchange when building the response message. Reset inFilterStartsWith to null in initialize() since this strategy only filters HTTP protocol headers, not Camel internals. Also: switch HttpProducer to import from camel-http-base directly, deprecate the empty camel-http-common wrapper class, and document both in the 4.21 upgrade guide. Co-Authored-By: Claude Sonnet 4.6 rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED --- .../camel/http/base/HttpProtocolHeaderFilterStrategy.java | 3 +++ .../camel/http/common/HttpProtocolHeaderFilterStrategy.java | 4 ++++ .../java/org/apache/camel/component/http/HttpProducer.java | 2 +- .../camel/component/jetty/HttpFilterNoCamelHeadersTest.java | 2 +- .../modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc | 3 +++ 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java index 7b113bd2d3636..afb3c4f69b407 100644 --- a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java +++ b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java @@ -27,6 +27,9 @@ public HttpProtocolHeaderFilterStrategy() { // Just add the http headers here protected void initialize() { + // This strategy filters HTTP protocol headers only; Camel-prefixed headers must not be blocked + // so that they survive the request-to-response copy in HttpProducer.copyHeaders. + setInFilterStartsWith((String[]) null); getInFilter().add("content-encoding"); getInFilter().add("content-language"); diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java index 54f8f95c3e3ea..44c1e0c5575f7 100644 --- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java +++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java @@ -16,5 +16,9 @@ */ package org.apache.camel.http.common; +/** + * @deprecated use {@link org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy} directly + */ +@Deprecated(since = "4.21") public class HttpProtocolHeaderFilterStrategy extends org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy { } diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java index 8931a5607fa3b..2c0641844ab4f 100644 --- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java +++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java @@ -45,9 +45,9 @@ import org.apache.camel.WrappedFile; import org.apache.camel.component.http.helper.HttpMethodHelper; import org.apache.camel.http.base.HttpOperationFailedException; +import org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy; import org.apache.camel.http.base.cookie.CookieHandler; import org.apache.camel.http.common.HttpHelper; -import org.apache.camel.http.common.HttpProtocolHeaderFilterStrategy; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.support.DefaultProducer; import org.apache.camel.support.ExchangeHelper; diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpFilterNoCamelHeadersTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpFilterNoCamelHeadersTest.java index d8f8acc39efe2..0ebe599be2886 100644 --- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpFilterNoCamelHeadersTest.java +++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpFilterNoCamelHeadersTest.java @@ -39,7 +39,7 @@ public void testFilterCamelHeaders() throws Exception { getMockEndpoint("mock:result").expectedMessageCount(1); getMockEndpoint("mock:result").message(0).header("bar").isEqualTo(123); - getMockEndpoint("mock:result").message(0).header(Exchange.FILE_NAME).isNull(); + getMockEndpoint("mock:result").message(0).header(Exchange.FILE_NAME).isEqualTo("test.txt"); getMockEndpoint("mock:result").message(0).header("CamelDummy").isNull(); Exchange out = template.request("direct:start", new Processor() { diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc index 39172c367c24b..6beaa6a9f759f 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc @@ -97,6 +97,9 @@ The following component-specific header filter strategy classes have been remove If your code references any of these classes directly, replace them with `DefaultHeaderFilterStrategy`. +The class `org.apache.camel.http.common.HttpProtocolHeaderFilterStrategy` has been deprecated. +Use `org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy` directly instead. + ==== Error Registry SPI changes The `ErrorRegistry` SPI has been enhanced to capture rich exchange data snapshots at error time, From eb117e1b787bda1c607cc94b72ab6cc346841e5a Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:27:29 -0400 Subject: [PATCH 7/8] CAMEL-23543: Address review comments from davsclaus (round 2) - Revert CAMEL_FILTER_PATTERN and tryPattern to their original state; the org.apache.camel prefix is a Camel 1.x artifact and adding it to the deprecated constant created inconsistency with CAMEL_FILTER_STARTS_WITH. - Add setOutFilterStartsWith(null) to HttpProtocolHeaderFilterStrategy for symmetry with the inbound opt-out already present. - Clarify upgrade guide: deleted strategy classes should be replaced with `new DefaultHeaderFilterStrategy()` (not just the class name). Co-Authored-By: Claude Sonnet 4.6 --- .../base/HttpProtocolHeaderFilterStrategy.java | 1 + .../support/DefaultHeaderFilterStrategy.java | 16 +++++++--------- .../ROOT/pages/camel-4x-upgrade-guide-4_21.adoc | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java index afb3c4f69b407..00918c71a79e7 100644 --- a/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java +++ b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java @@ -30,6 +30,7 @@ protected void initialize() { // This strategy filters HTTP protocol headers only; Camel-prefixed headers must not be blocked // so that they survive the request-to-response copy in HttpProducer.copyHeaders. setInFilterStartsWith((String[]) null); + setOutFilterStartsWith((String[]) null); getInFilter().add("content-encoding"); getInFilter().add("content-language"); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java index 52c5c153b31a5..1f8a48e907bdd 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java @@ -42,13 +42,12 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy { /** - * A filter pattern that only accepts keys starting with Camel or org.apache.camel. + * A filter pattern that only accepts keys starting with Camel. * * @deprecated use {@link #CAMEL_FILTER_STARTS_WITH} */ @Deprecated(since = "3.9.0") - public static final Pattern CAMEL_FILTER_PATTERN - = Pattern.compile("(?i)(Camel|org\\.apache\\.camel)[.a-zA-Z0-9]*"); + public static final Pattern CAMEL_FILTER_PATTERN = Pattern.compile("(?i)Camel[.a-zA-z0-9]*"); /** * A filter pattern for keys starting with Camel or camel. @@ -378,10 +377,9 @@ private boolean doFiltering(Direction direction, String headerName, Object heade } private boolean tryPattern(String headerName, String lower, Pattern pattern) { - // optimize if it's the default pattern as we know the pattern is to check for keys starting with Camel + // optimize if its the default pattern as we know the pattern is to check for keys starting with Camel if (pattern == CAMEL_FILTER_PATTERN) { - boolean match = headerName.startsWith("Camel") || headerName.startsWith("camel") - || headerName.startsWith("org.apache.camel"); + boolean match = headerName.startsWith("Camel") || headerName.startsWith("camel"); if (match) { return true; } @@ -389,13 +387,13 @@ private boolean tryPattern(String headerName, String lower, Pattern pattern) { if (lower == null) { lower = headerName.toLowerCase(); } - match = lower.startsWith("camel") || lower.startsWith("org.apache.camel"); + match = lower.startsWith("camel"); if (match) { return true; } } - } else { - return pattern.matcher(headerName).matches(); + } else if (pattern.matcher(headerName).matches()) { + return true; } return false; } diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc index 6beaa6a9f759f..0de72ce8ecfbf 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc @@ -95,7 +95,7 @@ The following component-specific header filter strategy classes have been remove * `VertxWebsocketHeaderFilterStrategy` * `XmppHeaderFilterStrategy` -If your code references any of these classes directly, replace them with `DefaultHeaderFilterStrategy`. +If your code references any of these classes directly, replace them with `new DefaultHeaderFilterStrategy()`, which now provides the same behavior by default. The class `org.apache.camel.http.common.HttpProtocolHeaderFilterStrategy` has been deprecated. Use `org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy` directly instead. From 3a59d6b23d32dda38de5adb1d6951b3adad288e8 Mon Sep 17 00:00:00 2001 From: Adriano Machado <60320+ammachado@users.noreply.github.com> Date: Wed, 10 Jun 2026 09:52:51 -0400 Subject: [PATCH 8/8] CAMEL-23543: Fix propagateCamelToCxf to bypass filter for mapped Camel headers Mapped headers like CamelHttpResponseCode were being silently dropped by DefaultHeaderFilterStrategy's "Camel" prefix filter before reaching the CXF placement logic. The same bypass guard already existed in propagateCamelHeadersToCxfHeaders but was missing in propagateCamelToCxf. Co-Authored-By: Claude Sonnet 4.6 --- .../camel/component/cxf/common/header/CxfHeaderHelper.java | 3 ++- .../org/apache/camel/support/DefaultHeaderFilterStrategy.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/camel-cxf/camel-cxf-common/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java b/components/camel-cxf/camel-cxf-common/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java index 181a81bb90945..5daf623add20a 100644 --- a/components/camel-cxf/camel-cxf-common/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java +++ b/components/camel-cxf/camel-cxf-common/src/main/java/org/apache/camel/component/cxf/common/header/CxfHeaderHelper.java @@ -130,7 +130,8 @@ public static void propagateCamelToCxf( camelHeaders.entrySet().forEach(entry -> { // Need to make sure the cxf needed header will not be filtered - if (strategy.applyFilterToCamelHeaders(entry.getKey(), entry.getValue(), exchange)) { + if (strategy.applyFilterToCamelHeaders(entry.getKey(), entry.getValue(), exchange) + && CAMEL_TO_CXF_HEADERS.get(entry.getKey()) == null) { LOG.trace("Drop external header: {}={}", entry.getKey(), entry.getValue()); return; } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java index 1f8a48e907bdd..aa91104f2262f 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java @@ -377,7 +377,7 @@ private boolean doFiltering(Direction direction, String headerName, Object heade } private boolean tryPattern(String headerName, String lower, Pattern pattern) { - // optimize if its the default pattern as we know the pattern is to check for keys starting with Camel + // optimize if it's the default pattern as we know the pattern is to check for keys starting with Camel if (pattern == CAMEL_FILTER_PATTERN) { boolean match = headerName.startsWith("Camel") || headerName.startsWith("camel"); if (match) {