Affects: spring-web 6.1.10
Hello, we're observing an issue with ShallowEtagHeaderFilter when the downloaded file is bigger than 2Gb, the ContentCachingResponseWrapper throws a NumberFormatException due to int overflow when trying to save the Content-Length value.
Is it possible to update this class to support long
values for the Content-Length value?
Here is a stack trace of an exception
java.lang.NumberFormatException: For input string: "2148532224"
at java.base/java.lang.NumberFormatException.forInputString(Unknown Source)
at java.base/java.lang.Integer.parseInt(Unknown Source)
at java.base/java.lang.Integer.valueOf(Unknown Source)
at org.springframework.web.util.ContentCachingResponseWrapper.addHeader(ContentCachingResponseWrapper.java:173)
at jakarta.servlet.http.HttpServletResponseWrapper.addHeader(HttpServletResponseWrapper.java:141)
.......
// Configuration.java
@Bean
public ShallowEtagHeaderFilter shallowEtagHeaderFilter() {
return new ShallowEtagHeaderFilter();
}
and the sample code we use in @RestController
// Controller.java
return ResponseEntity.ok()
.eTag(file.getEtag())
.contentLength(file.getLength()) // long
.header(HttpHeaders.CONTENT_TYPE, file.getContentType())
.build();
It would be great If you could share suggestions on how to avoid this issue when content length overflows int
.
Comment From: bclozel
@geobreze we'll look into this, thanks for the report. Are you aware that using the ShallowEtagHeaderFilter
is effectively caching the entire response in memory? This is putting huge pressure on your GC and I wouldn't advise this approach if your application is serving very large files.
Instead, I would advise using the static resources features with the strategy that fits your use case.
Comment From: geobreze
Hi @bclozel, thanks for pointing this out, will take a look into it.
ShallowEtagHeaderFilter is effectively caching the entire response in memory
Is there an option not to cache the response if etag is already provided in the controller?
Comment From: bclozel
Is there an option not to cache the response if etag is already provided in the controller?
This is already the case for this filter: https://github.com/spring-projects/spring-framework/blob/main/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java#L218
Comment From: snicoll
ContentCachingResponseWrapper
is really designed to limit to 2GB given it's buffering the content in memory. We have a dedicated exception that states as much: https://github.com/spring-projects/spring-framework/blob/92385418ae62a52046f4fb73aadafddf47c19ee6/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java#L143-L146
We'd like to revisit this class so that it throws the exception consistently.