Skip to content

Commit 9876ca0

Browse files
committed
Support fragments in UriComponentsBuilder.fromHttpUrl()
Prior to this commit, UriComponentsBuilder.fromHttpUrl() threw an IllegalArgumentException if the provided URL contained a fragment. This commit aligns the implementation of fromHttpUrl() with that of fromUriString(), by parsing a fragment and storing it in the builder. Closes gh-25300
1 parent dd11dbf commit 9876ca0

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
* @author Oliver Gierke
6060
* @author Brian Clozel
6161
* @author Sebastien Deleuze
62+
* @author Sam Brannen
6263
* @since 3.1
6364
* @see #newInstance()
6465
* @see #fromPath(String)
@@ -95,7 +96,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {
9596

9697
private static final Pattern HTTP_URL_PATTERN = Pattern.compile(
9798
"^" + HTTP_PATTERN + "(//(" + USERINFO_PATTERN + "@)?" + HOST_PATTERN + "(:" + PORT_PATTERN + ")?" + ")?" +
98-
PATH_PATTERN + "(\\?" + LAST_PATTERN + ")?");
99+
PATH_PATTERN + "(\\?" + QUERY_PATTERN + ")?" + "(#" + LAST_PATTERN + ")?");
99100

100101
private static final Pattern FORWARDED_HOST_PATTERN = Pattern.compile("host=\"?([^;,\"]+)\"?");
101102

@@ -288,6 +289,10 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) {
288289
}
289290
builder.path(matcher.group(8));
290291
builder.query(matcher.group(10));
292+
String fragment = matcher.group(12);
293+
if (StringUtils.hasText(fragment)) {
294+
builder.fragment(fragment);
295+
}
291296
return builder;
292297
}
293298
else {

spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,84 @@ void fromHttpUrlInvalidIPv6Host() {
248248
UriComponentsBuilder.fromHttpUrl("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource"));
249249
}
250250

251+
@Test
252+
void fromHttpUrlWithoutFragment() {
253+
String httpUrl = "http://localhost:8080/test/print";
254+
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
255+
assertThat(uriComponents.getScheme()).isEqualTo("http");
256+
assertThat(uriComponents.getUserInfo()).isNull();
257+
assertThat(uriComponents.getHost()).isEqualTo("localhost");
258+
assertThat(uriComponents.getPort()).isEqualTo(8080);
259+
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
260+
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
261+
assertThat(uriComponents.getQuery()).isNull();
262+
assertThat(uriComponents.getFragment()).isNull();
263+
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
264+
265+
httpUrl = "http://user:test@localhost:8080/test/print?foo=bar";
266+
uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
267+
assertThat(uriComponents.getScheme()).isEqualTo("http");
268+
assertThat(uriComponents.getUserInfo()).isEqualTo("user:test");
269+
assertThat(uriComponents.getHost()).isEqualTo("localhost");
270+
assertThat(uriComponents.getPort()).isEqualTo(8080);
271+
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
272+
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
273+
assertThat(uriComponents.getQuery()).isEqualTo("foo=bar");
274+
assertThat(uriComponents.getFragment()).isNull();
275+
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
276+
277+
httpUrl = "http://localhost:8080/test/print?foo=bar";
278+
uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
279+
assertThat(uriComponents.getScheme()).isEqualTo("http");
280+
assertThat(uriComponents.getUserInfo()).isNull();
281+
assertThat(uriComponents.getHost()).isEqualTo("localhost");
282+
assertThat(uriComponents.getPort()).isEqualTo(8080);
283+
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
284+
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
285+
assertThat(uriComponents.getQuery()).isEqualTo("foo=bar");
286+
assertThat(uriComponents.getFragment()).isNull();
287+
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
288+
}
289+
290+
@Test // gh-25300
291+
void fromHttpUrlWithFragment() {
292+
String httpUrl = "https://example.com#baz";
293+
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
294+
assertThat(uriComponents.getScheme()).isEqualTo("https");
295+
assertThat(uriComponents.getUserInfo()).isNull();
296+
assertThat(uriComponents.getHost()).isEqualTo("example.com");
297+
assertThat(uriComponents.getPort()).isEqualTo(-1);
298+
assertThat(uriComponents.getPath()).isNullOrEmpty();
299+
assertThat(uriComponents.getPathSegments()).isEmpty();
300+
assertThat(uriComponents.getQuery()).isNull();
301+
assertThat(uriComponents.getFragment()).isEqualTo("baz");
302+
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
303+
304+
httpUrl = "http://localhost:8080/test/print#baz";
305+
uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
306+
assertThat(uriComponents.getScheme()).isEqualTo("http");
307+
assertThat(uriComponents.getUserInfo()).isNull();
308+
assertThat(uriComponents.getHost()).isEqualTo("localhost");
309+
assertThat(uriComponents.getPort()).isEqualTo(8080);
310+
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
311+
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
312+
assertThat(uriComponents.getQuery()).isNull();
313+
assertThat(uriComponents.getFragment()).isEqualTo("baz");
314+
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
315+
316+
httpUrl = "http://localhost:8080/test/print?foo=bar#baz";
317+
uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
318+
assertThat(uriComponents.getScheme()).isEqualTo("http");
319+
assertThat(uriComponents.getUserInfo()).isNull();
320+
assertThat(uriComponents.getHost()).isEqualTo("localhost");
321+
assertThat(uriComponents.getPort()).isEqualTo(8080);
322+
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
323+
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
324+
assertThat(uriComponents.getQuery()).isEqualTo("foo=bar");
325+
assertThat(uriComponents.getFragment()).isEqualTo("baz");
326+
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
327+
}
328+
251329
@Test
252330
void fromHttpRequest() {
253331
MockHttpServletRequest request = new MockHttpServletRequest();

0 commit comments

Comments
 (0)