-
Notifications
You must be signed in to change notification settings - Fork 37.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EOFException in HttpMessageConverterExtractor while extracting data of a empty GZiped response #28613
Conversation
@davidvieiratrustly Please sign the Contributor License Agreement! Click here to manually synchronize the status of this Pull Request. See the FAQ for frequently asked questions. |
@davidvieiratrustly Thank you for signing the Contributor License Agreement! |
23c6b2a
to
52df119
Compare
should not throw an exception when the response body is an empty lazy GZIP stream.
52df119
to
f9ce8ba
Compare
I don't think an empty stream is valid gzip. This looks like an incorrect server response, which is in line with the exception thrown. For example, you can try and create an empty gzip file and see that it's starting with the "magical number"
We are probably going to decline this change. Unless you've seen servers produce valid gzip empty responses? |
We have this problem in production right now while making requests to a bank API. We don't know what server the bank is using. I've created an example project to replicate the error using Netty Mock Server: As EOFException documentation states: We are reading the first byte of the response from the body into hasEmptyMessageBody; I don't think it's necessary to throw the exception, as when we get it, it's already indicative enough that the message body is empty. So, we must catch this exception so that the RestTemplate is not coupled with the request client implementation. Thank you for your time and assistance! |
Which is the underlying HTTP client library? I'm not sure why the |
I've tested with Apache Http Client (HttpComponentsClientHttpRequestFactory), OkHttp(OkHttp3ClientHttpRequestFactory) and SimpleJDK(SimpleClientHttpRequestFactory). The first two fail, while the Simple JDK works as inteded. You can check the full test in this repo: https://github.com/davidvieiratrustly/RestTemplateGzipBug/blob/main/src/test/java/com/example/demo/Demo1ApplicationTests.java Also, everything works as expected in the new WebClient; it only fails for RestTemplate with OkHTTP and Apache HTTP Client. Thank you in advance 🙏 |
As said above, this is likely to be an issue with the server and a blanket handling of Unfortunately, at least with the Here the The The
This is all indicative of a bad response from that particular server, from what we can gather from the mock response you've show in your reproducer code. We'd still be interested in a (redacted if needed) dump of the actual response if possible, but the issue certainly doesn't lie with Spring Framework. Please note a few additional interesting things regarding your tests with several backing clients:
In your test the JDK case is green because it happily consumes 0 bytes (since it doesn't attempt to decompress). If you feed it actual gzip content and turn it into a As a result, these "work" when the actual body is I've rewritten the tests (using a (see https://gist.github.com/simonbasle/f7880ded86857d71ee68bbe10cf2edce) |
ConclusionIf you removed You'll need to find a way to configure your underlying client to work around the issue, e.g. by deactivating automatic gzip support and adding some sort of interceptor to decompress the bytes yourself, provisioning for an empty byte array for that specific remote server. Another option is to query the server WITHOUT |
Problem: When calling RestTemplate#exchange with response type != Void.class, if
we get a EOFException in the RestTemplate client.
Solution: IntrospectingClientHttpResponse#hasEmptyMessageBody should not throw an exception when the response body is an empty lazy gzip stream.
After reading the first byte, if it receives an EOFException, it should understand it as a signal of the end of the stream, thus returning true to the question "Has an empty message body?", not EOFException to the RestTemplate client.
Related issue:
#12671