Fix HttpClientResponse body()/end() race (5.0 backport)#6071
Merged
vietj merged 1 commit intoeclipse-vertx:5.0from Apr 17, 2026
Merged
Fix HttpClientResponse body()/end() race (5.0 backport)#6071vietj merged 1 commit intoeclipse-vertx:5.0from
vietj merged 1 commit intoeclipse-vertx:5.0from
Conversation
This change fixes the race in `HttpClientResponseImpl` described in eclipse-vertx#6038: `handleTrailers()`/`handleException()` can run before `body()`/`end()` creates the promise. If that happens, the completion signal is dropped and the future can hang. This is observed from the call site as a HTTP request timeout. This fix is only applied to `HttpClientResponseImpl`: - keep ended/failure state on `HttpClientResponseImpl` - in `body()`/`end()`, create the `HttpEventHandler` promise while holding `synchronized(conn)` - after unlock, replay completion/failure via `handleEnd()`/`handleException()` when needed Although `HttpEventHandler` looks very similar (like it _could_ be affected by the same/similar race condition), it is not affected. I intentionally did not change `HttpEventHandler`, because it is also used in server request processing. The only case when server request processing could be affected , is when `body()` is called from a _different_ thread while `end()` is being processed - that is very unlikely (feels like a misuse). Also added two new tests to `Http1xTest` that reliably fail without the change to `HttpClientResponseImpl` and reliably pass with that change. The added regression tests are `testResponseBodyAfterResponseEnd` and `testResponseEndAfterResponseEnd`. Fixes eclipse-vertx#6038
vietj
approved these changes
Apr 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change fixes the race in
HttpClientResponseImpldescribed in #6038:handleTrailers()/handleException()can run beforebody()/end()creates the promise. If that happens, the completion signal is dropped and the future can hang. This is observed from the call site as a HTTP request timeout.This fix is only applied to
HttpClientResponseImpl:HttpClientResponseImplbody()/end(), create theHttpEventHandlerpromise while holdingsynchronized(conn)handleEnd()/handleException()when neededAlthough
HttpEventHandlerlooks very similar (like it could be affected by the same/similar race condition), it is not affected. I intentionally did not changeHttpEventHandler, because it is also used in server request processing. The only case when server request processing could be affected , is whenbody()is called from a different thread whileend()is being processed - that is very unlikely (feels like a misuse).Also added two new tests to
Http1xTestthat reliably fail without the change toHttpClientResponseImpland reliably pass with that change. The added regression tests aretestResponseBodyAfterResponseEndandtestResponseEndAfterResponseEnd.Contributes to #6038