From 63ffa710d6d9b8f5b6e615b7c7c92ff62f6c421a Mon Sep 17 00:00:00 2001 From: Ruslan Stelmachenko Date: Thu, 9 Sep 2021 01:43:20 +0300 Subject: [PATCH] Include all bytes of body in UnknownContentTypeException HttpMessageConverterExtractor uses MessageBodyClientHttpResponseWrapper which may read the first byte of the response stream to check if there is content. After that it is necessary to use the wrapper to get the full body. This commit ensures that when UnknownContentTypeException is raised it gets the body through the wrapper, or otherwise the first byte is missed if the InputStream is not markable. Closes gh-27374 --- .../client/HttpMessageConverterExtractor.java | 4 ++-- .../HttpMessageConverterExtractorTests.java | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) 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 771a444bd73..dc515cc91d6 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 @@ -122,8 +122,8 @@ public class HttpMessageConverterExtractor implements ResponseExtractor { } throw new UnknownContentTypeException(this.responseType, contentType, - response.getRawStatusCode(), response.getStatusText(), response.getHeaders(), - getResponseBody(response)); + responseWrapper.getRawStatusCode(), responseWrapper.getStatusText(), responseWrapper.getHeaders(), + getResponseBody(responseWrapper)); } /** 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 2374a0d9548..de86b8671de 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 @@ -38,6 +38,7 @@ import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.catchThrowableOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; @@ -194,4 +195,23 @@ public class HttpMessageConverterExtractorTests { .withCauseInstanceOf(HttpMessageNotReadableException.class); } + @Test + public void unknownContentTypeExceptionContainsCorrectResponseBody() throws IOException { + responseHeaders.setContentType(contentType); + given(response.getRawStatusCode()).willReturn(HttpStatus.OK.value()); + given(response.getHeaders()).willReturn(responseHeaders); + given(response.getBody()).willReturn(new ByteArrayInputStream("Foobar".getBytes()) { + @Override + public boolean markSupported() { + return false; + } + }); + given(converter.canRead(String.class, contentType)).willReturn(false); + + UnknownContentTypeException unknownContentTypeException = + catchThrowableOfType(() -> extractor.extractData(response), UnknownContentTypeException.class); + assertThat(unknownContentTypeException).isNotNull(); + assertThat(unknownContentTypeException.getResponseBodyAsString()).isEqualTo("Foobar"); + } + }