Skip to content

Commit

Permalink
Support fragments in UriComponentsBuilder.fromHttpUrl()
Browse files Browse the repository at this point in the history
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 spring-projectsgh-25300
  • Loading branch information
sbrannen authored and xcl(徐程林) committed Aug 16, 2020
1 parent 49d6058 commit 02adc2d
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 1 deletion.
Expand Up @@ -59,6 +59,7 @@
* @author Oliver Gierke
* @author Brian Clozel
* @author Sebastien Deleuze
* @author Sam Brannen
* @since 3.1
* @see #newInstance()
* @see #fromPath(String)
Expand Down Expand Up @@ -95,7 +96,7 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable {

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

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

Expand Down Expand Up @@ -288,6 +289,10 @@ public static UriComponentsBuilder fromHttpUrl(String httpUrl) {
}
builder.path(matcher.group(8));
builder.query(matcher.group(10));
String fragment = matcher.group(12);
if (StringUtils.hasText(fragment)) {
builder.fragment(fragment);
}
return builder;
}
else {
Expand Down
Expand Up @@ -248,6 +248,84 @@ void fromHttpUrlInvalidIPv6Host() {
UriComponentsBuilder.fromHttpUrl("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource"));
}

@Test
void fromHttpUrlWithoutFragment() {
String httpUrl = "http://localhost:8080/test/print";
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
assertThat(uriComponents.getScheme()).isEqualTo("http");
assertThat(uriComponents.getUserInfo()).isNull();
assertThat(uriComponents.getHost()).isEqualTo("localhost");
assertThat(uriComponents.getPort()).isEqualTo(8080);
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
assertThat(uriComponents.getQuery()).isNull();
assertThat(uriComponents.getFragment()).isNull();
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);

httpUrl = "http://user:test@localhost:8080/test/print?foo=bar";
uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
assertThat(uriComponents.getScheme()).isEqualTo("http");
assertThat(uriComponents.getUserInfo()).isEqualTo("user:test");
assertThat(uriComponents.getHost()).isEqualTo("localhost");
assertThat(uriComponents.getPort()).isEqualTo(8080);
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
assertThat(uriComponents.getQuery()).isEqualTo("foo=bar");
assertThat(uriComponents.getFragment()).isNull();
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);

httpUrl = "http://localhost:8080/test/print?foo=bar";
uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
assertThat(uriComponents.getScheme()).isEqualTo("http");
assertThat(uriComponents.getUserInfo()).isNull();
assertThat(uriComponents.getHost()).isEqualTo("localhost");
assertThat(uriComponents.getPort()).isEqualTo(8080);
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
assertThat(uriComponents.getQuery()).isEqualTo("foo=bar");
assertThat(uriComponents.getFragment()).isNull();
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
}

@Test // gh-25300
void fromHttpUrlWithFragment() {
String httpUrl = "https://example.com#baz";
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
assertThat(uriComponents.getScheme()).isEqualTo("https");
assertThat(uriComponents.getUserInfo()).isNull();
assertThat(uriComponents.getHost()).isEqualTo("example.com");
assertThat(uriComponents.getPort()).isEqualTo(-1);
assertThat(uriComponents.getPath()).isNullOrEmpty();
assertThat(uriComponents.getPathSegments()).isEmpty();
assertThat(uriComponents.getQuery()).isNull();
assertThat(uriComponents.getFragment()).isEqualTo("baz");
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);

httpUrl = "http://localhost:8080/test/print#baz";
uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
assertThat(uriComponents.getScheme()).isEqualTo("http");
assertThat(uriComponents.getUserInfo()).isNull();
assertThat(uriComponents.getHost()).isEqualTo("localhost");
assertThat(uriComponents.getPort()).isEqualTo(8080);
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
assertThat(uriComponents.getQuery()).isNull();
assertThat(uriComponents.getFragment()).isEqualTo("baz");
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);

httpUrl = "http://localhost:8080/test/print?foo=bar#baz";
uriComponents = UriComponentsBuilder.fromHttpUrl(httpUrl).build();
assertThat(uriComponents.getScheme()).isEqualTo("http");
assertThat(uriComponents.getUserInfo()).isNull();
assertThat(uriComponents.getHost()).isEqualTo("localhost");
assertThat(uriComponents.getPort()).isEqualTo(8080);
assertThat(uriComponents.getPath()).isEqualTo("/test/print");
assertThat(uriComponents.getPathSegments()).isEqualTo(Arrays.asList("test", "print"));
assertThat(uriComponents.getQuery()).isEqualTo("foo=bar");
assertThat(uriComponents.getFragment()).isEqualTo("baz");
assertThat(uriComponents.toUri().toString()).isEqualTo(httpUrl);
}

@Test
void fromHttpRequest() {
MockHttpServletRequest request = new MockHttpServletRequest();
Expand Down

0 comments on commit 02adc2d

Please sign in to comment.