Skip to content

Commit 736af46

Browse files
committed
ContentCachingResponseWrapper skips contentLength for chunked responses
Closes gh-26182
1 parent a495bd6 commit 736af46

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import javax.servlet.http.HttpServletResponse;
2828
import javax.servlet.http.HttpServletResponseWrapper;
2929

30+
import org.springframework.http.HttpHeaders;
3031
import org.springframework.lang.Nullable;
3132
import org.springframework.util.FastByteArrayOutputStream;
3233

@@ -209,7 +210,9 @@ protected void copyBodyToResponse(boolean complete) throws IOException {
209210
if (this.content.size() > 0) {
210211
HttpServletResponse rawResponse = (HttpServletResponse) getResponse();
211212
if ((complete || this.contentLength != null) && !rawResponse.isCommitted()) {
212-
rawResponse.setContentLength(complete ? this.content.size() : this.contentLength);
213+
if (rawResponse.getHeader(HttpHeaders.TRANSFER_ENCODING) == null) {
214+
rawResponse.setContentLength(complete ? this.content.size() : this.contentLength);
215+
}
213216
this.contentLength = null;
214217
}
215218
this.content.writeTo(rawResponse.getOutputStream());
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2002-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.web.filter;
17+
18+
import java.nio.charset.StandardCharsets;
19+
20+
import javax.servlet.http.HttpServletResponse;
21+
22+
import org.junit.jupiter.api.Test;
23+
24+
import org.springframework.http.HttpHeaders;
25+
import org.springframework.util.FileCopyUtils;
26+
import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
27+
import org.springframework.web.util.ContentCachingResponseWrapper;
28+
29+
import static org.assertj.core.api.Assertions.assertThat;
30+
31+
/**
32+
* Unit tests for {@link ContentCachingResponseWrapper}.
33+
* @author Rossen Stoyanchev
34+
*/
35+
public class ContentCachingResponseWrapperTests {
36+
37+
@Test
38+
void copyBodyToResponse() throws Exception {
39+
byte[] responseBody = "Hello World".getBytes(StandardCharsets.UTF_8);
40+
MockHttpServletResponse response = new MockHttpServletResponse();
41+
42+
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
43+
responseWrapper.setStatus(HttpServletResponse.SC_OK);
44+
FileCopyUtils.copy(responseBody, responseWrapper.getOutputStream());
45+
responseWrapper.copyBodyToResponse();
46+
47+
assertThat(response.getStatus()).isEqualTo(200);
48+
assertThat(response.getContentLength() > 0).isTrue();
49+
assertThat(response.getContentAsByteArray()).isEqualTo(responseBody);
50+
}
51+
52+
@Test
53+
void copyBodyToResponseWithTransferEncoding() throws Exception {
54+
byte[] responseBody = "6\r\nHello 5\r\nWorld0\r\n\r\n".getBytes(StandardCharsets.UTF_8);
55+
MockHttpServletResponse response = new MockHttpServletResponse();
56+
57+
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
58+
responseWrapper.setStatus(HttpServletResponse.SC_OK);
59+
responseWrapper.setHeader(HttpHeaders.TRANSFER_ENCODING, "chunked");
60+
FileCopyUtils.copy(responseBody, responseWrapper.getOutputStream());
61+
responseWrapper.copyBodyToResponse();
62+
63+
assertThat(response.getStatus()).isEqualTo(200);
64+
assertThat(response.getHeader(HttpHeaders.TRANSFER_ENCODING)).isEqualTo("chunked");
65+
assertThat(response.getHeader(HttpHeaders.CONTENT_LENGTH)).isNull();
66+
assertThat(response.getContentAsByteArray()).isEqualTo(responseBody);
67+
}
68+
69+
}

0 commit comments

Comments
 (0)