Skip to content

Commit

Permalink
Support preset headers again in ContentCachingResponseWrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrannen committed Feb 23, 2024
1 parent f59c402 commit f618c01
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
* <p>Used e.g. by {@link org.springframework.web.filter.ShallowEtagHeaderFilter}.
*
* @author Juergen Hoeller
* @author Arjen Poutsma
* @author Sam Brannen
* @since 4.1.3
* @see ContentCachingRequestWrapper
*/
Expand Down Expand Up @@ -154,20 +156,21 @@ public void setContentType(String type) {
@Override
@Nullable
public String getContentType() {
return this.contentType;
if (this.contentType != null) {
return this.contentType;
}
return super.getContentType();
}

@Override
public boolean containsHeader(String name) {
if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) {
return this.contentLength != null;
if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name) && this.contentLength != null) {
return true;
}
else if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) {
return this.contentType != null;
}
else {
return super.containsHeader(name);
else if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) && this.contentType != null) {
return true;
}
return super.containsHeader(name);
}

@Override
Expand Down Expand Up @@ -219,29 +222,24 @@ public void addIntHeader(String name, int value) {
@Override
@Nullable
public String getHeader(String name) {
if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) {
return (this.contentLength != null) ? this.contentLength.toString() : null;
if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name) && this.contentLength != null) {
return this.contentLength.toString();
}
else if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) {
else if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) && this.contentType != null) {
return this.contentType;
}
else {
return super.getHeader(name);
}
return super.getHeader(name);
}

@Override
public Collection<String> getHeaders(String name) {
if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name)) {
return this.contentLength != null ? Collections.singleton(this.contentLength.toString()) :
Collections.emptySet();
if (HttpHeaders.CONTENT_LENGTH.equalsIgnoreCase(name) && this.contentLength != null) {
return Collections.singleton(this.contentLength.toString());
}
else if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name)) {
return this.contentType != null ? Collections.singleton(this.contentType) : Collections.emptySet();
}
else {
return super.getHeaders(name);
else if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) && this.contentType != null) {
return Collections.singleton(this.contentType);
}
return super.getHeaders(name);
}

@Override
Expand Down Expand Up @@ -327,7 +325,7 @@ protected void copyBodyToResponse(boolean complete) throws IOException {
}
this.contentLength = null;
}
if (complete || this.contentType != null) {
if (this.contentType != null) {
rawResponse.setContentType(this.contentType);
this.contentType = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,24 @@
import java.nio.charset.StandardCharsets;

import jakarta.servlet.http.HttpServletResponse;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
import org.springframework.web.util.ContentCachingResponseWrapper;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.http.HttpHeaders.CONTENT_LENGTH;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;

/**
* Tests for {@link ContentCachingResponseWrapper}.
*
* @author Rossen Stoyanchev
* @author Sam Brannen
*/
class ContentCachingResponseWrapperTests {

Expand All @@ -50,6 +55,81 @@ void copyBodyToResponse() throws Exception {
assertThat(response.getContentAsByteArray()).isEqualTo(responseBody);
}

@Test
void copyBodyToResponseWithPresetHeaders() throws Exception {
String PUZZLE = "puzzle";
String ENIGMA = "enigma";
String NUMBER = "number";
String MAGIC = "42";

byte[] responseBody = "Hello World".getBytes(StandardCharsets.UTF_8);
String responseLength = Integer.toString(responseBody.length);
String contentType = MediaType.APPLICATION_JSON_VALUE;

MockHttpServletResponse response = new MockHttpServletResponse();
response.setContentType(contentType);
response.setContentLength(999);
response.setHeader(PUZZLE, ENIGMA);
response.setIntHeader(NUMBER, 42);

ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
responseWrapper.setStatus(HttpServletResponse.SC_OK);
assertThat(responseWrapper.getStatus()).isEqualTo(200);
assertThat(responseWrapper.getContentSize()).isZero();

assertThat(responseWrapper.getHeaderNames())
.containsExactlyInAnyOrder(PUZZLE, NUMBER, CONTENT_TYPE, CONTENT_LENGTH);

SoftAssertions.assertSoftly(softly -> {
softly.assertThat(responseWrapper.containsHeader(PUZZLE)).as(PUZZLE).isTrue();
softly.assertThat(responseWrapper.getHeader(PUZZLE)).as(PUZZLE).isEqualTo(ENIGMA);
softly.assertThat(responseWrapper.getHeaders(PUZZLE)).as(PUZZLE).containsExactly(ENIGMA);

softly.assertThat(responseWrapper.containsHeader(NUMBER)).as(NUMBER).isTrue();
softly.assertThat(responseWrapper.getHeader(NUMBER)).as(NUMBER).isEqualTo(MAGIC);
softly.assertThat(responseWrapper.getHeaders(NUMBER)).as(NUMBER).containsExactly(MAGIC);

softly.assertThat(responseWrapper.containsHeader(CONTENT_TYPE)).as(CONTENT_TYPE).isTrue();
softly.assertThat(responseWrapper.getHeader(CONTENT_TYPE)).as(CONTENT_TYPE).isEqualTo(contentType);
softly.assertThat(responseWrapper.getHeaders(CONTENT_TYPE)).as(CONTENT_TYPE).containsExactly(contentType);
softly.assertThat(responseWrapper.getContentType()).as(CONTENT_TYPE).isEqualTo(contentType);

softly.assertThat(responseWrapper.containsHeader(CONTENT_LENGTH)).as(CONTENT_LENGTH).isTrue();
softly.assertThat(responseWrapper.getHeader(CONTENT_LENGTH)).as(CONTENT_LENGTH).isEqualTo("999");
softly.assertThat(responseWrapper.getHeaders(CONTENT_LENGTH)).as(CONTENT_LENGTH).containsExactly("999");
});

FileCopyUtils.copy(responseBody, responseWrapper.getOutputStream());
responseWrapper.copyBodyToResponse();

assertThat(responseWrapper.getHeaderNames())
.containsExactlyInAnyOrder(PUZZLE, NUMBER, CONTENT_TYPE, CONTENT_LENGTH);

assertThat(response.getStatus()).isEqualTo(200);
assertThat(response.getContentType()).isEqualTo(contentType);
assertThat(response.getContentLength()).isEqualTo(responseBody.length);
assertThat(response.getContentAsByteArray()).isEqualTo(responseBody);
assertThat(response.getHeaderNames())
.containsExactlyInAnyOrder(PUZZLE, NUMBER, CONTENT_TYPE, CONTENT_LENGTH);

assertThat(response.containsHeader(PUZZLE)).as(PUZZLE).isTrue();
assertThat(response.getHeader(PUZZLE)).as(PUZZLE).isEqualTo(ENIGMA);
assertThat(response.getHeaders(PUZZLE)).as(PUZZLE).containsExactly(ENIGMA);

assertThat(response.containsHeader(NUMBER)).as(NUMBER).isTrue();
assertThat(response.getHeader(NUMBER)).as(NUMBER).isEqualTo(MAGIC);
assertThat(response.getHeaders(NUMBER)).as(NUMBER).containsExactly(MAGIC);

assertThat(response.containsHeader(CONTENT_TYPE)).as(CONTENT_TYPE).isTrue();
assertThat(response.getHeader(CONTENT_TYPE)).as(CONTENT_TYPE).isEqualTo(contentType);
assertThat(response.getHeaders(CONTENT_TYPE)).as(CONTENT_TYPE).containsExactly(contentType);
assertThat(response.getContentType()).as(CONTENT_TYPE).isEqualTo(contentType);

assertThat(response.containsHeader(CONTENT_LENGTH)).as(CONTENT_LENGTH).isTrue();
assertThat(response.getHeader(CONTENT_LENGTH)).as(CONTENT_LENGTH).isEqualTo(responseLength);
assertThat(response.getHeaders(CONTENT_LENGTH)).as(CONTENT_LENGTH).containsExactly(responseLength);
}

@Test
void copyBodyToResponseWithTransferEncoding() throws Exception {
byte[] responseBody = "6\r\nHello 5\r\nWorld0\r\n\r\n".getBytes(StandardCharsets.UTF_8);
Expand All @@ -63,7 +143,7 @@ void copyBodyToResponseWithTransferEncoding() throws Exception {

assertThat(response.getStatus()).isEqualTo(200);
assertThat(response.getHeader(HttpHeaders.TRANSFER_ENCODING)).isEqualTo("chunked");
assertThat(response.getHeader(HttpHeaders.CONTENT_LENGTH)).isNull();
assertThat(response.getHeader(CONTENT_LENGTH)).isNull();
assertThat(response.getContentAsByteArray()).isEqualTo(responseBody);
}

Expand Down

0 comments on commit f618c01

Please sign in to comment.