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 69f5b41527db CAMEL-25635: camel-platform-http-vertx - the charset 
parameter of the request Content-Type is only recognized in lower case (#27853)
69f5b41527db is described below

commit 69f5b41527dbe626d612404a71c01f150a52ec2c
Author: allthingssecurity <[email protected]>
AuthorDate: Thu Oct 15 17:31:36 2026 +0530

    CAMEL-25635: camel-platform-http-vertx - the charset parameter of the 
request Content-Type is only recognized in lower case (#27853)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../http/vertx/VertxPlatformHttpConsumer.java      | 19 ++++-
 .../vertx/VertxPlatformHttpRequestCharsetTest.java | 99 ++++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |  8 ++
 3 files changed, 125 insertions(+), 1 deletion(-)

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 4735af73e171..1f725df7b368 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
@@ -36,6 +36,7 @@ import io.vertx.core.http.CookieSameSite;
 import io.vertx.core.http.HttpMethod;
 import io.vertx.ext.auth.User;
 import io.vertx.ext.web.FileUpload;
+import io.vertx.ext.web.ParsedHeaderValue;
 import io.vertx.ext.web.Route;
 import io.vertx.ext.web.RoutingContext;
 import io.vertx.ext.web.handler.TimeoutHandler;
@@ -61,7 +62,9 @@ import org.apache.camel.spi.RestRegistry.RestService;
 import org.apache.camel.support.DefaultConsumer;
 import org.apache.camel.support.PluginHelper;
 import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.MimeTypeHelper;
+import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -487,11 +490,25 @@ public class VertxPlatformHttpConsumer extends 
DefaultConsumer
         exchange.getMessage().removeHeader("Proxy-Connection");
     }
 
+    /**
+     * The charset parameter of the request Content-Type, whose name is 
case-insensitive (RFC 9110), or null when there
+     * is none or its value is empty ({@code charset=}, {@code charset=""}), 
as in UndertowHelper and NettyHttpHelper.
+     */
+    private static String charsetParameter(ParsedHeaderValue contentType) {
+        for (Map.Entry<String, String> parameter : 
contentType.parameters().entrySet()) {
+            if ("charset".equalsIgnoreCase(parameter.getKey())) {
+                String name = IOHelper.normalizeCharset(parameter.getValue());
+                return ObjectHelper.isEmpty(name) ? null : name;
+            }
+        }
+        return null;
+    }
+
     protected Future<Void> processHttpRequest(Exchange exchange, 
RoutingContext ctx) {
         // reuse existing http message if pooled
         Message in = initializeHttpMessage(exchange, ctx);
 
-        final String charset = 
ctx.parsedHeaders().contentType().parameter("charset");
+        final String charset = 
charsetParameter(ctx.parsedHeaders().contentType());
         if (charset != null) {
             exchange.setProperty(ExchangePropertyKey.CHARSET_NAME, charset);
             in.setHeader(Exchange.HTTP_CHARACTER_ENCODING, charset);
diff --git 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpRequestCharsetTest.java
 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpRequestCharsetTest.java
new file mode 100644
index 000000000000..cbd3d4cfc3fd
--- /dev/null
+++ 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpRequestCharsetTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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 java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * The charset parameter of the request Content-Type is read whatever the case 
of its name (RFC 9110, 5.6.6), and an
+ * empty charset parameter counts as no charset (CAMEL-25355).
+ */
+class VertxPlatformHttpRequestCharsetTest {
+
+    private static final String TEXT = "Grüße aus Köln";
+
+    private CamelContext context;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        context = VertxPlatformHttpEngineTest.createCamelContext();
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                // decodes the request in its charset and answers in UTF-8
+                from("platform-http:/decode")
+                        .convertBodyTo(String.class)
+                        .setHeader(Exchange.CONTENT_TYPE, 
constant("text/plain; charset=UTF-8"));
+            }
+        });
+        VertxPlatformHttpEngineTest.startCamelContext(context);
+    }
+
+    @AfterEach
+    void tearDown() {
+        context.stop();
+    }
+
+    @Test
+    void testRequestCharsetParameterInUpperCase() throws Exception {
+        HttpResponse<byte[]> response = post("text/plain; Charset=ISO-8859-1", 
TEXT.getBytes(ISO_8859_1));
+
+        assertEquals(200, response.statusCode());
+        assertArrayEquals(TEXT.getBytes(UTF_8), response.body());
+    }
+
+    @Test
+    void testEmptyRequestCharsetParameter() throws Exception {
+        // no charset: the body is decoded with the default charset (UTF-8) 
instead of failing on Charset.forName("")
+        HttpResponse<byte[]> response = post("text/plain; charset=", 
TEXT.getBytes(UTF_8));
+
+        assertEquals(200, response.statusCode());
+        assertArrayEquals(TEXT.getBytes(UTF_8), response.body());
+    }
+
+    @Test
+    void testEmptyQuotedRequestCharsetParameterFollowedByAnotherParameter() 
throws Exception {
+        HttpResponse<byte[]> response = post("text/plain; charset=\"\"; 
format=flowed", TEXT.getBytes(UTF_8));
+
+        assertEquals(200, response.statusCode());
+        assertArrayEquals(TEXT.getBytes(UTF_8), response.body());
+    }
+
+    private HttpResponse<byte[]> post(String contentType, byte[] body) throws 
Exception {
+        VertxPlatformHttpServer server = 
context.hasService(VertxPlatformHttpServer.class);
+        HttpRequest request = 
HttpRequest.newBuilder(URI.create("http://localhost:"; + server.getPort() + 
"/decode"))
+                .header("Content-Type", contentType)
+                .POST(HttpRequest.BodyPublishers.ofByteArray(body))
+                .build();
+        return HttpClient.newHttpClient().send(request, 
HttpResponse.BodyHandlers.ofByteArray());
+    }
+}
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 0942e3621447..cfe3340e54d4 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -350,6 +350,14 @@ with `OAuthHelper.validateOAuthToken` from camel-support 
instead.
 For any other message, such as one from camel-undertow, the processors keep 
reading the message headers, but leave out
 a value that also appears in the query string of the request.
 
+=== camel-platform-http-vertx - the charset parameter of the request 
Content-Type in any case
+
+The consumer now reads the charset parameter of the request `Content-Type` 
whatever the case of its name, as
+camel-undertow and camel-netty-http do: a body sent with `Content-Type: 
text/plain; Charset=ISO-8859-1` is decoded as
+ISO-8859-1 and `CamelCharsetName` is set. Before, only `charset=` in lower 
case was read and such a body was decoded
+as UTF-8. An empty charset parameter (`charset=` or `charset=""`) now counts 
as no charset, as in camel-undertow,
+camel-netty-http and camel-http-common (CAMEL-25355); before, converting the 
body to a String failed with 500.
+
 === camel-report-maven-plugin - Java routes are read with the Java DSL parser
 
 The `validate` and `route-coverage` goals read Java routes with the Java DSL 
parser of camel-java-io instead of

Reply via email to