Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,16 @@ public Path(String pathString) throws IllegalArgumentException {
int start = 0;

// parse uri scheme, if any
int colon = pathString.indexOf(':');
int colon = -1;
int slash = pathString.indexOf('/');
if (StringUtils.countMatches(pathString, ":") > 2) {
//In case of IPv6 address, we should be able to parse the scheme
// correctly (This will ensure to parse path with & without scheme
// correctly in IPv6).
colon = pathString.indexOf(":/");
} else {
colon = pathString.indexOf(':');
}
if ((colon != -1) &&
((slash == -1) || (colon < slash))) { // has a scheme
scheme = pathString.substring(0, colon);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

import javax.net.SocketFactory;

import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.thirdparty.com.google.common.cache.Cache;
import org.apache.hadoop.thirdparty.com.google.common.cache.CacheBuilder;
Expand Down Expand Up @@ -223,6 +224,22 @@ public static InetSocketAddress createSocketAddr(String target,
}
target = target.trim();
boolean hasScheme = target.contains("://");
if (StringUtils.countMatches(target, ":") > 2) {
// if scheme exists in the target
// for example : https://ffff:ffff:ffff:ffff::1:XXXXX
// we have to form https://[ffff:ffff:ffff:ffff::1]:XXXXX
if (hasScheme) {
int i = target.lastIndexOf("/");
String scheme = target.substring(0, i + 1);
String ipAddrWithPort = target.substring(i + 1);
target = scheme + normalizeV6Address(ipAddrWithPort);
} else {
// if scheme does not exists in the target
// for example : ffff:ffff:ffff:ffff::1:XXXXX
// we have to form [ffff:ffff:ffff:ffff::1]:XXXXX
target = normalizeV6Address(target);
}
}
URI uri = createURI(target, hasScheme, helpText, useCacheIfPresent);

String host = uri.getHost();
Expand Down Expand Up @@ -275,6 +292,24 @@ private static URI createURI(String target,
return uri;
}

public static String normalizeV6Address(String target) {
if (!target.startsWith("[")) {
if (target.contains("%")) {
int i = target.lastIndexOf('%');
target = target.trim();
String port = target.substring(target.lastIndexOf(":") + 1);
String addr = target.substring(0, i);
target = "[" + addr + "]" + ":" + port;
} else {
int i = target.lastIndexOf(':');
String port = target.substring(target.lastIndexOf(":") + 1);
String addr = target.substring(0, i);
target = "[" + addr + "]" + ":" + port;
}
}
return target;
}

/**
* Create a socket address with the given host and port. The hostname
* might be replaced with another host that was set via
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -817,4 +817,41 @@ private <T> void assertBetterArrayEquals(T[] expect, T[]got) {
String gotStr = StringUtils.join(got, ", ");
assertEquals(expectStr, gotStr);
}

@Test
public void testCreateSocketAddressWithIPV6() throws Throwable {
String ipv6Address = "2a03:2880:2130:cf05:face:b00c:0:1";
String ipv6WithPort = ipv6Address + ":12345";

InetSocketAddress addr = NetUtils.createSocketAddr(ipv6WithPort,
1000, "myconfig");
assertEquals("[" + ipv6Address + "]", addr.getHostName());
assertEquals(12345, addr.getPort());

String ipv6SampleAddressWithScope = ipv6Address + "%2";
ipv6WithPort = ipv6SampleAddressWithScope + ":12345";
addr = NetUtils.createSocketAddr(ipv6WithPort, 1000, "myconfig");
assertEquals("[" + ipv6Address + "]", addr.getHostName());
assertEquals(12345, addr.getPort());

ipv6Address = "[2a03:2880:2130:cf05:face:b00c:0:1]";
ipv6WithPort = ipv6Address + ":12345";

addr = NetUtils.createSocketAddr(ipv6WithPort, 1000, "myconfig");
assertEquals(ipv6Address, addr.getHostName());
assertEquals(12345, addr.getPort());

String ipv6AddressWithScheme =
"https://2a03:2880:2130:cf05:face:b00c:0:1:12345";
addr = NetUtils.createSocketAddr(ipv6AddressWithScheme, 1000,
"myconfig");
assertEquals(ipv6Address, addr.getHostName());
assertEquals(12345, addr.getPort());

ipv6AddressWithScheme = "https://[2a03:2880:2130:cf05:face:b00c:0:1]:12345";
addr = NetUtils.createSocketAddr(ipv6AddressWithScheme, 1000,
"myconfig");
assertEquals(ipv6Address, addr.getHostName());
assertEquals(12345, addr.getPort());
}
}