fix(http-client-vertx): resolve relative redirect Location against the request URI (#1142) - #1162
Open
chopmob-cloud wants to merge 2 commits into
Conversation
…e request URI The opt-in redirect follower in VertxA2AHttpClient passed the raw Location header value straight to WebClient.getAbs()/postAbs(). RFC 9110 (10.2.2) and RFC 7231 permit a relative Location such as /collect, so a relative value was handed to an absolute-URI request and failed with MalformedURLException instead of being followed. Resolve the Location against the original request URI using RFC 3986 (5) reference resolution (URI.create(url).resolve(location)) before building the redirected request. Absolute Location values are returned unchanged, so existing behavior is preserved; a malformed base or location falls back to the raw value. No redirect-target validation is added or weakened. Adds a Vert.x redirect test that serves a relative Location from a single origin and asserts it is resolved and followed; the inherited absolute-Location tests continue to pass. Fixes a2aproject#1142. Signed-off-by: AlgoVoi <chopmob@gmail.com>
ehsavoie
requested changes
Sep 21, 2026
| * @param location the raw {@code Location} header value | ||
| * @return the absolute redirect target | ||
| */ | ||
| private static String resolveRedirectLocation(String requestUri, String location) { |
Collaborator
There was a problem hiding this comment.
This should be package protected so we can add a bunch of unit tests to validate the expected behaviour instead of 'just' a single 'integration' test with mocks
…2aproject#1162) Make resolveRedirectLocation package-private so RFC 3986 reference resolution can be unit-tested without a mock server, per review. Add a focused test class covering absolute-path, relative-path, dot-segment, query, protocol-relative, already-absolute, and malformed base/location (raw fallback) cases. The existing mock-server integration test is kept. Signed-off-by: AlgoVoi <chopmob@gmail.com>
This branch has not been deployed
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.
Summary
Fixes #1142. The Vert.x client's opt-in redirect following passed the redirect
Locationstraight towebClient.getAbs(location)(301/302/303) andpostAbs(location)(307/308), so a relativeLocation(e.g./collect, permitted by RFC 9110/7231) was never resolved against the original request URI and the redirect failed withMalformedURLException: no protocol.Fix
Resolve the
Locationagainst the original request URI per RFC 3986 (URI.create(url).resolve(location)) in both redirect branches before constructing the redirected request. Absolute Locations pass through unchanged; a malformed base/location falls back to the raw value (prior behavior). OnlyVertxPostBuilder.post()follows redirects (the GET/SSE paths are single-shot by design), so the fix is scoped to those two branches, and no existing redirect-target validation is added or weakened.Tests
Added
synchronousPostFollowsRelativeRedirectLocation(MockServer, single origin): a302withLocation: /collectis now resolved against the base and followed through to the target. The inherited absolute-Location test confirms absolute Locations still work unchanged. Reverting the resolve step reproduces the originalMalformedURLException: no protocol: /collect.mvn -pl extras/http-client-vertx -am testpasses (45 tests, 0 failures).