SimpleClientHttpResponse throws IOException when response body is empty and status code is >= 400 #33020
Description
Affects: Spring Versions >= 5.0.0, including 6.x.x, Java versions 8 and 21 (possibly others as well but these are the only ones I've looked at)
When using SimpleClientHttpRequestFactory
, the response has an empty body, and an error status code, then an IOException
is thrown when trying to read the response body. I think the expected behavior would be that an empty input stream would be returned instead of an IOException
being thrown.
This causes an issue within a ClientHttpRequestInterceptor
which has to accommodate this by handling the IOException.
Resolution
Instead of doing a null check on the errorStream
, check the response status and use the appropriate stream. Below snippet is from the javadoc for HttpURLConnection#getErrorStream
.
Returns: an error stream if any, null if there have been no errors, the connection is not connected or the server sent no useful data.
Relevant code that would need to be updated.
Alternatives
- Use something other than
SimpleClientHttpRequestFactory
. This can be more involved because of the differences between the different HTTP client implementations, it isn't always as simple as changing and using the defaults for the new HTTP client. - Custom request factory in our apps that is identical to the
SimpleClientHttpRequestFactory
, but with the change described above. - Handle the IOException within the relevant
ClientHttpRequestInterceptor
s.
Reproduction attached. Run the app and there will be 2 log messages output (1 for RestClient and 1 for RestTemplate). DemoClient
uses a 3 second timeout before sending the http request to the local server. If the server takes longer than that to start, this timeout will need to be increased.
demo.zip