Skip to content

Introduce getContentAsString() in ContentCachingRequestWrapper #30709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
Expand Down Expand Up @@ -196,6 +197,14 @@ public byte[] getContentAsByteArray() {
return this.cachedContent.toByteArray();
}

/**
* Return the cached request content as a String. The Charset used to decode
* the cached content is the same as returned by getCharacterEncoding.
*/
public String getContentAsString() {
return this.cachedContent.toString(Charset.forName(getCharacterEncoding()));
}

/**
* Template method for handling a content overflow: specifically, a request
* body being read that exceeds the specified content cache limit.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

package org.springframework.web.util;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import org.junit.jupiter.api.Test;

import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;

import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -35,7 +35,7 @@ public class ContentCachingRequestWrapperTests {

protected static final String FORM_CONTENT_TYPE = MediaType.APPLICATION_FORM_URLENCODED_VALUE;

protected static final String CHARSET = StandardCharsets.UTF_8.name();
protected static final Charset CHARSET = StandardCharsets.UTF_8;

protected static final String GET = HttpMethod.GET.name();

Expand All @@ -49,30 +49,32 @@ public class ContentCachingRequestWrapperTests {
@Test
void cachedContent() throws Exception {
this.request.setMethod(GET);
this.request.setCharacterEncoding(CHARSET);
this.request.setCharacterEncoding(CHARSET.name());
this.request.setContent("Hello World".getBytes(CHARSET));

ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request);
byte[] response = FileCopyUtils.copyToByteArray(wrapper.getInputStream());
byte[] response = wrapper.getInputStream().readAllBytes();
assertThat(wrapper.getContentAsByteArray()).isEqualTo(response);
assertThat(wrapper.getContentAsString()).isEqualTo("Hello World");
}

@Test
void cachedContentWithLimit() throws Exception {
this.request.setMethod(GET);
this.request.setCharacterEncoding(CHARSET);
this.request.setCharacterEncoding(CHARSET.name());
this.request.setContent("Hello World".getBytes(CHARSET));

ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request, CONTENT_CACHE_LIMIT);
byte[] response = FileCopyUtils.copyToByteArray(wrapper.getInputStream());
byte[] response = wrapper.getInputStream().readAllBytes();
assertThat(response).isEqualTo("Hello World".getBytes(CHARSET));
assertThat(wrapper.getContentAsByteArray()).isEqualTo("Hel".getBytes(CHARSET));
assertThat(wrapper.getContentAsString()).isEqualTo("Hel");
}

@Test
void cachedContentWithOverflow() throws Exception {
this.request.setMethod(GET);
this.request.setCharacterEncoding(CHARSET);
this.request.setCharacterEncoding(CHARSET.name());
this.request.setContent("Hello World".getBytes(CHARSET));

ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request, CONTENT_CACHE_LIMIT) {
Expand All @@ -82,39 +84,40 @@ protected void handleContentOverflow(int contentCacheLimit) {
}
};

assertThatIllegalStateException().isThrownBy(() ->
FileCopyUtils.copyToByteArray(wrapper.getInputStream()))
assertThatIllegalStateException().isThrownBy(() -> wrapper.getInputStream().readAllBytes())
.withMessage("3");
}

@Test
void requestParams() throws Exception {
this.request.setMethod(POST);
this.request.setContentType(FORM_CONTENT_TYPE);
this.request.setCharacterEncoding(CHARSET);
this.request.setCharacterEncoding(CHARSET.name());
this.request.setParameter("first", "value");
this.request.setParameter("second", "foo", "bar");

ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request);
// getting request parameters will consume the request body
assertThat(wrapper.getParameterMap().isEmpty()).isFalse();
assertThat(new String(wrapper.getContentAsByteArray())).isEqualTo("first=value&second=foo&second=bar");
assertThat(wrapper.getContentAsString()).isEqualTo("first=value&second=foo&second=bar");
// SPR-12810 : inputstream body should be consumed
assertThat(new String(FileCopyUtils.copyToByteArray(wrapper.getInputStream()))).isEmpty();
assertThat(new String(wrapper.getInputStream().readAllBytes())).isEmpty();
}

@Test // SPR-12810
void inputStreamFormPostRequest() throws Exception {
this.request.setMethod(POST);
this.request.setContentType(FORM_CONTENT_TYPE);
this.request.setCharacterEncoding(CHARSET);
this.request.setCharacterEncoding(CHARSET.name());
this.request.setParameter("first", "value");
this.request.setParameter("second", "foo", "bar");

ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(this.request);

byte[] response = FileCopyUtils.copyToByteArray(wrapper.getInputStream());
byte[] response = wrapper.getInputStream().readAllBytes();
assertThat(wrapper.getContentAsByteArray()).isEqualTo(response);
assertThat(wrapper.getContentAsString()).isEqualTo(new String(response, CHARSET));
}

}