diff --git a/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java b/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java index 06ee23e167..f1a85fb943 100644 --- a/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java +++ b/spring-web/src/main/java/org/springframework/web/client/HttpMessageConverterExtractor.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; @@ -122,9 +123,14 @@ public class HttpMessageConverterExtractor implements ResponseExtractor { } /** - * Indicates whether the given response has a message body.

Default implementation - * returns {@code false} for a response status of {@code 204} or {@code 304}, or a {@code - * Content-Length} of {@code 0}. + * Indicates whether the given response has a message body. + *

Default implementation returns {@code false} for: + *

* * @param response the response to check for a message body * @return {@code true} if the response has a body, {@code false} otherwise @@ -136,8 +142,19 @@ public class HttpMessageConverterExtractor implements ResponseExtractor { responseStatus == HttpStatus.NOT_MODIFIED) { return false; } - long contentLength = response.getHeaders().getContentLength(); - return contentLength != 0; + HttpHeaders headers = response.getHeaders(); + long contentLength = headers.getContentLength(); + if(contentLength == 0) { + return false; + } + boolean chunked = headers.containsKey(HttpHeaders.TRANSFER_ENCODING) + && headers.get(HttpHeaders.TRANSFER_ENCODING).contains("chunked"); + boolean closed = headers.containsKey(HttpHeaders.CONNECTION) + && headers.getConnection().contains("close"); + if(!chunked && contentLength == -1 && closed) { + return false; + } + return true; } } diff --git a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java index 406adbc3e8..8a195577f0 100644 --- a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java @@ -108,7 +108,7 @@ public class HttpMessageConverterExtractorTests { assertEquals(expected, result); } - @Test + @Test(expected = RestClientException.class) @SuppressWarnings("unchecked") public void cannotRead() throws IOException { HttpMessageConverter converter = mock(HttpMessageConverter.class); @@ -122,13 +122,22 @@ public class HttpMessageConverterExtractorTests { given(response.getHeaders()).willReturn(responseHeaders); given(converter.canRead(String.class, contentType)).willReturn(false); - try { - extractor.extractData(response); - fail("RestClientException expected"); - } - catch (RestClientException expected) { - // expected - } + extractor.extractData(response); + } + + @Test + public void connectionClose() throws IOException { + HttpMessageConverter converter = mock(HttpMessageConverter.class); + List> converters = new ArrayList>(); + converters.add(converter); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setConnection("close"); + extractor = new HttpMessageConverterExtractor(String.class, createConverterList(converter)); + given(response.getStatusCode()).willReturn(HttpStatus.OK); + given(response.getHeaders()).willReturn(responseHeaders); + + Object result = extractor.extractData(response); + assertNull(result); } @Test