Merge pull request #358 from bclozel/SPR-10539
* bclozel-SPR-10539: Polish Add IPv6 support in RestTemplate
This commit is contained in:
@@ -182,7 +182,8 @@ final class HierarchicalUriComponents extends UriComponents {
|
||||
}
|
||||
String encodedScheme = encodeUriComponent(this.getScheme(), encoding, Type.SCHEME);
|
||||
String encodedUserInfo = encodeUriComponent(this.userInfo, encoding, Type.USER_INFO);
|
||||
String encodedHost = encodeUriComponent(this.host, encoding, Type.HOST);
|
||||
String encodedHost = encodeUriComponent(this.host, encoding, getHostType());
|
||||
|
||||
PathComponent encodedPath = this.path.encode(encoding);
|
||||
MultiValueMap<String, String> encodedQueryParams =
|
||||
new LinkedMultiValueMap<String, String>(this.queryParams.size());
|
||||
@@ -240,6 +241,9 @@ final class HierarchicalUriComponents extends UriComponents {
|
||||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
private Type getHostType() {
|
||||
return ((this.host != null) && this.host.startsWith("[")) ? Type.HOST_IPV6 : Type.HOST_IPV4;
|
||||
}
|
||||
|
||||
// verifying
|
||||
|
||||
@@ -254,7 +258,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
||||
}
|
||||
verifyUriComponent(getScheme(), Type.SCHEME);
|
||||
verifyUriComponent(userInfo, Type.USER_INFO);
|
||||
verifyUriComponent(host, Type.HOST);
|
||||
verifyUriComponent(host, getHostType());
|
||||
this.path.verify();
|
||||
for (Map.Entry<String, List<String>> entry : queryParams.entrySet()) {
|
||||
verifyUriComponent(entry.getKey(), Type.QUERY_PARAM);
|
||||
@@ -462,12 +466,18 @@ final class HierarchicalUriComponents extends UriComponents {
|
||||
return isUnreserved(c) || isSubDelimiter(c) || ':' == c;
|
||||
}
|
||||
},
|
||||
HOST {
|
||||
HOST_IPV4 {
|
||||
@Override
|
||||
public boolean isAllowed(int c) {
|
||||
return isUnreserved(c) || isSubDelimiter(c);
|
||||
}
|
||||
},
|
||||
HOST_IPV6 {
|
||||
@Override
|
||||
public boolean isAllowed(int c) {
|
||||
return isUnreserved(c) || isSubDelimiter(c) || '[' == c || ']' == c || ':' == c;
|
||||
}
|
||||
},
|
||||
PORT {
|
||||
@Override
|
||||
public boolean isAllowed(int c) {
|
||||
|
||||
@@ -64,7 +64,11 @@ public class UriComponentsBuilder {
|
||||
|
||||
private static final String USERINFO_PATTERN = "([^@/]*)";
|
||||
|
||||
private static final String HOST_PATTERN = "([^/?#:]*)";
|
||||
private static final String HOST_IPV4_PATTERN = "[^\\[/?#:]*";
|
||||
|
||||
private static final String HOST_IPV6_PATTERN = "\\[[\\p{XDigit}\\:\\.]*[%\\p{Alnum}]*\\]";
|
||||
|
||||
private static final String HOST_PATTERN = "(" + HOST_IPV6_PATTERN + "|" + HOST_IPV4_PATTERN + ")";
|
||||
|
||||
private static final String PORT_PATTERN = "(\\d*)";
|
||||
|
||||
@@ -226,7 +230,11 @@ public class UriComponentsBuilder {
|
||||
String scheme = m.group(1);
|
||||
builder.scheme((scheme != null) ? scheme.toLowerCase() : scheme);
|
||||
builder.userInfo(m.group(4));
|
||||
builder.host(m.group(5));
|
||||
String host = m.group(5);
|
||||
if(StringUtils.hasLength(scheme) && !StringUtils.hasLength(host)) {
|
||||
throw new IllegalArgumentException("[" + httpUrl + "] is not a valid HTTP URL");
|
||||
}
|
||||
builder.host(host);
|
||||
String port = m.group(7);
|
||||
if (StringUtils.hasLength(port)) {
|
||||
builder.port(Integer.parseInt(port));
|
||||
|
||||
@@ -254,7 +254,7 @@ public abstract class UriUtils {
|
||||
*/
|
||||
public static String encodeHost(String host, String encoding) throws UnsupportedEncodingException {
|
||||
return HierarchicalUriComponents
|
||||
.encodeUriComponent(host, encoding, HierarchicalUriComponents.Type.HOST);
|
||||
.encodeUriComponent(host, encoding, HierarchicalUriComponents.Type.HOST_IPV4);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -169,6 +169,30 @@ public class UriComponentsBuilderTests {
|
||||
assertEquals("https", UriComponentsBuilder.fromHttpUrl("HTTPS://www.google.com").build().getScheme());
|
||||
}
|
||||
|
||||
// SPR-10539
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void fromHttpUrlStringInvalidIPv6Host() throws URISyntaxException {
|
||||
UriComponentsBuilder.fromHttpUrl("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource").build().encode();
|
||||
}
|
||||
|
||||
// SPR-10539
|
||||
|
||||
@Test
|
||||
public void fromUriStringIPv6Host() throws URISyntaxException {
|
||||
UriComponents result = UriComponentsBuilder
|
||||
.fromUriString("http://[1abc:2abc:3abc::5ABC:6abc]:8080/resource").build().encode();
|
||||
assertEquals("[1abc:2abc:3abc::5ABC:6abc]", result.getHost());
|
||||
|
||||
UriComponents resultWithScopeId = UriComponentsBuilder
|
||||
.fromUriString("http://[1abc:2abc:3abc::5ABC:6abc%eth0]:8080/resource").build().encode();
|
||||
assertEquals("[1abc:2abc:3abc::5ABC:6abc%25eth0]", resultWithScopeId.getHost());
|
||||
|
||||
UriComponents resultIPv4compatible = UriComponentsBuilder
|
||||
.fromUriString("http://[::192.168.1.1]:8080/resource").build().encode();
|
||||
assertEquals("[::192.168.1.1]", resultIPv4compatible.getHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void path() throws URISyntaxException {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/foo/bar");
|
||||
|
||||
@@ -25,9 +25,7 @@ import java.net.URISyntaxException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
@@ -45,20 +43,38 @@ public class UriComponentsTests {
|
||||
|
||||
@Test
|
||||
public void toUriEncoded() throws URISyntaxException {
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/hotel list/Z\u00fcrich").build();
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(
|
||||
"http://example.com/hotel list/Z\u00fcrich").build();
|
||||
assertEquals(new URI("http://example.com/hotel%20list/Z%C3%BCrich"), uriComponents.encode().toUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toUriNotEncoded() throws URISyntaxException {
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(
|
||||
"http://example.com/hotel list/Z\u00fcrich").build();
|
||||
assertEquals(new URI("http://example.com/hotel%20list/Z\u00fcrich"), uriComponents.toUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toUriAlreadyEncoded() throws URISyntaxException {
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(
|
||||
"http://example.com/hotel%20list/Z%C3%BCrich").build(true);
|
||||
UriComponents encoded = uriComponents.encode();
|
||||
assertEquals(new URI("http://example.com/hotel%20list/Z%C3%BCrich"), encoded.toUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toUriNotEncoded() throws URISyntaxException {
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/hotel list/Z\u00fcrich").build();
|
||||
assertEquals(new URI("http://example.com/hotel%20list/Z\u00fcrich"), uriComponents.toUri());
|
||||
public void toUriWithIpv6HostAlreadyEncoded() throws URISyntaxException {
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(
|
||||
"http://[1abc:2abc:3abc::5ABC:6abc]:8080/hotel%20list/Z%C3%BCrich").build(true);
|
||||
UriComponents encoded = uriComponents.encode();
|
||||
assertEquals(new URI("http://[1abc:2abc:3abc::5ABC:6abc]:8080/hotel%20list/Z%C3%BCrich"), encoded.toUri());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expand() {
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com").path("/{foo} {bar}").build();
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(
|
||||
"http://example.com").path("/{foo} {bar}").build();
|
||||
uriComponents = uriComponents.expand("1 2", "3 4");
|
||||
assertEquals("/1 2 3 4", uriComponents.getPath());
|
||||
assertEquals("http://example.com/1 2 3 4", uriComponents.toUriString());
|
||||
|
||||
Reference in New Issue
Block a user