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

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

commit b89518d1d8fd421a688e84a37bd40707e58c5997
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Dec 21 10:46:57 2025 +0100

    CAMEL-22798: camel-platform-http-vertx - VertX has hardcoded content-type 
validation
---
 .../camel/catalog/components/platform-http.json    |   7 +-
 .../http/vertx/VertxPlatformHttpConsumer.java      |  20 ++--
 .../VertxPlatformServerRequestValidationTest.java  | 121 +++++++++++++++++++++
 .../http/PlatformHttpComponentConfigurer.java      |   6 +
 .../component/platform/http/platform-http.json     |   7 +-
 .../platform/http/PlatformHttpComponent.java       |  15 +++
 .../dsl/PlatformHttpComponentBuilderFactory.java   |  25 +++++
 7 files changed, 186 insertions(+), 15 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/platform-http.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/platform-http.json
index 970d47bf17ab..9de65466be58 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/platform-http.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/platform-http.json
@@ -28,9 +28,10 @@
     "bridgeErrorHandler": { "index": 0, "kind": "property", "displayName": 
"Bridge Error Handler", "group": "consumer", "label": "consumer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Allows for bridging the consumer to the Camel routing Error Handler, which 
mean any exceptions (if possible) occurred while the Camel consumer is trying 
to pickup incoming messages, or the like [...]
     "handleWriteResponseError": { "index": 1, "kind": "property", 
"displayName": "Handle Write Response Error", "group": "consumer", "label": 
"advanced,consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "When Camel is complete processing the 
message, and the HTTP server is writing response. This option controls whether 
Camel should catch any failure during writing response [...]
     "requestTimeout": { "index": 2, "kind": "property", "displayName": 
"Request Timeout", "group": "consumer", "label": "advanced,consumer", 
"required": false, "type": "integer", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "description": "The period in milliseconds 
after which the request should be timed out." },
-    "autowiredEnabled": { "index": 3, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
-    "engine": { "index": 4, "kind": "property", "displayName": "Engine", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.platform.http.spi.PlatformHttpEngine", 
"deprecated": false, "autowired": false, "secret": false, "description": "An 
HTTP Server engine implementation to serve the requests" },
-    "headerFilterStrategy": { "index": 5, "kind": "property", "displayName": 
"Header Filter Strategy", "group": "filter", "label": "filter", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a custom 
org.apache.camel.spi.HeaderFilterStrategy to filter header to and from Camel 
message." }
+    "serverRequestValidation": { "index": 3, "kind": "property", 
"displayName": "Server Request Validation", "group": "consumer", "label": 
"advanced,consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether HTTP server should do preliminary 
validation of incoming requests, validating if Content-Type\/Accept header, 
matches what is allowed according to consumes\/produces c [...]
+    "autowiredEnabled": { "index": 4, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "engine": { "index": 5, "kind": "property", "displayName": "Engine", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.platform.http.spi.PlatformHttpEngine", 
"deprecated": false, "autowired": false, "secret": false, "description": "An 
HTTP Server engine implementation to serve the requests" },
+    "headerFilterStrategy": { "index": 6, "kind": "property", "displayName": 
"Header Filter Strategy", "group": "filter", "label": "filter", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a custom 
org.apache.camel.spi.HeaderFilterStrategy to filter header to and from Camel 
message." }
   },
   "properties": {
     "path": { "index": 0, "kind": "path", "displayName": "Path", "group": 
"consumer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The path under which this endpoint 
serves the HTTP requests, for proxy use 'proxy'" },
diff --git 
a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
 
b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
index 324650f84605..fd088b7f2a03 100644
--- 
a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
+++ 
b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpConsumer.java
@@ -149,16 +149,18 @@ public class VertxPlatformHttpConsumer extends 
DefaultConsumer
             methods.forEach(m -> 
newRoute.method(HttpMethod.valueOf(m.name())));
         }
 
-        if (getEndpoint().getConsumes() != null) {
-            //comma separated contentTypes has to be registered one by one
-            for (String c : getEndpoint().getConsumes().split(",")) {
-                newRoute.consumes(c);
+        if (getEndpoint().getComponent().isServerRequestValidation()) {
+            if (getEndpoint().getConsumes() != null) {
+                //comma separated contentTypes has to be registered one by one
+                for (String c : getEndpoint().getConsumes().split(",")) {
+                    newRoute.consumes(c);
+                }
             }
-        }
-        if (getEndpoint().getProduces() != null) {
-            //comma separated contentTypes has to be registered one by one
-            for (String p : getEndpoint().getProduces().split(",")) {
-                newRoute.produces(p);
+            if (getEndpoint().getProduces() != null) {
+                //comma separated contentTypes has to be registered one by one
+                for (String p : getEndpoint().getProduces().split(",")) {
+                    newRoute.produces(p);
+                }
             }
         }
 
diff --git 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformServerRequestValidationTest.java
 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformServerRequestValidationTest.java
new file mode 100644
index 000000000000..deca3af3c4ef
--- /dev/null
+++ 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformServerRequestValidationTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.platform.http.vertx;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.platform.http.PlatformHttpComponent;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.is;
+
+public class VertxPlatformServerRequestValidationTest {
+
+    @Test
+    void testServerRequestFalse() throws Exception {
+        final CamelContext context = 
VertxPlatformHttpEngineTest.createCamelContext();
+
+        try {
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() {
+                    PlatformHttpComponent phc = 
context.getComponent("platform-http", PlatformHttpComponent.class);
+                    phc.setServerRequestValidation(false);
+
+                    restConfiguration().component("platform-http")
+                            .contextPath("/rest");
+
+                    rest().post("/test")
+                            .consumes("application/json")
+                            .produces("application/json")
+                            .to("direct:rest");
+
+                    from("direct:rest")
+                            .setBody(simple("Hello"));
+                }
+            });
+
+            context.start();
+
+            given()
+                    .body("<hello>World</hello>")
+                    .contentType("application/xml")
+                    .post("/rest/test")
+                    .then()
+                    .statusCode(200)
+                    .body(is("Hello"));
+
+            given()
+                    .body("{ \"name\": \"jack\" }")
+                    .contentType("application/json")
+                    .accept("application/xml")
+                    .post("/rest/test")
+                    .then()
+                    .statusCode(200)
+                    .body(is("Hello"));
+        } finally {
+            context.stop();
+        }
+    }
+
+    @Test
+    void testServerRequestTrue() throws Exception {
+        final CamelContext context = 
VertxPlatformHttpEngineTest.createCamelContext();
+
+        try {
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() {
+                    PlatformHttpComponent phc = 
context.getComponent("platform-http", PlatformHttpComponent.class);
+                    phc.setServerRequestValidation(true);
+
+                    restConfiguration().component("platform-http")
+                            .contextPath("/rest");
+
+                    rest().post("/test")
+                            .consumes("application/json")
+                            .produces("application/json")
+                            .to("direct:rest");
+
+                    from("direct:rest")
+                            .setBody(simple("Hello"));
+                }
+            });
+
+            context.start();
+
+            given()
+                    .body("<hello>World</hello>")
+                    .contentType("application/xml")
+                    .post("/rest/test")
+                    .then()
+                    .statusCode(415);
+
+            given()
+                    .body("{ \"name\": \"jack\" }")
+                    .contentType("application/json")
+                    .accept("application/xml")
+                    .post("/rest/test")
+                    .then()
+                    .statusCode(406);
+        } finally {
+            context.stop();
+        }
+    }
+
+}
diff --git 
a/components/camel-platform-http/src/generated/java/org/apache/camel/component/platform/http/PlatformHttpComponentConfigurer.java
 
b/components/camel-platform-http/src/generated/java/org/apache/camel/component/platform/http/PlatformHttpComponentConfigurer.java
index 72a4a7d45dc0..c0beb64b8244 100644
--- 
a/components/camel-platform-http/src/generated/java/org/apache/camel/component/platform/http/PlatformHttpComponentConfigurer.java
+++ 
b/components/camel-platform-http/src/generated/java/org/apache/camel/component/platform/http/PlatformHttpComponentConfigurer.java
@@ -34,6 +34,8 @@ public class PlatformHttpComponentConfigurer extends 
PropertyConfigurerSupport i
         case "headerFilterStrategy": 
target.setHeaderFilterStrategy(property(camelContext, 
org.apache.camel.spi.HeaderFilterStrategy.class, value)); return true;
         case "requesttimeout":
         case "requestTimeout": target.setRequestTimeout(property(camelContext, 
long.class, value)); return true;
+        case "serverrequestvalidation":
+        case "serverRequestValidation": 
target.setServerRequestValidation(property(camelContext, boolean.class, 
value)); return true;
         default: return false;
         }
     }
@@ -52,6 +54,8 @@ public class PlatformHttpComponentConfigurer extends 
PropertyConfigurerSupport i
         case "headerFilterStrategy": return 
org.apache.camel.spi.HeaderFilterStrategy.class;
         case "requesttimeout":
         case "requestTimeout": return long.class;
+        case "serverrequestvalidation":
+        case "serverRequestValidation": return boolean.class;
         default: return null;
         }
     }
@@ -71,6 +75,8 @@ public class PlatformHttpComponentConfigurer extends 
PropertyConfigurerSupport i
         case "headerFilterStrategy": return target.getHeaderFilterStrategy();
         case "requesttimeout":
         case "requestTimeout": return target.getRequestTimeout();
+        case "serverrequestvalidation":
+        case "serverRequestValidation": return 
target.isServerRequestValidation();
         default: return null;
         }
     }
diff --git 
a/components/camel-platform-http/src/generated/resources/META-INF/org/apache/camel/component/platform/http/platform-http.json
 
b/components/camel-platform-http/src/generated/resources/META-INF/org/apache/camel/component/platform/http/platform-http.json
index 970d47bf17ab..9de65466be58 100644
--- 
a/components/camel-platform-http/src/generated/resources/META-INF/org/apache/camel/component/platform/http/platform-http.json
+++ 
b/components/camel-platform-http/src/generated/resources/META-INF/org/apache/camel/component/platform/http/platform-http.json
@@ -28,9 +28,10 @@
     "bridgeErrorHandler": { "index": 0, "kind": "property", "displayName": 
"Bridge Error Handler", "group": "consumer", "label": "consumer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Allows for bridging the consumer to the Camel routing Error Handler, which 
mean any exceptions (if possible) occurred while the Camel consumer is trying 
to pickup incoming messages, or the like [...]
     "handleWriteResponseError": { "index": 1, "kind": "property", 
"displayName": "Handle Write Response Error", "group": "consumer", "label": 
"advanced,consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "When Camel is complete processing the 
message, and the HTTP server is writing response. This option controls whether 
Camel should catch any failure during writing response [...]
     "requestTimeout": { "index": 2, "kind": "property", "displayName": 
"Request Timeout", "group": "consumer", "label": "advanced,consumer", 
"required": false, "type": "integer", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "description": "The period in milliseconds 
after which the request should be timed out." },
-    "autowiredEnabled": { "index": 3, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
-    "engine": { "index": 4, "kind": "property", "displayName": "Engine", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.platform.http.spi.PlatformHttpEngine", 
"deprecated": false, "autowired": false, "secret": false, "description": "An 
HTTP Server engine implementation to serve the requests" },
-    "headerFilterStrategy": { "index": 5, "kind": "property", "displayName": 
"Header Filter Strategy", "group": "filter", "label": "filter", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a custom 
org.apache.camel.spi.HeaderFilterStrategy to filter header to and from Camel 
message." }
+    "serverRequestValidation": { "index": 3, "kind": "property", 
"displayName": "Server Request Validation", "group": "consumer", "label": 
"advanced,consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether HTTP server should do preliminary 
validation of incoming requests, validating if Content-Type\/Accept header, 
matches what is allowed according to consumes\/produces c [...]
+    "autowiredEnabled": { "index": 4, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "engine": { "index": 5, "kind": "property", "displayName": "Engine", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.apache.camel.component.platform.http.spi.PlatformHttpEngine", 
"deprecated": false, "autowired": false, "secret": false, "description": "An 
HTTP Server engine implementation to serve the requests" },
+    "headerFilterStrategy": { "index": 6, "kind": "property", "displayName": 
"Header Filter Strategy", "group": "filter", "label": "filter", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a custom 
org.apache.camel.spi.HeaderFilterStrategy to filter header to and from Camel 
message." }
   },
   "properties": {
     "path": { "index": 0, "kind": "path", "displayName": "Path", "group": 
"consumer", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The path under which this endpoint 
serves the HTTP requests, for proxy use 'proxy'" },
diff --git 
a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
 
b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
index 00abe1cf0f4b..c272ac263a08 100644
--- 
a/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
+++ 
b/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java
@@ -64,6 +64,13 @@ public class PlatformHttpComponent extends 
HeaderFilterStrategyComponent
     @Metadata(label = "advanced,consumer",
               description = "The period in milliseconds after which the 
request should be timed out.")
     private long requestTimeout;
+    @Metadata(label = "advanced,consumer", defaultValue = "true",
+              description = "Whether HTTP server should do preliminary 
validation of incoming requests, validating if Content-Type/Accept header, 
matches what"
+                            + " is allowed according to consumes/produces 
configuration (if set). If validation fails HTTP Status 415/406 is returned."
+                            + " The HTTP server performs this validation 
before Camel is involved, and as such if validation fails then Camel is never 
activated."
+                            + " Setting this option to false, allows Camel to 
process any incoming requests such as to do custom validation"
+                            + " or all requests must be handled by Camel.")
+    private boolean serverRequestValidation = true;
 
     private final Set<HttpEndpointModel> httpEndpoints = new TreeSet<>();
     private final Set<HttpEndpointModel> httpManagementEndpoints = new 
TreeSet<>();
@@ -248,6 +255,14 @@ public class PlatformHttpComponent extends 
HeaderFilterStrategyComponent
         this.requestTimeout = requestTimeout;
     }
 
+    public boolean isServerRequestValidation() {
+        return serverRequestValidation;
+    }
+
+    public void setServerRequestValidation(boolean serverRequestValidation) {
+        this.serverRequestValidation = serverRequestValidation;
+    }
+
     private Consumer doCreateConsumer(
             CamelContext camelContext, Processor processor, String verb, 
String basePath,
             String uriTemplate,
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/PlatformHttpComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/PlatformHttpComponentBuilderFactory.java
index 0bbda8aae1a8..f981332b2d0b 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/PlatformHttpComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/PlatformHttpComponentBuilderFactory.java
@@ -118,6 +118,30 @@ public interface PlatformHttpComponentBuilderFactory {
         }
     
         
+        /**
+         * Whether HTTP server should do preliminary validation of incoming
+         * requests, validating if Content-Type/Accept header, matches what is
+         * allowed according to consumes/produces configuration (if set). If
+         * validation fails HTTP Status 415/406 is returned. The HTTP server
+         * performs this validation before Camel is involved, and as such if
+         * validation fails then Camel is never activated. Setting this option
+         * to false, allows Camel to process any incoming requests such as to 
do
+         * custom validation or all requests must be handled by Camel.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: true
+         * Group: consumer
+         * 
+         * @param serverRequestValidation the value to set
+         * @return the dsl builder
+         */
+        default PlatformHttpComponentBuilder serverRequestValidation(boolean 
serverRequestValidation) {
+            doSetProperty("serverRequestValidation", serverRequestValidation);
+            return this;
+        }
+    
+        
         /**
          * Whether autowiring is enabled. This is used for automatic autowiring
          * options (the option must be marked as autowired) by looking up in 
the
@@ -190,6 +214,7 @@ public interface PlatformHttpComponentBuilderFactory {
             case "bridgeErrorHandler": ((PlatformHttpComponent) 
component).setBridgeErrorHandler((boolean) value); return true;
             case "handleWriteResponseError": ((PlatformHttpComponent) 
component).setHandleWriteResponseError((boolean) value); return true;
             case "requestTimeout": ((PlatformHttpComponent) 
component).setRequestTimeout((long) value); return true;
+            case "serverRequestValidation": ((PlatformHttpComponent) 
component).setServerRequestValidation((boolean) value); return true;
             case "autowiredEnabled": ((PlatformHttpComponent) 
component).setAutowiredEnabled((boolean) value); return true;
             case "engine": ((PlatformHttpComponent) 
component).setEngine((org.apache.camel.component.platform.http.spi.PlatformHttpEngine)
 value); return true;
             case "headerFilterStrategy": ((PlatformHttpComponent) 
component).setHeaderFilterStrategy((org.apache.camel.spi.HeaderFilterStrategy) 
value); return true;

Reply via email to