Skip to content

Commit

Permalink
Enable IPv6 URIs in reindex from remote (#36874)
Browse files Browse the repository at this point in the history
Reindex from remote was using a custom regex to dermine what URIs were
valid. This commit removes the custom regex and uses the java.net.URI
class instead, allowing IPv6 support without changing the existing
validation around a URI in reindex from remote.
  • Loading branch information
hub-cap committed Dec 20, 2018
1 parent c6e19f4 commit 566c98a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
Expand Up @@ -40,10 +40,10 @@

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;
Expand All @@ -56,7 +56,6 @@
*/
public class RestReindexAction extends AbstractBaseReindexRestHandler<ReindexRequest, ReindexAction> {
static final ObjectParser<ReindexRequest, Void> PARSER = new ObjectParser<>("reindex");
private static final Pattern HOST_PATTERN = Pattern.compile("(?<scheme>[^:]+)://(?<host>[^:]+):(?<port>\\d+)(?<pathPrefix>/.*)?");

static {
ObjectParser.Parser<ReindexRequest, Void> sourceParser = (parser, request, context) -> {
Expand Down Expand Up @@ -136,15 +135,27 @@ static RemoteInfo buildRemoteInfo(Map<String, Object> source) throws IOException
String username = extractString(remote, "username");
String password = extractString(remote, "password");
String hostInRequest = requireNonNull(extractString(remote, "host"), "[host] must be specified to reindex from a remote cluster");
Matcher hostMatcher = HOST_PATTERN.matcher(hostInRequest);
if (false == hostMatcher.matches()) {
URI uri;
try {
uri = new URI(hostInRequest);
// URI has less stringent URL parsing than our code. We want to fail if all values are not provided.
if (uri.getPort() == -1) {
throw new URISyntaxException(hostInRequest, "The port was not defined in the [host]");
}
} catch (URISyntaxException ex) {
throw new IllegalArgumentException("[host] must be of the form [scheme]://[host]:[port](/[pathPrefix])? but was ["
+ hostInRequest + "]");
+ hostInRequest + "]", ex);
}
String scheme = hostMatcher.group("scheme");
String host = hostMatcher.group("host");
String pathPrefix = hostMatcher.group("pathPrefix");
int port = Integer.parseInt(hostMatcher.group("port"));

String scheme = uri.getScheme();
String host = uri.getHost();
int port = uri.getPort();

String pathPrefix = null;
if (uri.getPath().isEmpty() == false) {
pathPrefix = uri.getPath();
}

Map<String, String> headers = extractStringStringMap(remote, "headers");
TimeValue socketTimeout = extractTimeValue(remote, "socket_timeout", RemoteInfo.DEFAULT_SOCKET_TIMEOUT);
TimeValue connectTimeout = extractTimeValue(remote, "connect_timeout", RemoteInfo.DEFAULT_CONNECT_TIMEOUT);
Expand Down
Expand Up @@ -102,6 +102,12 @@ public void testRejectMatchAll() {
assertMatchesTooMuch(random);
}

public void testIPv6Address() {
List<String> whitelist = randomWhitelist();
whitelist.add("[::1]:*");
checkRemoteWhitelist(buildRemoteWhitelist(whitelist), newRemoteInfo("[::1]", 9200));
}

private void assertMatchesTooMuch(List<String> whitelist) {
Exception e = expectThrows(IllegalArgumentException.class, () -> buildRemoteWhitelist(whitelist));
assertEquals("Refusing to start because whitelist " + whitelist + " accepts all addresses. "
Expand Down
Expand Up @@ -78,6 +78,8 @@ public void testBuildRemoteInfoFullyLoaded() throws IOException {

public void testBuildRemoteInfoWithoutAllParts() throws IOException {
expectThrows(IllegalArgumentException.class, () -> buildRemoteInfoHostTestCase("example.com"));
expectThrows(IllegalArgumentException.class, () -> buildRemoteInfoHostTestCase(":9200"));
expectThrows(IllegalArgumentException.class, () -> buildRemoteInfoHostTestCase("http://:9200"));
expectThrows(IllegalArgumentException.class, () -> buildRemoteInfoHostTestCase("example.com:9200"));
expectThrows(IllegalArgumentException.class, () -> buildRemoteInfoHostTestCase("http://example.com"));
}
Expand All @@ -99,6 +101,14 @@ public void testBuildRemoteInfoWithAllHostParts() throws IOException {
assertEquals(RemoteInfo.DEFAULT_SOCKET_TIMEOUT, info.getSocketTimeout());
assertEquals(RemoteInfo.DEFAULT_CONNECT_TIMEOUT, info.getConnectTimeout());

info = buildRemoteInfoHostTestCase("https://[::1]:9201");
assertEquals("https", info.getScheme());
assertEquals("[::1]", info.getHost());
assertEquals(9201, info.getPort());
assertNull(info.getPathPrefix());
assertEquals(RemoteInfo.DEFAULT_SOCKET_TIMEOUT, info.getSocketTimeout());
assertEquals(RemoteInfo.DEFAULT_CONNECT_TIMEOUT, info.getConnectTimeout());

info = buildRemoteInfoHostTestCase("https://other.example.com:9201/");
assertEquals("https", info.getScheme());
assertEquals("other.example.com", info.getHost());
Expand Down

0 comments on commit 566c98a

Please sign in to comment.