diff --git a/htroot/IndexFederated_p.java b/htroot/IndexFederated_p.java index b762c490a..557d5d33b 100644 --- a/htroot/IndexFederated_p.java +++ b/htroot/IndexFederated_p.java @@ -189,7 +189,18 @@ public class IndexFederated_p { prop.put("table", 1); final SolrConnector solr = sb.index.fulltext().getDefaultRemoteSolrConnector(); final long[] size = new long[]{((RemoteSolrConnector) solr).getSize()}; - final ArrayList urls = ((ShardInstance) ((RemoteSolrConnector) solr).getInstance()).getAdminInterfaces(); + + final boolean toExternalAddress = !header.accessFromLocalhost(); + String externalHost = null; + if(toExternalAddress) { + /* The request does not come from the same computer than this peer : we get the external address used to reach it from the request headers, and we will use + * it if some remote solr instance(s) URLs are configured with loopback address alias (such as 'localhost', '127.0.0.1', '[::1]') + * to render the externally reachable Solr instance(s) admin URLs */ + externalHost = header.getServerName(); + } + + final ArrayList urls = ((ShardInstance) ((RemoteSolrConnector) solr).getInstance()) + .getAdminInterfaces(toExternalAddress, externalHost); boolean dark = false; for (int i = 0; i < size.length; i++) { prop.put("table_list_" + i + "_dark", dark ? 1 : 0); dark = !dark; diff --git a/source/net/yacy/cora/document/id/MultiProtocolURL.java b/source/net/yacy/cora/document/id/MultiProtocolURL.java index 1dc973eca..d681b7f21 100644 --- a/source/net/yacy/cora/document/id/MultiProtocolURL.java +++ b/source/net/yacy/cora/document/id/MultiProtocolURL.java @@ -482,6 +482,33 @@ public class MultiProtocolURL implements Serializable, Comparable= 0 && host.charAt(0) != '[') { + copy.host = '[' + host + ']'; // IPv6 host must be enclosed in square brackets + } else { + copy.host = host; + } + + if (!Punycode.isBasic(this.host)) try { + this.host = toPunycode(this.host); + } catch (final PunycodeException e) { + ConcurrentLog.logException(e); + } + + return copy; + + } /** * Resolve '..' segments in the path. diff --git a/source/net/yacy/cora/federate/solr/instance/RemoteInstance.java b/source/net/yacy/cora/federate/solr/instance/RemoteInstance.java index 5e6dc5a50..d3bf67fed 100644 --- a/source/net/yacy/cora/federate/solr/instance/RemoteInstance.java +++ b/source/net/yacy/cora/federate/solr/instance/RemoteInstance.java @@ -21,7 +21,6 @@ package net.yacy.cora.federate.solr.instance; import java.io.IOException; -import java.net.InetAddress; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; @@ -58,7 +57,6 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient; import net.yacy.cora.document.id.MultiProtocolURL; -import net.yacy.cora.protocol.Domains; import net.yacy.cora.protocol.HeaderFramework; import net.yacy.cora.util.CommonPattern; import net.yacy.cora.util.ConcurrentLog; @@ -284,19 +282,35 @@ public class RemoteInstance implements SolrInstance { return o instanceof RemoteInstance && ((RemoteInstance) o).solrurl.equals(this.solrurl); } - /** - * @return the administration URL of the remote Solr instance - */ - public String getAdminInterface() { - final InetAddress localhostExternAddress = Domains.myPublicLocalIP(); - final String localhostExtern = localhostExternAddress == null ? "127.0.0.1" : localhostExternAddress.getHostAddress(); - String u = this.solrurl; - int p = u.indexOf("localhost",0); - if (p < 0) p = u.indexOf("127.0.0.1",0); - if (p < 0) p = u.indexOf("0:0:0:0:0:0:0:1",0); - if (p >= 0) u = u.substring(0, p) + localhostExtern + u.substring(p + 9); - return u; - } + /** + * @param toExternalAddress + * when true, try to replace the eventual loopback host part of the + * Solr URL with the external host name of the hosting machine + * @param externalHost + * the eventual external host name or address to use when + * toExternalAddress is true + * @return the administration URL of the remote Solr instance + */ + public String getAdminInterface(final boolean toExternalAddress, final String externalHost) { + String u = this.solrurl; + if (toExternalAddress && externalHost != null && !externalHost.trim().isEmpty()) { + try { + MultiProtocolURL url = new MultiProtocolURL(u); + + if(url.isLocal()) { + url = url.ofNewHost(externalHost); + u = url.toString(); + } + + } catch (final MalformedURLException ignored) { + /* + * This should not happen as the solrurl attribute has already been parsed in + * the constructor + */ + } + } + return u; + } @Override public String getDefaultCoreName() { diff --git a/source/net/yacy/cora/federate/solr/instance/ShardInstance.java b/source/net/yacy/cora/federate/solr/instance/ShardInstance.java index 62ac1f3a7..b955391d2 100644 --- a/source/net/yacy/cora/federate/solr/instance/ShardInstance.java +++ b/source/net/yacy/cora/federate/solr/instance/ShardInstance.java @@ -81,9 +81,18 @@ public class ShardInstance implements SolrInstance { for (RemoteInstance instance: instances) instance.close(); } - public ArrayList getAdminInterfaces() { + /** + * @param toExternalAddress + * when true, try to replace the eventual loopback host part of the + * Solr instances URLs with the external host name of the hosting machine + * @param externalHost + * the eventual external host name or address to use when + * toExternalAddress is true + * @return the administration URLs of the Solr instances + */ + public ArrayList getAdminInterfaces(final boolean toExternalAddress, final String externalHost) { ArrayList a = new ArrayList(); - for (RemoteInstance i: this.instances) a.add(i.getAdminInterface()); + for (RemoteInstance i: this.instances) a.add(i.getAdminInterface(toExternalAddress, externalHost)); return a; } }