From 0970b1dc7afaf100cf0b443a22bf582d7cc0a590 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 13 Dec 2023 16:40:53 +0100 Subject: [PATCH] Optimize ContentCachingRequestWrapper allocation This commit builds on top of changes made in gh-29775 and gh-31737. Before this change, we would allocate several byte arrays even in cases of known request size. This could decrease performance when getting the cached content as it requires merging several arrays and data is not colocated in memory. This change ensures that we create a `FastByteArrayOutputStream` instance with the known request size so that the first allocated segment can contain the entire content. If the request size is not know, we will default back on the default allocation size for the `FastByteArrayOutputStream`. Closes gh-31834 --- .../web/util/ContentCachingRequestWrapper.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java index 5a53f64c39c..95cb4d1f951 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java @@ -56,7 +56,7 @@ import org.springframework.util.FastByteArrayOutputStream; */ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { - private final FastByteArrayOutputStream cachedContent = new FastByteArrayOutputStream(); + private FastByteArrayOutputStream cachedContent; @Nullable private final Integer contentCacheLimit; @@ -74,6 +74,8 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { */ public ContentCachingRequestWrapper(HttpServletRequest request) { super(request); + int contentLength = request.getContentLength(); + this.cachedContent = (contentLength > 0) ? new FastByteArrayOutputStream(contentLength) : new FastByteArrayOutputStream(); this.contentCacheLimit = null; } @@ -86,6 +88,8 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { */ public ContentCachingRequestWrapper(HttpServletRequest request, int contentCacheLimit) { super(request); + int contentLength = request.getContentLength(); + this.cachedContent = (contentLength > 0) ? new FastByteArrayOutputStream(contentLength) : new FastByteArrayOutputStream(); this.contentCacheLimit = contentCacheLimit; }