From 2b28a664fe0d04b2eb81937db8a85cd4c2c6e69c Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Tue, 9 Jan 2024 17:38:44 +0530 Subject: [PATCH] Updated jetty maxFormContentSize value to 1048576 bytes (default is 200000 bytes), to support user data upto 1048576 bytes (#8420) This PR enables support for user data content upto 1048576 bytes - updates jetty maxFormContentSize value to 1048576 bytes (default is 200000 bytes). CloudStack can support max user data content to 1048576 bytes (the size can be configurable through vm.userdata.max.length setting, max 1048576), but it's limited due to the default Jetty max content size, which is 200000 bytes. Configuration Reference from jetty doc: https://eclipse.dev/jetty/documentation/jetty-9/index.html#configuring-specific-webapp-deployment (check with maxFormContentSize here) --- client/conf/server.properties.in | 3 +++ .../org/apache/cloudstack/ServerDaemon.java | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/client/conf/server.properties.in b/client/conf/server.properties.in index 42d98a6eb29..9fb777f1e21 100644 --- a/client/conf/server.properties.in +++ b/client/conf/server.properties.in @@ -29,6 +29,9 @@ http.port=8080 # Max inactivity time in minutes for the session session.timeout=30 +# Max allowed API request payload / content size in bytes +request.content.size=1048576 + # Options to configure and enable HTTPS on management server # # For management server to pickup these configuration settings, the configured diff --git a/client/src/main/java/org/apache/cloudstack/ServerDaemon.java b/client/src/main/java/org/apache/cloudstack/ServerDaemon.java index 63cdc45b8dc..763c274c7f5 100644 --- a/client/src/main/java/org/apache/cloudstack/ServerDaemon.java +++ b/client/src/main/java/org/apache/cloudstack/ServerDaemon.java @@ -26,10 +26,10 @@ import java.lang.management.ManagementFactory; import java.net.URL; import java.util.Properties; -import com.cloud.utils.Pair; -import com.cloud.utils.server.ServerProperties; import org.apache.commons.daemon.Daemon; import org.apache.commons.daemon.DaemonContext; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.server.ForwardedRequestCustomizer; import org.eclipse.jetty.server.HttpConfiguration; @@ -40,6 +40,7 @@ import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.MovedContextHandler; import org.eclipse.jetty.server.handler.RequestLogHandler; @@ -50,10 +51,10 @@ import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.webapp.WebAppContext; -import org.apache.log4j.Logger; +import com.cloud.utils.Pair; import com.cloud.utils.PropertiesUtil; -import org.apache.commons.lang3.StringUtils; +import com.cloud.utils.server.ServerProperties; /*** * The ServerDaemon class implements the embedded server, it can be started either @@ -79,6 +80,8 @@ public class ServerDaemon implements Daemon { private static final String KEYSTORE_PASSWORD = "https.keystore.password"; private static final String WEBAPP_DIR = "webapp.dir"; private static final String ACCESS_LOG = "access.log"; + private static final String REQUEST_CONTENT_SIZE_KEY = "request.content.size"; + private static final int DEFAULT_REQUEST_CONTENT_SIZE = 1048576; //////////////////////////////////////////////////////// /////////////// Server Configuration /////////////////// @@ -90,6 +93,7 @@ public class ServerDaemon implements Daemon { private int httpPort = 8080; private int httpsPort = 8443; private int sessionTimeout = 30; + private int maxFormContentSize = DEFAULT_REQUEST_CONTENT_SIZE; private boolean httpsEnable = false; private String accessLogFile = "access.log"; private String bindInterface = null; @@ -136,6 +140,7 @@ public class ServerDaemon implements Daemon { setWebAppLocation(properties.getProperty(WEBAPP_DIR)); setAccessLogFile(properties.getProperty(ACCESS_LOG, "access.log")); setSessionTimeout(Integer.valueOf(properties.getProperty(SESSION_TIMEOUT, "30"))); + setMaxFormContentSize(Integer.valueOf(properties.getProperty(REQUEST_CONTENT_SIZE_KEY, String.valueOf(DEFAULT_REQUEST_CONTENT_SIZE)))); } catch (final IOException e) { LOG.warn("Failed to read configuration from server.properties file", e); } finally { @@ -186,6 +191,7 @@ public class ServerDaemon implements Daemon { // Extra config options server.setStopAtShutdown(true); + server.setAttribute(ContextHandler.MAX_FORM_CONTENT_SIZE_KEY, maxFormContentSize); // HTTPS Connector createHttpsConnector(httpConfig); @@ -257,6 +263,7 @@ public class ServerDaemon implements Daemon { final WebAppContext webApp = new WebAppContext(); webApp.setContextPath(contextPath); webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false"); + webApp.setMaxFormContentSize(maxFormContentSize); // GZIP handler final GzipHandler gzipHandler = new GzipHandler(); @@ -355,4 +362,8 @@ public class ServerDaemon implements Daemon { public void setSessionTimeout(int sessionTimeout) { this.sessionTimeout = sessionTimeout; } + + public void setMaxFormContentSize(int maxFormContentSize) { + this.maxFormContentSize = maxFormContentSize; + } }