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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 01d97c3dd31f CAMEL-24910: camel-platform-http-vertx - a path parameter 
wins over an incoming header of the same name (#26751)
01d97c3dd31f is described below

commit 01d97c3dd31fa321e55c1b3974f49cf74fc649c3
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Sep 23 10:28:33 2026 +0200

    CAMEL-24910: camel-platform-http-vertx - a path parameter wins over an 
incoming header of the same name (#26751)
    
    A path parameter is what the request says it is: it now replaces an 
incoming header of the same name instead of appending to it, so /stock/{sku} is 
not read as a list when the caller also sent a sku header.
---
 .../http/vertx/VertxPlatformHttpSupport.java       |  6 ++-
 .../http/vertx/VertxPlatformHttpEngineTest.java    | 46 ++++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_23.adoc    |  7 ++++
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git 
a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java
 
b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java
index 43fd2903069b..80226cc58244 100644
--- 
a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java
+++ 
b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java
@@ -274,9 +274,11 @@ public final class VertxPlatformHttpSupport {
             applyHeaderFilterStrategy(ctx, headersMap, exchange, 
headerFilterStrategy, request);
         }
 
-        // Path parameters
+        // Path parameters: the value from the path wins over an incoming 
header of that name. A path parameter is
+        // single-valued and part of the route's contract, so appending would 
turn ${header.sku} into a list and a
+        // correct value would fail (CAMEL-24910); a query parameter may 
repeat and is still appended.
         for (Map.Entry<String, String> en : ctx.pathParams().entrySet()) {
-            appendEntry(headersMap, en.getKey(), en.getValue());
+            headersMap.put(en.getKey(), en.getValue());
         }
 
         SocketAddress localAddress = request.localAddress();
diff --git 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
index d81479098864..cb54cbc6bd5e 100644
--- 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
+++ 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java
@@ -503,6 +503,52 @@ public class VertxPlatformHttpEngineTest {
         }
     }
 
+    /**
+     * CAMEL-24910: a path parameter is single-valued and part of the route's 
contract, so it wins over an incoming
+     * header of the same name; before, the two were merged into a list and 
${header.name} answered "[X, Camel]".
+     */
+    @Test
+    public void testPathParameterWinsOverAHeaderOfTheSameName() throws 
Exception {
+        final CamelContext context = createCamelContextForTest();
+        try {
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() {
+                    from("platform-http:/greeting/{name}")
+                            .transform().simple("Hello ${header.name}");
+                }
+            });
+
+            context.start();
+
+            given()
+                    .when()
+                    .get("/greeting/Camel")
+                    .then()
+                    .statusCode(200)
+                    .body(equalTo("Hello Camel"));
+
+            // the same request with a header of that name: the path still 
decides
+            given()
+                    .header("name", "Rider")
+                    .when()
+                    .get("/greeting/Camel")
+                    .then()
+                    .statusCode(200)
+                    .body(equalTo("Hello Camel"));
+
+            // and a query parameter may still repeat, which is a list
+            given()
+                    .when()
+                    .get("/greeting/Camel?other=a&other=b")
+                    .then()
+                    .statusCode(200)
+                    .body(equalTo("Hello Camel"));
+        } finally {
+            context.stop();
+        }
+    }
+
     @Test
     public void testMatchOnUriPrefix() throws Exception {
         final CamelContext context = createCamelContextForTest();
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
index be1c20b5d9c4..586085c0b156 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
@@ -2330,6 +2330,13 @@ A name without a scheme, `resource:orderTemplate.json`, 
is a classpath resource.
 value and is not evaluated again. Nothing changes without the option: the 
`resource:` prefix on the expression
 text itself is resolved as before, and a returned value that happens to start 
with `resource:` stays as it is.
 
+=== camel-platform-http-vertx - a path parameter wins over an incoming header 
of the same name
+
+A REST endpoint with a path parameter, `/stock/{sku}`, sets the header `sku` 
from the path. When the request also
+carried an HTTP header of that name, the two were merged and `${header.sku}` 
was a `List` such as `[X, CAMEL-MUG]`,
+so a route that read it failed even when the path value was correct. The value 
from the path is used now; a query
+parameter may still repeat and is still collected into a list.
+
 === camel-core - the required attribute on rest param and route template 
parameter is now a String
 
 `ParamDefinition.required` (the rest DSL `param`) and 
`RouteTemplateParameterDefinition.required`

Reply via email to