File tree Expand file tree Collapse file tree 3 files changed +48
-3
lines changed
main/java/org/springframework/web/util
test/java/org/springframework/web/util Expand file tree Collapse file tree 3 files changed +48
-3
lines changed Original file line number Diff line number Diff line change @@ -182,7 +182,13 @@ public HierarchicalUriComponents encode(String encoding) throws UnsupportedEncod
182
182
}
183
183
String encodedScheme = encodeUriComponent (this .getScheme (), encoding , Type .SCHEME );
184
184
String encodedUserInfo = encodeUriComponent (this .userInfo , encoding , Type .USER_INFO );
185
- String encodedHost = encodeUriComponent (this .host , encoding , Type .HOST );
185
+ String encodedHost ;
186
+ if (StringUtils .hasLength (this .host ) && this .host .startsWith ("[" )) {
187
+ encodedHost = encodeUriComponent (this .host , encoding , Type .HOST_IPV6 );
188
+ } else {
189
+ encodedHost = encodeUriComponent (this .host , encoding , Type .HOST );
190
+ }
191
+
186
192
PathComponent encodedPath = this .path .encode (encoding );
187
193
MultiValueMap <String , String > encodedQueryParams =
188
194
new LinkedMultiValueMap <String , String >(this .queryParams .size ());
@@ -468,6 +474,12 @@ public boolean isAllowed(int c) {
468
474
return isUnreserved (c ) || isSubDelimiter (c );
469
475
}
470
476
},
477
+ HOST_IPV6 {
478
+ @ Override
479
+ public boolean isAllowed (int c ) {
480
+ return isUnreserved (c ) || isSubDelimiter (c ) || '[' == c || ']' == c || ':' == c ;
481
+ }
482
+ },
471
483
PORT {
472
484
@ Override
473
485
public boolean isAllowed (int c ) {
Original file line number Diff line number Diff line change @@ -64,7 +64,11 @@ public class UriComponentsBuilder {
64
64
65
65
private static final String USERINFO_PATTERN = "([^@/]*)" ;
66
66
67
- private static final String HOST_PATTERN = "([^/?#:]*)" ;
67
+ private static final String HOST_IPv4_PATTERN = "[^\\ [/?#:]*" ;
68
+
69
+ private static final String HOST_IPV6_PATTERN = "\\ [[\\ p{XDigit}\\ :\\ .]*[%\\ p{Alnum}]*\\ ]" ;
70
+
71
+ private static final String HOST_PATTERN = "(" +HOST_IPV6_PATTERN + "|" + HOST_IPv4_PATTERN + ")" ;
68
72
69
73
private static final String PORT_PATTERN = "(\\ d*)" ;
70
74
@@ -226,7 +230,11 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) {
226
230
String scheme = m .group (1 );
227
231
builder .scheme ((scheme != null ) ? scheme .toLowerCase () : scheme );
228
232
builder .userInfo (m .group (4 ));
229
- builder .host (m .group (5 ));
233
+ String host = m .group (5 );
234
+ if (StringUtils .hasLength (scheme ) && !StringUtils .hasLength (host )) {
235
+ throw new IllegalArgumentException ("[" + httpUrl + "] is not a valid HTTP URL" );
236
+ }
237
+ builder .host (host );
230
238
String port = m .group (7 );
231
239
if (StringUtils .hasLength (port )) {
232
240
builder .port (Integer .parseInt (port ));
Original file line number Diff line number Diff line change @@ -169,6 +169,31 @@ public void fromHttpUrlStringCaseInsesitiveScheme() {
169
169
assertEquals ("https" , UriComponentsBuilder .fromHttpUrl ("HTTPS://www.google.com" ).build ().getScheme ());
170
170
}
171
171
172
+ // SPR-10539
173
+
174
+ @ Test (expected = IllegalArgumentException .class )
175
+ public void fromHttpUrlStringInvalidIPv6Host () throws URISyntaxException {
176
+ UriComponents result = UriComponentsBuilder
177
+ .fromHttpUrl ("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource" ).build ().encode ();
178
+ }
179
+
180
+ // SPR-10539
181
+
182
+ @ Test
183
+ public void fromUriStringIPv6Host () throws URISyntaxException {
184
+ UriComponents result = UriComponentsBuilder
185
+ .fromUriString ("http://[1abc:2abc:3abc::5ABC:6abc]:8080/resource" ).build ().encode ();
186
+ assertEquals ("[1abc:2abc:3abc::5ABC:6abc]" ,result .getHost ());
187
+
188
+ UriComponents resultWithScopeId = UriComponentsBuilder
189
+ .fromUriString ("http://[1abc:2abc:3abc::5ABC:6abc%eth0]:8080/resource" ).build ().encode ();
190
+ assertEquals ("[1abc:2abc:3abc::5ABC:6abc%25eth0]" ,resultWithScopeId .getHost ());
191
+
192
+ UriComponents resultIPv4compatible = UriComponentsBuilder
193
+ .fromUriString ("http://[::192.168.1.1]:8080/resource" ).build ().encode ();
194
+ assertEquals ("[::192.168.1.1]" ,resultIPv4compatible .getHost ());
195
+ }
196
+
172
197
@ Test
173
198
public void path () throws URISyntaxException {
174
199
UriComponentsBuilder builder = UriComponentsBuilder .fromPath ("/foo/bar" );
You can’t perform that action at this time.
0 commit comments