Skip to content

Commit 1164ac3

Browse files
committed
ContentCachingRequestWrapper requires cacheLimit
Closes gh-33914
1 parent b027cf1 commit 1164ac3

File tree

2 files changed

+49
-52
lines changed

2 files changed

+49
-52
lines changed

spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java

+17-14
Original file line numberDiff line numberDiff line change
@@ -71,31 +71,34 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper {
7171
/**
7272
* Create a new ContentCachingRequestWrapper for the given servlet request.
7373
* @param request the original servlet request
74+
* @param cacheLimit the maximum number of bytes to cache per request;
75+
* no limit is set if the value is 0 or less. It is recommended to set a
76+
* concrete limit in order to avoid using too much memory.
77+
* @since 4.3.6
78+
* @see #handleContentOverflow(int)
7479
*/
75-
public ContentCachingRequestWrapper(HttpServletRequest request) {
80+
public ContentCachingRequestWrapper(HttpServletRequest request, int cacheLimit) {
7681
super(request);
7782
int contentLength = request.getContentLength();
78-
this.cachedContent = (contentLength > 0) ? new FastByteArrayOutputStream(contentLength) : new FastByteArrayOutputStream();
79-
this.contentCacheLimit = null;
83+
this.cachedContent = (contentLength > 0 ?
84+
new FastByteArrayOutputStream((cacheLimit > 0 ? Math.min(contentLength, cacheLimit) : contentLength)) :
85+
new FastByteArrayOutputStream());
86+
this.contentCacheLimit = (cacheLimit > 0 ? cacheLimit : null);
8087
}
8188

8289
/**
8390
* Create a new ContentCachingRequestWrapper for the given servlet request.
8491
* @param request the original servlet request
85-
* @param contentCacheLimit the maximum number of bytes to cache per request
86-
* @since 4.3.6
87-
* @see #handleContentOverflow(int)
92+
* @deprecated in favor of {@link #ContentCachingRequestWrapper(HttpServletRequest, int)}
93+
* in order to explicitly choose the cache limit
8894
*/
89-
public ContentCachingRequestWrapper(HttpServletRequest request, int contentCacheLimit) {
95+
@Deprecated(since = "6.2.1", forRemoval = true)
96+
public ContentCachingRequestWrapper(HttpServletRequest request) {
9097
super(request);
9198
int contentLength = request.getContentLength();
92-
if (contentLength > 0) {
93-
this.cachedContent = new FastByteArrayOutputStream(Math.min(contentLength, contentCacheLimit));
94-
}
95-
else {
96-
this.cachedContent = new FastByteArrayOutputStream();
97-
}
98-
this.contentCacheLimit = contentCacheLimit;
99+
this.cachedContent = (contentLength > 0 ?
100+
new FastByteArrayOutputStream(contentLength) : new FastByteArrayOutputStream());
101+
this.contentCacheLimit = null;
99102
}
100103

101104

spring-web/src/test/java/org/springframework/web/util/ContentCachingRequestWrapperTests.java

+32-38
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@
1616

1717
package org.springframework.web.util;
1818

19-
import java.io.UnsupportedEncodingException;
20-
import java.nio.charset.StandardCharsets;
21-
2219
import org.junit.jupiter.api.Test;
2320

2421
import org.springframework.http.HttpMethod;
2522
import org.springframework.http.MediaType;
2623
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
2724

25+
import static java.nio.charset.StandardCharsets.UTF_8;
2826
import static org.assertj.core.api.Assertions.assertThat;
2927
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
3028

@@ -38,68 +36,59 @@ class ContentCachingRequestWrapperTests {
3836

3937
protected static final String FORM_CONTENT_TYPE = MediaType.APPLICATION_FORM_URLENCODED_VALUE;
4038

41-
protected static final String CHARSET = StandardCharsets.UTF_8.name();
42-
43-
protected static final String GET = HttpMethod.GET.name();
44-
45-
protected static final String POST = HttpMethod.POST.name();
46-
47-
protected static final int CONTENT_CACHE_LIMIT = 3;
48-
4939

5040
@Test
51-
void cachedContentToByteArrayWithNoRead() throws Exception {
52-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello"));
41+
void cachedContentToByteArrayWithNoRead() {
42+
ContentCachingRequestWrapper wrapper = createGetRequest("Hello", -1);
5343
assertThat(wrapper.getContentAsByteArray()).isEmpty();
5444
}
5545

5646
@Test
57-
void cachedContentToStringWithNoRead() throws Exception {
58-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello"));
47+
void cachedContentToStringWithNoRead() {
48+
ContentCachingRequestWrapper wrapper = createGetRequest("Hello", -1);
5949
assertThat(wrapper.getContentAsString()).isEqualTo("");
6050
}
6151

6252
@Test
6353
void cachedContentToByteArray() throws Exception {
64-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello World"));
54+
ContentCachingRequestWrapper wrapper = createGetRequest("Hello World", -1);
6555
byte[] response = wrapper.getInputStream().readAllBytes();
6656
assertThat(wrapper.getContentAsByteArray()).isEqualTo(response);
6757
}
6858

6959
@Test
7060
void cachedContentToString() throws Exception {
71-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello World"));
61+
ContentCachingRequestWrapper wrapper = createGetRequest("Hello World", -1);
7262
byte[] response = wrapper.getInputStream().readAllBytes();
73-
assertThat(wrapper.getContentAsString()).isEqualTo(new String(response, CHARSET));
63+
assertThat(wrapper.getContentAsString()).isEqualTo(new String(response, UTF_8));
7464
}
7565

7666
@Test
7767
void cachedContentToByteArrayWithLimit() throws Exception {
78-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello World"), CONTENT_CACHE_LIMIT);
68+
ContentCachingRequestWrapper wrapper = createGetRequest("Hello World", 3);
7969
byte[] response = wrapper.getInputStream().readAllBytes();
80-
assertThat(response).isEqualTo("Hello World".getBytes(CHARSET));
81-
assertThat(wrapper.getContentAsByteArray()).isEqualTo("Hel".getBytes(CHARSET));
70+
assertThat(response).isEqualTo("Hello World".getBytes(UTF_8));
71+
assertThat(wrapper.getContentAsByteArray()).isEqualTo("Hel".getBytes(UTF_8));
8272
}
8373

8474
@Test
8575
void cachedContentToStringWithLimit() throws Exception {
86-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello World"), CONTENT_CACHE_LIMIT);
76+
ContentCachingRequestWrapper wrapper = createGetRequest("Hello World", 3);
8777
byte[] response = wrapper.getInputStream().readAllBytes();
88-
assertThat(response).isEqualTo("Hello World".getBytes(CHARSET));
89-
assertThat(wrapper.getContentAsString()).isEqualTo(new String("Hel".getBytes(CHARSET), CHARSET));
78+
assertThat(response).isEqualTo("Hello World".getBytes(UTF_8));
79+
assertThat(wrapper.getContentAsString()).isEqualTo(new String("Hel".getBytes(UTF_8), UTF_8));
9080
}
9181

9282
@Test
93-
void shouldNotAllocateMoreThanCacheLimit() throws Exception {
94-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello World"), CONTENT_CACHE_LIMIT);
95-
assertThat(wrapper).extracting("cachedContent.initialBlockSize").isEqualTo(CONTENT_CACHE_LIMIT);
83+
void shouldNotAllocateMoreThanCacheLimit() {
84+
ContentCachingRequestWrapper wrapper = createGetRequest("Hello World", 3);
85+
assertThat(wrapper).extracting("cachedContent.initialBlockSize").isEqualTo(3);
9686
}
9787

9888

9989
@Test
100-
void cachedContentWithOverflow() throws Exception {
101-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(
102-
createGetRequest("Hello World"), CONTENT_CACHE_LIMIT) {
90+
void cachedContentWithOverflow() {
91+
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(createGetRequest("Hello World"), 3) {
10392
@Override
10493
protected void handleContentOverflow(int contentCacheLimit) {
10594
throw new IllegalStateException(String.valueOf(contentCacheLimit));
@@ -117,7 +106,7 @@ void requestParams() throws Exception {
117106
request.setParameter("first", "value");
118107
request.setParameter("second", "foo", "bar");
119108

120-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request);
109+
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request, -1);
121110
// getting request parameters will consume the request body
122111
assertThat(wrapper.getParameterMap()).isNotEmpty();
123112
assertThat(new String(wrapper.getContentAsByteArray())).isEqualTo("first=value&second=foo&second=bar");
@@ -131,25 +120,30 @@ void inputStreamFormPostRequest() throws Exception {
131120
request.setParameter("first", "value");
132121
request.setParameter("second", "foo", "bar");
133122

134-
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request);
123+
ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request, -1);
135124

136125
byte[] response = wrapper.getInputStream().readAllBytes();
137126
assertThat(wrapper.getContentAsByteArray()).isEqualTo(response);
138127
}
139128

140-
private MockHttpServletRequest createGetRequest(String content) throws UnsupportedEncodingException {
129+
private ContentCachingRequestWrapper createGetRequest(String content, int cacheLimit) {
130+
return new ContentCachingRequestWrapper(createGetRequest(content), cacheLimit);
131+
}
132+
133+
134+
private MockHttpServletRequest createGetRequest(String content) {
141135
MockHttpServletRequest request = new MockHttpServletRequest();
142-
request.setMethod(GET);
143-
request.setCharacterEncoding(CHARSET);
144-
request.setContent(content.getBytes(CHARSET));
136+
request.setMethod(HttpMethod.GET.name());
137+
request.setCharacterEncoding(UTF_8);
138+
request.setContent(content.getBytes(UTF_8));
145139
return request;
146140
}
147141

148142
private MockHttpServletRequest createPostRequest() {
149143
MockHttpServletRequest request = new MockHttpServletRequest();
150-
request.setMethod(POST);
144+
request.setMethod(HttpMethod.POST.name());
151145
request.setContentType(FORM_CONTENT_TYPE);
152-
request.setCharacterEncoding(CHARSET);
146+
request.setCharacterEncoding(UTF_8.name());
153147
return request;
154148
}
155149

0 commit comments

Comments
 (0)