You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2025/02/03 14:53:29 UTC

(camel) branch fu created (now 99f0b4d6e7e)

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

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


      at 99f0b4d6e7e CAMEL-21700: camel-platform-http-main - Support file uploads by default.

This branch includes the following new commits:

     new 99f0b4d6e7e CAMEL-21700: camel-platform-http-main - Support file uploads by default.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(camel) 01/01: CAMEL-21700: camel-platform-http-main - Support file uploads by default.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 99f0b4d6e7e3b403d9b55f4f177ffa32833f90c1
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Feb 3 15:53:13 2025 +0100

    CAMEL-21700: camel-platform-http-main - Support file uploads by default.
---
 .../apache/camel/catalog/dev-consoles.properties   |  1 +
 .../catalog/dev-consoles/main-http-server.json     | 15 ++++
 .../main/camel-main-configuration-metadata.json    |  2 +
 .../apache/camel/dev-console/main-http-server.json | 15 ++++
 .../org/apache/camel/dev-console/main-http-server  |  2 +
 .../org/apache/camel/dev-consoles.properties       |  7 ++
 .../http/main/DefaultMainHttpServerFactory.java    | 14 +++-
 .../platform/http/main/MainHttpServer.java         | 18 ++++
 .../http/main/MainHttpServerDevConsole.java        | 76 +++++++++++++++++
 .../VertxPlatformHttpServerConfiguration.java      |  4 +-
 .../http/vertx/VertxPlatformHttpServerSupport.java | 15 +++-
 .../impl/engine/DefaultStreamCachingStrategy.java  | 41 +--------
 ...ttpServerConfigurationPropertiesConfigurer.java | 14 ++++
 .../camel-main-configuration-metadata.json         |  2 +
 core/camel-main/src/main/docs/main.adoc            |  4 +-
 .../org/apache/camel/main/BaseMainSupport.java     |  2 +-
 .../main/HttpServerConfigurationProperties.java    | 51 ++++++++++-
 .../apache/camel/main/MainHttpServerFactory.java   |  4 +-
 .../org/apache/camel/support/TempDirHelper.java    | 98 ++++++++++++++++++++++
 .../apache/camel/support/MessageHelperTest.java    |  1 -
 .../org/apache/camel/support/ObjectHelperTest.java |  1 -
 .../camel/main/download/MainHttpServerFactory.java |  2 +-
 22 files changed, 338 insertions(+), 51 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles.properties
index c2b95c3bd17..7ce1a9dbffd 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles.properties
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles.properties
@@ -24,6 +24,7 @@ kubernetes-configmaps
 kubernetes-secrets
 log
 main-configuration
+main-http-server
 memory
 micrometer
 platform-http
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/main-http-server.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/main-http-server.json
new file mode 100644
index 00000000000..8bca6f3b74c
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/main-http-server.json
@@ -0,0 +1,15 @@
+{
+  "console": {
+    "kind": "console",
+    "group": "camel",
+    "name": "main-http-server",
+    "title": "Main HTTP Server",
+    "description": "Camel Main HTTP Server",
+    "deprecated": false,
+    "javaType": "org.apache.camel.component.platform.http.main.MainHttpServerDevConsole",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-platform-http-main",
+    "version": "4.10.0-SNAPSHOT"
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 31101f2b13f..71a1bfd7be6 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -271,6 +271,8 @@
     { "name": "camel.server.devConsoleEnabled", "description": "Whether to enable developer console (not intended for production use). Dev console must also be enabled on CamelContext. For example by setting camel.context.dev-console=true in application.properties, or via code camelContext.setDevConsole(true); If enabled then you can access a basic developer console on context-path: \/q\/dev.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "j [...]
     { "name": "camel.server.downloadEnabled", "description": "Whether to enable file download via HTTP. This makes it possible to browse and download resource source files such as Camel XML or YAML routes. Only enable this for development, troubleshooting or special situations for management and monitoring.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.enabled", "description": "Whether embedded HTTP server is enabled. By default, the server is not enabled.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
+    { "name": "camel.server.fileUploadDirectory", "description": "Directory to temporary store file uploads while Camel routes the incoming request. If no directory has been explicit configured, then a temporary directory is created in the java.io.tmpdir directory.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
+    { "name": "camel.server.fileUploadEnabled", "description": "Whether to enable file uploads being supported (such as POST multipart\/form-data) and stored into a temporary directory.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.server.healthCheckEnabled", "description": "Whether to enable health-check console. If enabled then you can access health-check status on context-path: \/q\/health (default)", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.healthPath", "description": "The path endpoint used to expose the health status", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "\/q\/health" },
     { "name": "camel.server.host", "description": "Hostname to use for binding embedded HTTP server", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "0.0.0.0" },
diff --git a/components/camel-platform-http-main/src/generated/resources/META-INF/org/apache/camel/dev-console/main-http-server.json b/components/camel-platform-http-main/src/generated/resources/META-INF/org/apache/camel/dev-console/main-http-server.json
new file mode 100644
index 00000000000..8bca6f3b74c
--- /dev/null
+++ b/components/camel-platform-http-main/src/generated/resources/META-INF/org/apache/camel/dev-console/main-http-server.json
@@ -0,0 +1,15 @@
+{
+  "console": {
+    "kind": "console",
+    "group": "camel",
+    "name": "main-http-server",
+    "title": "Main HTTP Server",
+    "description": "Camel Main HTTP Server",
+    "deprecated": false,
+    "javaType": "org.apache.camel.component.platform.http.main.MainHttpServerDevConsole",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-platform-http-main",
+    "version": "4.10.0-SNAPSHOT"
+  }
+}
+
diff --git a/components/camel-platform-http-main/src/generated/resources/META-INF/services/org/apache/camel/dev-console/main-http-server b/components/camel-platform-http-main/src/generated/resources/META-INF/services/org/apache/camel/dev-console/main-http-server
new file mode 100644
index 00000000000..eea0ea2dfac
--- /dev/null
+++ b/components/camel-platform-http-main/src/generated/resources/META-INF/services/org/apache/camel/dev-console/main-http-server
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.platform.http.main.MainHttpServerDevConsole
diff --git a/components/camel-platform-http-main/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties b/components/camel-platform-http-main/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties
new file mode 100644
index 00000000000..da04ba948d5
--- /dev/null
+++ b/components/camel-platform-http-main/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+dev-consoles=main-http-server
+groupId=org.apache.camel
+artifactId=camel-platform-http-main
+version=4.10.0-SNAPSHOT
+projectName=Camel :: Platform HTTP :: Main
+projectDescription=Platform HTTP for standalone Camel Main applications
diff --git a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
index f25f8cd7ad0..7daae15af58 100644
--- a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
+++ b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
@@ -25,11 +25,14 @@ import org.apache.camel.main.HttpServerConfigurationProperties;
 import org.apache.camel.main.MainConstants;
 import org.apache.camel.main.MainHttpServerFactory;
 import org.apache.camel.spi.annotations.JdkService;
+import org.apache.camel.support.TempDirHelper;
 import org.apache.camel.util.ObjectHelper;
 
 @JdkService(MainConstants.PLATFORM_HTTP_SERVER)
 public class DefaultMainHttpServerFactory implements CamelContextAware, MainHttpServerFactory {
 
+    private static final String DEFAULT_UPLOAD_DIR = "${java.io.tmpdir}/camel/camel-tmp-#uuid#/";
+
     private CamelContext camelContext;
 
     @Override
@@ -43,7 +46,7 @@ public class DefaultMainHttpServerFactory implements CamelContextAware, MainHttp
     }
 
     @Override
-    public Service newHttpServer(HttpServerConfigurationProperties configuration) {
+    public Service newHttpServer(CamelContext camelContext, HttpServerConfigurationProperties configuration) {
         MainHttpServer server = new MainHttpServer();
 
         server.setCamelContext(camelContext);
@@ -54,6 +57,15 @@ public class DefaultMainHttpServerFactory implements CamelContextAware, MainHttp
             server.setMaxBodySize(configuration.getMaxBodySize());
         }
         server.setUseGlobalSslContextParameters(configuration.isUseGlobalSslContextParameters());
+        server.setFileUploadEnabled(configuration.isFileUploadEnabled());
+        if (configuration.isFileUploadEnabled()) {
+            String dir = configuration.getFileUploadDirectory();
+            if (dir == null) {
+                dir = DEFAULT_UPLOAD_DIR;
+            }
+            dir = TempDirHelper.resolveTempDir(camelContext, null, dir);
+            server.setFileUploadDirectory(dir);
+        }
         server.setInfoEnabled(configuration.isInfoEnabled());
         server.setStaticEnabled(configuration.isStaticEnabled());
         server.setStaticContextPath(configuration.getStaticContextPath());
diff --git a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
index d8a891a9d76..4980ef51d0d 100644
--- a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
+++ b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
@@ -152,6 +152,24 @@ public class MainHttpServer extends ServiceSupport implements CamelContextAware,
         this.configuration = configuration;
     }
 
+    @ManagedAttribute(description = "Whether file uploads is enabled")
+    public boolean isFileUploadEnabled() {
+        return configuration.getBodyHandler().isHandleFileUploads();
+    }
+
+    public void setFileUploadEnabled(boolean fileUploadEnabled) {
+        configuration.getBodyHandler().setHandleFileUploads(fileUploadEnabled);
+    }
+
+    @ManagedAttribute(description = "Directory to temporary store file uploads")
+    public String getFileUploadDirectory() {
+        return configuration.getBodyHandler().getUploadsDirectory();
+    }
+
+    public void setFileUploadDirectory(String fileUploadDirectory) {
+        configuration.getBodyHandler().setUploadsDirectory(fileUploadDirectory);
+    }
+
     @ManagedAttribute(description = "Whether info is enabled (/q/info)")
     public boolean isInfoEnabled() {
         return infoEnabled;
diff --git a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServerDevConsole.java b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServerDevConsole.java
new file mode 100644
index 00000000000..8f02b14655a
--- /dev/null
+++ b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServerDevConsole.java
@@ -0,0 +1,76 @@
+/*
+ * 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.main;
+
+import java.util.Map;
+
+import org.apache.camel.spi.annotations.DevConsole;
+import org.apache.camel.support.console.AbstractDevConsole;
+import org.apache.camel.util.json.JsonObject;
+
+@DevConsole(name = "main-http-server", displayName = "Main HTTP Server", description = "Camel Main HTTP Server")
+public class MainHttpServerDevConsole extends AbstractDevConsole {
+
+    public MainHttpServerDevConsole() {
+        super("camel", "main-http-server", "Main HTTP Server", "Camel Main HTTP Server");
+    }
+
+    @Override
+    protected String doCallText(Map<String, Object> options) {
+        StringBuilder sb = new StringBuilder();
+
+        MainHttpServer server = getCamelContext().hasService(MainHttpServer.class);
+        if (server != null) {
+            String p = server.getPath();
+            if (p != null && p.startsWith("/")) {
+                p = p.substring(1);
+            }
+            String url = String.format("%s:%s%s", server.getHost(), server.getPort(), p);
+            sb.append(String.format("    Server: http://%s", url));
+            if (server.getMaxBodySize() != null) {
+                sb.append(String.format("\n    Max Body Size: %s", server.getMaxBodySize()));
+            }
+            sb.append(String.format("\n    File Upload Enabled: %b", server.isFileUploadEnabled()));
+            sb.append(String.format("\n    File Upload Dir: %s", server.getFileUploadDirectory()));
+            sb.append(String.format("\n    Use Global SSL ContextParameters: %s", server.isUseGlobalSslContextParameters()));
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    protected Map<String, Object> doCallJson(Map<String, Object> options) {
+        JsonObject root = new JsonObject();
+
+        MainHttpServer server = getCamelContext().hasService(MainHttpServer.class);
+        if (server != null) {
+            root.put("host", server.getHost());
+            root.put("port", server.getPort());
+            root.put("path", server.getPath());
+            if (server.getMaxBodySize() != null) {
+                root.put("maxBodySize", server.getMaxBodySize());
+            }
+            root.put("fileUploadEnabled", server.isFileUploadEnabled());
+            if (server.getFileUploadDirectory() != null) {
+                root.put("fileUploadDirectory", server.getFileUploadDirectory());
+            }
+            root.put("useGlobalSslContextParameters", server.isUseGlobalSslContextParameters());
+        }
+
+        return root;
+    }
+}
diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerConfiguration.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerConfiguration.java
index 07387884e9e..71c37456996 100644
--- a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerConfiguration.java
+++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerConfiguration.java
@@ -326,9 +326,9 @@ public class VertxPlatformHttpServerConfiguration {
 
     public static class BodyHandler {
         private boolean handleFileUploads;
-        private String uploadsDirectory = "file-uploads";
+        private String uploadsDirectory;
         private boolean mergeFormAttributes = true;
-        private boolean deleteUploadedFilesOnEnd;
+        private boolean deleteUploadedFilesOnEnd = true;
         private boolean preallocateBodyBuffer = true;
 
         public boolean isHandleFileUploads() {
diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerSupport.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerSupport.java
index 23cadb5e79d..adfad45c3a4 100644
--- a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerSupport.java
+++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerSupport.java
@@ -34,8 +34,13 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.component.vertx.common.VertxHelper;
 import org.apache.camel.support.jsse.SSLContextParameters;
 import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public final class VertxPlatformHttpServerSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(VertxPlatformHttpServerSupport.class);
+
     private static final Pattern COMMA_SEPARATED_SPLIT_REGEX = Pattern.compile("\\s*,\\s*");
 
     private VertxPlatformHttpServerSupport() {
@@ -53,13 +58,19 @@ public final class VertxPlatformHttpServerSupport {
         if (configuration.getMaxBodySize() != null) {
             bodyHandler.setBodyLimit(configuration.getMaxBodySize());
         }
-
         bodyHandler.setHandleFileUploads(configuration.getBodyHandler().isHandleFileUploads());
-        bodyHandler.setUploadsDirectory(configuration.getBodyHandler().getUploadsDirectory());
+        if (configuration.getBodyHandler().getUploadsDirectory() != null) {
+            bodyHandler.setUploadsDirectory(configuration.getBodyHandler().getUploadsDirectory());
+        }
         bodyHandler.setDeleteUploadedFilesOnEnd(configuration.getBodyHandler().isDeleteUploadedFilesOnEnd());
         bodyHandler.setMergeFormAttributes(configuration.getBodyHandler().isMergeFormAttributes());
         bodyHandler.setPreallocateBodyBuffer(configuration.getBodyHandler().isPreallocateBodyBuffer());
 
+        if (configuration.getBodyHandler().isHandleFileUploads()) {
+            LOG.debug("Vert.x HttpServer file-upload dir: {}",
+                    configuration.getBodyHandler().getUploadsDirectory());
+        }
+
         return (RoutingContext event) -> {
             event.request().resume();
             bodyHandler.handle(event);
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
index e92a0076793..d22e9aa0712 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
@@ -34,8 +34,8 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.StreamCache;
 import org.apache.camel.spi.StreamCachingStrategy;
+import org.apache.camel.support.TempDirHelper;
 import org.apache.camel.support.service.ServiceSupport;
-import org.apache.camel.util.FilePathResolver;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
 import org.slf4j.Logger;
@@ -333,43 +333,6 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
         return false;
     }
 
-    protected String resolveSpoolDirectory(String path) {
-        if (camelContext.getManagementNameStrategy() != null) {
-            String name = camelContext.getManagementNameStrategy().resolveManagementName(path, camelContext.getName(), false);
-            if (name != null) {
-                name = customResolveManagementName(name);
-            }
-            // and then check again with invalid check to ensure all ## is resolved
-            if (name != null) {
-                name = camelContext.getManagementNameStrategy().resolveManagementName(name, camelContext.getName(), true);
-            }
-            return name;
-        } else {
-            return defaultManagementName(path);
-        }
-    }
-
-    protected String defaultManagementName(String path) {
-        // must quote the names to have it work as literal replacement
-        String name = camelContext.getName();
-
-        // replace tokens
-        String answer = path;
-        answer = answer.replace("#camelId#", name);
-        answer = answer.replace("#name#", name);
-        // replace custom
-        answer = customResolveManagementName(answer);
-        return answer;
-    }
-
-    protected String customResolveManagementName(String pattern) {
-        if (pattern.contains("#uuid#")) {
-            String uuid = camelContext.getUuidGenerator().generateUuid();
-            pattern = pattern.replace("#uuid#", uuid);
-        }
-        return FilePathResolver.resolvePath(pattern);
-    }
-
     @Override
     protected void doStart() throws Exception {
         if (!enabled) {
@@ -409,7 +372,7 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
                 throw new IllegalArgumentException("SpoolDirectory must be configured when using SpoolThreshold > 0");
             }
             if (spoolDirectory == null) {
-                String name = resolveSpoolDirectory(spoolDirectoryName);
+                String name = TempDirHelper.resolveTempDir(camelContext, null, spoolDirectoryName);
                 if (name != null) {
                     spoolDirectory = new File(name);
                     spoolDirectoryName = null;
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
index 448df94e6e6..e47a448a491 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
@@ -28,6 +28,8 @@ public class HttpServerConfigurationPropertiesConfigurer extends org.apache.came
         map.put("DevConsoleEnabled", boolean.class);
         map.put("DownloadEnabled", boolean.class);
         map.put("Enabled", boolean.class);
+        map.put("FileUploadDirectory", java.lang.String.class);
+        map.put("FileUploadEnabled", boolean.class);
         map.put("HealthCheckEnabled", boolean.class);
         map.put("HealthPath", java.lang.String.class);
         map.put("Host", java.lang.String.class);
@@ -64,6 +66,10 @@ public class HttpServerConfigurationPropertiesConfigurer extends org.apache.came
         case "downloadenabled":
         case "downloadEnabled": target.setDownloadEnabled(property(camelContext, boolean.class, value)); return true;
         case "enabled": target.setEnabled(property(camelContext, boolean.class, value)); return true;
+        case "fileuploaddirectory":
+        case "fileUploadDirectory": target.setFileUploadDirectory(property(camelContext, java.lang.String.class, value)); return true;
+        case "fileuploadenabled":
+        case "fileUploadEnabled": target.setFileUploadEnabled(property(camelContext, boolean.class, value)); return true;
         case "healthcheckenabled":
         case "healthCheckEnabled": target.setHealthCheckEnabled(property(camelContext, boolean.class, value)); return true;
         case "healthpath":
@@ -120,6 +126,10 @@ public class HttpServerConfigurationPropertiesConfigurer extends org.apache.came
         case "downloadenabled":
         case "downloadEnabled": return boolean.class;
         case "enabled": return boolean.class;
+        case "fileuploaddirectory":
+        case "fileUploadDirectory": return java.lang.String.class;
+        case "fileuploadenabled":
+        case "fileUploadEnabled": return boolean.class;
         case "healthcheckenabled":
         case "healthCheckEnabled": return boolean.class;
         case "healthpath":
@@ -172,6 +182,10 @@ public class HttpServerConfigurationPropertiesConfigurer extends org.apache.came
         case "downloadenabled":
         case "downloadEnabled": return target.isDownloadEnabled();
         case "enabled": return target.isEnabled();
+        case "fileuploaddirectory":
+        case "fileUploadDirectory": return target.getFileUploadDirectory();
+        case "fileuploadenabled":
+        case "fileUploadEnabled": return target.isFileUploadEnabled();
         case "healthcheckenabled":
         case "healthCheckEnabled": return target.isHealthCheckEnabled();
         case "healthpath":
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 31101f2b13f..71a1bfd7be6 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -271,6 +271,8 @@
     { "name": "camel.server.devConsoleEnabled", "description": "Whether to enable developer console (not intended for production use). Dev console must also be enabled on CamelContext. For example by setting camel.context.dev-console=true in application.properties, or via code camelContext.setDevConsole(true); If enabled then you can access a basic developer console on context-path: \/q\/dev.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "j [...]
     { "name": "camel.server.downloadEnabled", "description": "Whether to enable file download via HTTP. This makes it possible to browse and download resource source files such as Camel XML or YAML routes. Only enable this for development, troubleshooting or special situations for management and monitoring.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.enabled", "description": "Whether embedded HTTP server is enabled. By default, the server is not enabled.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
+    { "name": "camel.server.fileUploadDirectory", "description": "Directory to temporary store file uploads while Camel routes the incoming request. If no directory has been explicit configured, then a temporary directory is created in the java.io.tmpdir directory.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
+    { "name": "camel.server.fileUploadEnabled", "description": "Whether to enable file uploads being supported (such as POST multipart\/form-data) and stored into a temporary directory.", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.server.healthCheckEnabled", "description": "Whether to enable health-check console. If enabled then you can access health-check status on context-path: \/q\/health (default)", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.healthPath", "description": "The path endpoint used to expose the health status", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "\/q\/health" },
     { "name": "camel.server.host", "description": "Hostname to use for binding embedded HTTP server", "sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "0.0.0.0" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index d4c0af3ef95..076867005fc 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -187,7 +187,7 @@ The camel.routecontroller supports 12 options, which are listed below.
 
 
 === Camel Embedded HTTP Server (only for standalone; not Spring Boot or Quarkus) configurations
-The camel.server supports 24 options, which are listed below.
+The camel.server supports 26 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -198,6 +198,8 @@ The camel.server supports 24 options, which are listed below.
 | *camel.server.devConsoleEnabled* | Whether to enable developer console (not intended for production use). Dev console must also be enabled on CamelContext. For example by setting camel.context.dev-console=true in application.properties, or via code camelContext.setDevConsole(true); If enabled then you can access a basic developer console on context-path: /q/dev. | false | boolean
 | *camel.server.downloadEnabled* | Whether to enable file download via HTTP. This makes it possible to browse and download resource source files such as Camel XML or YAML routes. Only enable this for development, troubleshooting or special situations for management and monitoring. | false | boolean
 | *camel.server.enabled* | Whether embedded HTTP server is enabled. By default, the server is not enabled. | false | boolean
+| *camel.server.fileUpload{zwsp}Directory* | Directory to temporary store file uploads while Camel routes the incoming request. If no directory has been explicit configured, then a temporary directory is created in the java.io.tmpdir directory. |  | String
+| *camel.server.fileUploadEnabled* | Whether to enable file uploads being supported (such as POST multipart/form-data) and stored into a temporary directory. | true | boolean
 | *camel.server.healthCheck{zwsp}Enabled* | Whether to enable health-check console. If enabled then you can access health-check status on context-path: /q/health (default) | false | boolean
 | *camel.server.healthPath* | The path endpoint used to expose the health status | /q/health | String
 | *camel.server.host* | Hostname to use for binding embedded HTTP server | 0.0.0.0 | String
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index 99408899ebc..8eaf7348ab0 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -1800,7 +1800,7 @@ public abstract class BaseMainSupport extends BaseService {
         // auto-detect camel-platform-http-main on classpath
         MainHttpServerFactory sf = resolveMainHttpServerFactory(camelContext);
         // create http server as a service managed by camel context
-        Service http = sf.newHttpServer(server);
+        Service http = sf.newHttpServer(camelContext, server);
         // force eager starting as embedded http server is used for
         // container platform to check readiness and need to be started eager
         camelContext.addService(http, true, true);
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
index f5f58eb0e85..33f5afa81a5 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
@@ -38,7 +38,10 @@ public class HttpServerConfigurationProperties implements BootstrapCloseable {
     private String path = "/";
     private Long maxBodySize;
     private boolean useGlobalSslContextParameters;
-
+    @Metadata(defaultValue = "true")
+    private boolean fileUploadEnabled = true;
+    @Metadata
+    private String fileUploadDirectory;
     private boolean infoEnabled;
     private boolean staticEnabled;
     @Metadata(defaultValue = "/")
@@ -147,6 +150,32 @@ public class HttpServerConfigurationProperties implements BootstrapCloseable {
         this.useGlobalSslContextParameters = useGlobalSslContextParameters;
     }
 
+    public boolean isFileUploadEnabled() {
+        return fileUploadEnabled;
+    }
+
+    /**
+     * Whether to enable file uploads being supported (such as POST multipart/form-data) and stored into a temporary
+     * directory.
+     */
+    public void setFileUploadEnabled(boolean fileUploadEnabled) {
+        this.fileUploadEnabled = fileUploadEnabled;
+    }
+
+    public String getFileUploadDirectory() {
+        return fileUploadDirectory;
+    }
+
+    /**
+     * Directory to temporary store file uploads while Camel routes the incoming request.
+     *
+     * If no directory has been explicit configured, then a temporary directory is created in the java.io.tmpdir
+     * directory.
+     */
+    public void setFileUploadDirectory(String fileUploadDirectory) {
+        this.fileUploadDirectory = fileUploadDirectory;
+    }
+
     public boolean isInfoEnabled() {
         return infoEnabled;
     }
@@ -406,6 +435,26 @@ public class HttpServerConfigurationProperties implements BootstrapCloseable {
         return this;
     }
 
+    /**
+     * Whether to enable file uploads being supported (such as POST multipart/form-data) and stored into a temporary
+     * directory.
+     */
+    public HttpServerConfigurationProperties withFileUploadEnabled(boolean fileUploadEnabled) {
+        this.fileUploadEnabled = fileUploadEnabled;
+        return this;
+    }
+
+    /**
+     * Directory to temporary store file uploads while Camel routes the incoming request.
+     *
+     * If no directory has been explicit configured, then a temporary directory is created in the java.io.tmpdir
+     * directory.
+     */
+    public HttpServerConfigurationProperties withFileUploadDirectory(String fileUploadDirectory) {
+        this.fileUploadDirectory = fileUploadDirectory;
+        return this;
+    }
+
     /**
      * Whether to enable info console. If enabled then you can see some basic Camel information at /q/info
      */
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainHttpServerFactory.java b/core/camel-main/src/main/java/org/apache/camel/main/MainHttpServerFactory.java
index f75a1e1fa36..f149cc90549 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/MainHttpServerFactory.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/MainHttpServerFactory.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.main;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Service;
 
 /**
@@ -26,8 +27,9 @@ public interface MainHttpServerFactory {
     /**
      * Creates the embedded HTTP server
      *
+     * @param  camelContext  the camel context
      * @param  configuration server configuration
      * @return               the server as a {@link Service} to be managed by {@link org.apache.camel.CamelContext}.
      */
-    Service newHttpServer(HttpServerConfigurationProperties configuration);
+    Service newHttpServer(CamelContext camelContext, HttpServerConfigurationProperties configuration);
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/TempDirHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/TempDirHelper.java
new file mode 100644
index 00000000000..835fe00e92c
--- /dev/null
+++ b/core/camel-support/src/main/java/org/apache/camel/support/TempDirHelper.java
@@ -0,0 +1,98 @@
+/*
+ * 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.support;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.util.FilePathResolver;
+import org.apache.camel.util.FileUtil;
+
+/**
+ * Helper for resolving temp directory.
+ */
+public final class TempDirHelper {
+
+    public static final String DEFAULT_PATTERN = "${java.io.tmpdir}/camel/camel-tmp-#uuid#";
+
+    private TempDirHelper() {
+    }
+
+    /**
+     * Resolves a temp dir using the default pattern.
+     *
+     * @param  camelContext the camel context
+     * @param  path         the sub-dir for the temp dir
+     * @return              the resolved temp dir
+     */
+    public static String resolveDefaultTempDir(CamelContext camelContext, String path) {
+        return resolveTempDir(camelContext, DEFAULT_PATTERN, path);
+    }
+
+    /**
+     * Resolves a temp dir
+     *
+     * @param  camelContext the camel context
+     * @param  pattern      pattern for the base path of the temp dir
+     * @param  path         the sub-dir for the temp dir
+     * @return              the resolved temp dir
+     */
+    public static String resolveTempDir(CamelContext camelContext, String pattern, String path) {
+        String answer;
+        if (pattern != null && path != null) {
+            path = pattern + "/" + path;
+        } else if (path == null) {
+            path = pattern;
+        }
+        if (camelContext.getManagementNameStrategy() != null) {
+            String name = camelContext.getManagementNameStrategy().resolveManagementName(path, camelContext.getName(), false);
+            if (name != null) {
+                name = customResolveManagementName(camelContext, name);
+            }
+            // and then check again with invalid check to ensure all ## is resolved
+            if (name != null) {
+                name = camelContext.getManagementNameStrategy().resolveManagementName(name, camelContext.getName(), true);
+            }
+            answer = name;
+        } else {
+            answer = defaultManagementName(camelContext, path);
+        }
+        // remove double slashes
+        answer = FileUtil.compactPath(answer);
+        return answer;
+    }
+
+    private static String defaultManagementName(CamelContext camelContext, String path) {
+        // must quote the names to have it work as literal replacement
+        String name = camelContext.getName();
+
+        // replace tokens
+        String answer = path;
+        answer = answer.replace("#camelId#", name);
+        answer = answer.replace("#name#", name);
+        // replace custom
+        answer = customResolveManagementName(camelContext, answer);
+        return answer;
+    }
+
+    private static String customResolveManagementName(CamelContext camelContext, String pattern) {
+        if (pattern.contains("#uuid#")) {
+            String uuid = camelContext.getUuidGenerator().generateUuid();
+            pattern = pattern.replace("#uuid#", uuid);
+        }
+        return FilePathResolver.resolvePath(pattern);
+    }
+
+}
diff --git a/core/camel-support/src/test/java/org/apache/camel/support/MessageHelperTest.java b/core/camel-support/src/test/java/org/apache/camel/support/MessageHelperTest.java
index 4c52e12ed80..6ba63e877b9 100644
--- a/core/camel-support/src/test/java/org/apache/camel/support/MessageHelperTest.java
+++ b/core/camel-support/src/test/java/org/apache/camel/support/MessageHelperTest.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.camel.support;
 
 import java.util.Map;
diff --git a/core/camel-support/src/test/java/org/apache/camel/support/ObjectHelperTest.java b/core/camel-support/src/test/java/org/apache/camel/support/ObjectHelperTest.java
index 9727f0c80af..23f42f12191 100644
--- a/core/camel-support/src/test/java/org/apache/camel/support/ObjectHelperTest.java
+++ b/core/camel-support/src/test/java/org/apache/camel/support/ObjectHelperTest.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.camel.support;
 
 import org.junit.jupiter.api.DisplayName;
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MainHttpServerFactory.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MainHttpServerFactory.java
index 8cbba6d1f00..a596b08c03d 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MainHttpServerFactory.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MainHttpServerFactory.java
@@ -37,7 +37,7 @@ public class MainHttpServerFactory {
                 try {
                     // enable http server if not silent
                     org.apache.camel.main.MainHttpServerFactory factory = resolveMainHttpServerFactory(camelContext);
-                    Service httpServer = factory.newHttpServer(config);
+                    Service httpServer = factory.newHttpServer(camelContext, config);
                     camelContext.addService(httpServer, true, true);
                 } catch (Exception e) {
                     throw new RuntimeException(e);