-
Notifications
You must be signed in to change notification settings - Fork 925
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
Relax the validation of Location
header when redirecting
#5477
Conversation
To-dos:
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5477 +/- ##
===========================================
+ Coverage 0 74.06% +74.06%
- Complexity 0 20822 +20822
===========================================
Files 0 1801 +1801
Lines 0 76656 +76656
Branches 0 9783 +9783
===========================================
+ Hits 0 56777 +56777
- Misses 0 15253 +15253
- Partials 0 4626 +4626 ☔ View full report in Codecov by Sentry. |
Reported by @ohadgur at https://discord.com/channels/1087271586832318494/1209914423494311948 Motivation: If a client is configured to follow redirects with `followRedirects()`, the client will validate the value of `Location` header before sending a follow-up request to the given redirect location. `RedirectingClient` validates and resolves the target location using `URI.resolve()` which rejects poorly encoded `Location` header values such as: - `Location: /foo bar` (space should be percent-encoded) - `Location: /?${}` (`$`, `{` and `}` should be percent-encoded.) Modifications: - `RedirectingClient` now uses `RequestTarget.forClient()` to parse and normalize the target location so it is more tolerant to poorly encoded `Location` header values. - `RedirectingClient` now implements its own relative path resolution logic. See `RedirectingClient.resolveLocation()` for the detail. - Added `host` and `port` properties to `RequestTarget`. - Moved `DefaultRequestTarget.findAuthority()` to `ArmeriaHttpUtil` to reuse it in `RedirectingClient`. - Miscellaneous: - Fixed a potential bug where `RoutingContext.newPath()` creates a new `RequestTarget` whose `path` is `null` Result: - An Armeria client is now more tolerant to poorly encoded `Location` header values when following redirects.
f6ab55b
to
7d883b9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thanks!
core/src/main/java/com/linecorp/armeria/client/RedirectingClient.java
Outdated
Show resolved
Hide resolved
…nt.java Co-authored-by: minux <songmw725@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks solid! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes make sense 👍 Thanks! 🙇 👍 🙇
Thanks for reviewing, folks! |
@trustin not urgent, of course, but when is this change expected to be released? |
We're expecting to release 1.28.0 tomorrow |
Reported by @ohadgur at https://discord.com/channels/1087271586832318494/1209914423494311948
Motivation:
If a client is configured to follow redirects with
followRedirects()
, the client will validate the value ofLocation
header before sending a follow-up request to the given redirect location.RedirectingClient
validates and resolves the target location usingURI.resolve()
which rejects poorly encodedLocation
header values such as:Location: /foo bar
(space should be percent-encoded)Location: /?${}
($
,{
and}
should be percent-encoded.)Such strict validation might not be suitable in real world scenarios and we could
normalize them just like a client validates and normalizes the initial request target.
Modifications:
RedirectingClient
now usesRequestTarget.forClient()
to parse and normalize the target location so it is more tolerant to poorly encodedLocation
header values.RedirectingClient
now implements its own relative path resolution logic. SeeRedirectingClient.resolveLocation()
and `resolveRelativeLocation() for the detail.host
andport
properties toRequestTarget
.host
property toClientRequestContext
.DefaultRequestTarget.findAuthority()
toArmeriaHttpUtil
to reuse it inRedirectingClient
.RoutingContext.newPath()
creates a newRequestTarget
whosepath
isnull
ClientRequestContext.uri()
returns a double-encoded URI(Special thanks to @ohadgur for reporting this bug and suggesting a fix.)
RequestTarget.forClient()
to remove the port number in an absoluterequest target when possible, so that
http://a:80
is normalized intohttp://a
.Result:
Location
header values when following redirects.RequestTarget
using
RequestTarget.host()
andRequestTarget.port()
.ClientRequestContext.host()
.RequestTarget.forClient()
now removes a redundant port number fromthe specified URI for simpler request target comparison. For example,
https://foo
andhttps://foo:443
are considered equal.