Fix maxFileSize environment variable support (#5542) (#5655)

## Description

Fixes #5542

This PR adds support for environment variables to configure the file
upload limit, which was previously ignored.

## Changes

- **Added support for `SYSTEMFILEUPLOADLIMIT` environment variable**:
Accepts format like "100MB", "1GB", etc.
- **Added support for `SYSTEM_MAXFILESIZE` environment variable**:
Accepts number in MB (e.g., "100" for 100MB)
- **Initialize `fileUploadLimit` from environment variables**: Added
`@PostConstruct` method in `ApplicationProperties` to read env vars and
set `fileUploadLimit` if not already set in settings.yml
- **Created `MultipartConfiguration`**: New configuration class that
syncs Spring multipart settings with `fileUploadLimit` from settings.yml
or environment variables
- **Updated `application.properties`**: Added documentation about
environment variable support

## How it works

1. On startup,
`ApplicationProperties.initializeFileUploadLimitFromEnv()` checks for
`SYSTEMFILEUPLOADLIMIT` or `SYSTEM_MAXFILESIZE` environment variables
2. If found and `fileUploadLimit` is not set in settings.yml, it sets
the value
3. `MultipartConfiguration` reads the `fileUploadLimit` via
`UploadLimitService` and configures Spring multipart settings
accordingly
4. Users can also still use `SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE` and
`SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE` directly

## Testing

Set environment variables:
- `SYSTEMFILEUPLOADLIMIT=10MB` or
- `SYSTEM_MAXFILESIZE=10`

The `fileUploadLimit` in settings.yml should be populated and multipart
limits should be respected.
This commit is contained in:
PandaMan
2026-02-07 01:20:05 +02:00
committed by GitHub
parent 00a9174939
commit cc1931fa75
3 changed files with 123 additions and 2 deletions

View File

@@ -35,6 +35,8 @@ import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import jakarta.annotation.PostConstruct;
import stirling.software.common.configuration.InstallationPathConfig;
import stirling.software.common.configuration.YamlPropertySourceFactory;
import stirling.software.common.model.exception.UnsupportedProviderException;
@@ -98,6 +100,46 @@ public class ApplicationProperties {
return propertySource;
}
/**
* Initialize fileUploadLimit from environment variables if not set in settings.yml.
* Supports SYSTEMFILEUPLOADLIMIT (format: "100MB") and SYSTEM_MAXFILESIZE (format: "100" in MB).
*/
@PostConstruct
public void initializeFileUploadLimitFromEnv() {
// Only override if fileUploadLimit is not already set in settings.yml
if (system.getFileUploadLimit() == null || system.getFileUploadLimit().isEmpty()) {
String fileUploadLimit = null;
// Check SYSTEMFILEUPLOADLIMIT first (format: "100MB", "1GB", etc.)
String systemFileUploadLimit = java.lang.System.getenv("SYSTEMFILEUPLOADLIMIT");
if (systemFileUploadLimit != null && !systemFileUploadLimit.trim().isEmpty()) {
fileUploadLimit = systemFileUploadLimit.trim();
log.info("Setting fileUploadLimit from SYSTEMFILEUPLOADLIMIT: {}", fileUploadLimit);
} else {
// Check SYSTEM_MAXFILESIZE (format: number in MB, e.g., "100")
String systemMaxFileSize = java.lang.System.getenv("SYSTEM_MAXFILESIZE");
if (systemMaxFileSize != null && !systemMaxFileSize.trim().isEmpty()) {
try {
// Validate it's a number
long sizeInMB = Long.parseLong(systemMaxFileSize.trim());
if (sizeInMB > 0 && sizeInMB <= 999) {
fileUploadLimit = sizeInMB + "MB";
log.info("Setting fileUploadLimit from SYSTEM_MAXFILESIZE: {}MB", sizeInMB);
} else {
log.warn("SYSTEM_MAXFILESIZE value {} is out of valid range (1-999), ignoring", sizeInMB);
}
} catch (NumberFormatException e) {
log.warn("SYSTEM_MAXFILESIZE value '{}' is not a valid number, ignoring", systemMaxFileSize);
}
}
}
if (fileUploadLimit != null) {
system.setFileUploadLimit(fileUploadLimit);
}
}
}
@Data
public static class AutoPipeline {
private String outputFolder;

View File

@@ -0,0 +1,76 @@
package stirling.software.SPDF.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.util.unit.DataSize;
import jakarta.servlet.MultipartConfigElement;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.controller.web.UploadLimitService;
/**
* Configuration for Spring multipart file upload settings.
* Synchronizes multipart limits with fileUploadLimit from settings.yml or environment variables
* (SYSTEMFILEUPLOADLIMIT or SYSTEM_MAXFILESIZE).
*/
@Configuration
@Slf4j
public class MultipartConfiguration {
@Autowired private UploadLimitService uploadLimitService;
/**
* Creates MultipartConfigElement that respects fileUploadLimit from settings.yml
* or environment variables (SYSTEMFILEUPLOADLIMIT or SYSTEM_MAXFILESIZE).
* Depends on ApplicationProperties being initialized so @PostConstruct has run.
*/
@Bean
@DependsOn("applicationProperties")
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// First check if SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE is explicitly set
String springMaxFileSize = java.lang.System.getenv("SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE");
long uploadLimitBytes = 0;
if (springMaxFileSize != null && !springMaxFileSize.trim().isEmpty()) {
// Parse the Spring property format (e.g., "2000MB")
try {
DataSize dataSize = DataSize.parse(springMaxFileSize.trim());
uploadLimitBytes = dataSize.toBytes();
log.info("Using SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE: {}", springMaxFileSize);
} catch (Exception e) {
log.warn("Failed to parse SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE: {}", springMaxFileSize, e);
}
}
// If not set via Spring property, use UploadLimitService which reads from
// fileUploadLimit (set from SYSTEMFILEUPLOADLIMIT/SYSTEM_MAXFILESIZE or settings.yml)
if (uploadLimitBytes == 0) {
uploadLimitBytes = uploadLimitService.getUploadLimit();
if (uploadLimitBytes > 0) {
log.info(
"Using fileUploadLimit setting: {}",
uploadLimitService.getReadableUploadLimit());
}
}
// If still no limit, use default of 2000MB
if (uploadLimitBytes == 0) {
uploadLimitBytes = 2000L * 1024 * 1024; // 2000MB default
log.info("Using default multipart file upload limit: 2000MB");
}
// Set max file size and max request size to the same value
factory.setMaxFileSize(DataSize.ofBytes(uploadLimitBytes));
factory.setMaxRequestSize(DataSize.ofBytes(uploadLimitBytes));
return factory.createMultipartConfig();
}
}

View File

@@ -26,8 +26,11 @@ spring.mvc.problemdetails.enabled=true
#logging.level.org.springframework=DEBUG
#logging.level.org.springframework.security=DEBUG
spring.servlet.multipart.max-file-size=2000MB
spring.servlet.multipart.max-request-size=2000MB
# Multipart file size limits
# Can be set via environment variables: SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE and SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE
# Or via SYSTEMFILEUPLOADLIMIT/SYSTEM_MAXFILESIZE which will also set fileUploadLimit in settings.yml
spring.servlet.multipart.max-file-size=${SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE:2000MB}
spring.servlet.multipart.max-request-size=${SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE:2000MB}
server.servlet.session.tracking-modes=cookie
server.servlet.context-path=${SYSTEM_ROOTURIPATH:/}
spring.devtools.restart.enabled=true