-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Emit WebClientResponseException for malformed HTTP response #27262
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
Emit WebClientResponseException for malformed HTTP response #27262
Conversation
Added test case for malformed response chunk, which is now failing as expected.
This targets an edge case that can occur when the Reactor client fails to process a response body due to an issue such as a malformed HTTP/1.1 response chunk, but since this issue only occurred after the body began to be parsed, nothing existed to catch it. This previously resulted in an unhandled ReactorException being thrown out of the subscriber to WebClient calls. Upon testing this further, it also appears to fix edge cases for Jetty and Apache HTTP Components as well when parsing a "bodiless entity" that has a malformed response chunk present, as this would beforehand defer the exception until later, again leading it to be thrown without being decorated in the Spring exception. Without this fix, error handling can be somewhat problematic, since each HTTP connector implementation throws a different exception type, and it would rely on the developer using this interface to know exactly what the internals of their chosen HTTP client were doing prior to the exception occurring.
@ascopes thanks for the detailed report and pull request. Consistently emitting exceptions that extend from I think we need to expand the handling of errors in In the mean time, @ascopes, could you please separate out the additional test cases that are unrelated to the fix into a separate PR, which I should be able to process independently. Thanks again. |
I agree. I've tried to recollect, but can't remember why it is only triggered for On the specific topic of the |
@rstoyanchev can do, it will most likely be some time next week before I will have time to look into this though, if that is okay. Reason these were bundled in here was because I was attempting to verify if any other closure-related scenarios existed with the same issue. On the topic of exceptions, would it perhaps be worth considering having a third type of web application exception subclass specifically for IO-based errors below the codec level? Since these usually would be expected to be error scenarios anyway, this may simplify error handling by not having to differentiate between an empty response with a cause in-code. I believe that the RestTemplate API does something very similar to this conceptually. |
Added test case for malformed response chunk, which is now failing as expected. See gh-27262
I've incorporated the commit with the tests, then simplified a little, removed the unrelated test, and applied a fix. That should take care of the main issue. |
Fixes an issue that can be triggered in reactive WebClients when the server throws a malformed response chunk.
I picked up on the original issue by using WireMock with the following test case:
...where we see an unhandled exception get thrown.
(With no additional stacktrace provided by the underlying reactor library).
This exception does not appear to be documented in the most recent documentation for this codepath,
and since the various HTTP client connectors all use their own variants for these exceptions, it makes it
overly difficult for developers to add suitable error handling for components such as in-house libraries for
projects relying on Spring WebFlux without hardcoding edge cases for all libraries by default. Therefore,
my assumption has been that this is a potential bug as a result.
The issue itself appears to be being caused by the body processing throwing the exception rather than
the call to
exchange()
itself. On bodiless entities this appears to defer to be lazy, and the reactor clientitself also appears to be only reporting the malformed chunks after the body has been processed, which
meant that the existing error handling in ExchangeFunctions was not being hit for these cases.
For some reason, the OKHTTP3 Mock Web Server is not chunking responses properly in such a way
that I could simulate this in integration tests, so I resorted to writing a simple thread with a ServerSocket
to simulate the same issue. If anyone can think of a nicer way of achieving this, I will be happy to replace
it, but for now it appears to cover that test case.
I have also expanded the new test pack that was added on the 8th for WebClient integration tests to
cover a couple of other test cases that I was performing on an in-house project in the company I work
for that also appear to not have existing cases yet. These are handling scenarios where the server closes
the socket before the response has been sent or midway through the request being received. These cases
passed already but I added them just to be certain that no other regressions were added in this error
handling flow.
I am not aware of any issues that cover this already, but I may have missed some. I did take the time to try
and find any that may reference something related to this, but if I have missed anything I will update the
PR accordingly.
Hope what I have added is all okay, as I have only ever contributed documentation changes before now. If
there is any feedback or anyone can think of a better way to resolve this; or if there is any reason for this
behavior needing to be left how it is, please let me know!