-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Spring Web ignores '+' character while encoding with HierarchicalUriComponents #23148
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
Comments
As I found, current behavior is a side-effect of fixing SPR-14828 (also known sa #19394) with f2e293a by @rstoyanchev. So I'm not sure now if you consider this a bug or a feature. Maybe it's invalid like #23025. |
Indeed same comment as under #23025. Basically there are different (sometimes opposite) needs when it comes to encoding. For |
Thanks for feedback!
Tried updating the test with the proposed suggestion: @Test
public void encode_withUrlInQueryParams() throws UnsupportedEncodingException {
String base = "https://www.base.com";
String first = "https://www.first.com?time_stamp=2019-06-17+03%3A48%3A56&address=25+Downing+Street";
String second = "https://www.second.com?address=25%20Downing%20Street";
String encoded = UriComponentsBuilder.fromHttpUrl(base)
.queryParam("first", first)
.queryParam("second", second)
.encode().build().toUriString();
Map<String, String> values = UriComponentsBuilder.fromUriString(encoded).build().getQueryParams().toSingleValueMap();
assertThat(URLDecoder.decode(values.get("second"), "UTF-8")).isEqualTo(second);
assertThat(URLDecoder.decode(values.get("first"), "UTF-8")).isEqualTo(first);
} Test still fails. Also tried applying crazy "encode everything" strategy: @Test
public void encode_withUrlInQueryParams() throws UnsupportedEncodingException {
String base = "https://www.base.com";
String first = "https://www.first.com?time_stamp=2019-06-17+03%3A48%3A56&address=25+Downing+Street";
String second = "https://www.second.com?address=25%20Downing%20Street";
String encoded = UriComponentsBuilder.fromHttpUrl(base)
.queryParam("first", first)
.queryParam("second", second)
.encode().build().encode().toUriString();
Map<String, String> values = UriComponentsBuilder.fromUriString(encoded).build().getQueryParams().toSingleValueMap();
assertThat(URLDecoder.decode(values.get("second"), "UTF-8")).isEqualTo(second);
assertThat(URLDecoder.decode(values.get("first"), "UTF-8")).isEqualTo(first);
} Still failure. So... As per my observation, Spring simply does not encode |
Pay attention to the documentation samples. Only URI variables are strongly encoded (i.e. all reserved characters). The literal parts of the URI template are simply checked for allowed characters per URI component. @Test
public void encode_withUrlInQueryParams() throws UnsupportedEncodingException {
String base = "https://www.base.com";
String first = "https://www.first.com?time_stamp=2019-06-17+03%3A48%3A56&address=25+Downing+Street";
String second = "https://www.second.com?address=25%20Downing%20Street";
String encoded = UriComponentsBuilder.fromHttpUrl(base)
.queryParam("first", "{first}")
.queryParam("second", "{second}")
.encode().buildAndExpand(first, second).toUriString();
Map<String, String> values = UriComponentsBuilder.fromUriString(encoded).build().getQueryParams().toSingleValueMap();
assertThat(URLDecoder.decode(values.get("second"), "UTF-8")).isEqualTo(second);
assertThat(URLDecoder.decode(values.get("first"), "UTF-8")).isEqualTo(first);
} |
First of all, thank you very much for maintaining this great project! But let me go straight to the issue.
Here is a unit test to demonstrate the problem:
This test works on
4.3.21.RELEASE
, but fails on5.1.7.RELEASE
version:In short: as Spring ignores
+
character while encoding, further decoding "breaks" parameter.The text was updated successfully, but these errors were encountered: