From ae7bcf2fff1072a6d541104a484976ad49a204c5 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/6] 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 | 22 ++++++--------- .../pages/camel-4x-upgrade-guide-4_21.adoc | 9 ++++++ 26 files changed, 57 insertions(+), 76 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..d3a4a42ad2c11 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; } @@ -419,13 +419,9 @@ private boolean evalFilterMatch(String headerName, String lower, Set fil if (lower == null) { lower = headerName.toLowerCase(); } - if (filter.contains(lower)) { - return true; - } + return filter.contains(lower); } else { - if (filter.contains(headerName)) { - return true; - } + return filter.contains(headerName); } 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 a75f995c5473a..2994cc05a340c 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 @@ -28,6 +28,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 042de019442114b6d5c30f1c1449b28c903d9ffb 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/6] 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 d3a4a42ad2c11..1f63defcf18b3 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 2994cc05a340c..1a9863d0be908 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 @@ -29,13 +29,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 9c9290f4bcdc6d496f6b594cabbaf784d06cacc4 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/6] 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 1f63defcf18b3..ec20fb6712fce 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 1a9863d0be908..d3cd358544a9a 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 @@ -28,10 +28,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: @@ -43,6 +42,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 a77f719f075f377cc485f8c51cb3b5faa17703a7 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/6] 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 d3cd358544a9a..fdf84bf9c53c0 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 @@ -27,6 +27,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 56ba7cd4f26fcb5749a76a3745483fd2cce7c204 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/6] 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 913c2f2c9f52a485f16e537a4a0b9b8e54370424 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/6] 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 fdf84bf9c53c0..a53b742c3eb76 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 @@ -56,6 +56,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,