Skip to content

Commit bf85d1b

Browse files
authored
Merge pull request #5195 from square/fix-content-length-of-http2-response-body
Correctly calculate HTTP2 response body size
2 parents 62cf6c2 + 0d8c2ec commit bf85d1b

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

okhttp/src/main/java/okhttp3/internal/http2/Http2ExchangeCodec.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import okhttp3.internal.http.ExchangeCodec
2727
import okhttp3.internal.http.RequestLine
2828
import okhttp3.internal.http.StatusLine
2929
import okhttp3.internal.http.StatusLine.Companion.HTTP_CONTINUE
30+
import okhttp3.internal.http.promisesBody
3031
import okhttp3.internal.http2.Header.Companion.RESPONSE_STATUS_UTF8
3132
import okhttp3.internal.http2.Header.Companion.TARGET_AUTHORITY
3233
import okhttp3.internal.http2.Header.Companion.TARGET_AUTHORITY_UTF8
@@ -106,7 +107,10 @@ class Http2ExchangeCodec(
106107
}
107108

108109
override fun reportedContentLength(response: Response): Long {
109-
return response.headersContentLength()
110+
return when {
111+
!response.promisesBody() -> 0L
112+
else -> response.headersContentLength()
113+
}
110114
}
111115

112116
override fun openResponseBodySource(response: Response): Source {

okhttp/src/test/java/okhttp3/internal/http2/HttpOverHttp2Test.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,53 @@ public HttpOverHttp2Test(Protocol protocol) {
178178
(server.getHostName() + ":" + server.getPort()));
179179
}
180180

181+
@Test public void get204Response() throws Exception {
182+
MockResponse responseWithoutBody = new MockResponse();
183+
responseWithoutBody.status("HTTP/1.1 204");
184+
responseWithoutBody.removeHeader("Content-Length");
185+
server.enqueue(responseWithoutBody);
186+
187+
Call call = client.newCall(new Request.Builder()
188+
.url(server.url("/foo"))
189+
.build());
190+
Response response = call.execute();
191+
192+
// Body contains nothing.
193+
assertThat(response.body().bytes().length).isEqualTo(0);
194+
assertThat(response.body().contentLength()).isEqualTo(0);
195+
196+
// Content-Length header doesn't exist in a 204 response.
197+
assertThat(response.header("content-length")).isNull();
198+
199+
assertThat(response.code()).isEqualTo(204);
200+
201+
RecordedRequest request = server.takeRequest();
202+
assertThat(request.getRequestLine()).isEqualTo("GET /foo HTTP/1.1");
203+
}
204+
205+
@Test public void head() throws Exception {
206+
MockResponse mockResponse = new MockResponse().setHeader("Content-Length", 5);
207+
mockResponse.status("HTTP/1.1 200");
208+
server.enqueue(mockResponse);
209+
210+
Call call = client.newCall(new Request.Builder()
211+
.head()
212+
.url(server.url("/foo"))
213+
.build());
214+
215+
Response response = call.execute();
216+
217+
// Body contains nothing.
218+
assertThat(response.body().bytes().length).isEqualTo(0);
219+
assertThat(response.body().contentLength()).isEqualTo(0);
220+
221+
// Content-Length header stays correctly.
222+
assertThat(response.header("content-length")).isEqualTo("5");
223+
224+
RecordedRequest request = server.takeRequest();
225+
assertThat(request.getRequestLine()).isEqualTo("HEAD /foo HTTP/1.1");
226+
}
227+
181228
@Test public void emptyResponse() throws IOException {
182229
server.enqueue(new MockResponse());
183230

0 commit comments

Comments
 (0)