mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-22 20:47:57 +01:00
Support for International Domain Names in DNSUtil
This commit is contained in:
parent
f2718c2d76
commit
d3cea48c0d
2 changed files with 78 additions and 9 deletions
|
@ -39,6 +39,23 @@ public class DNSUtil {
|
|||
private static final Logger LOGGER = Logger.getLogger(DNSUtil.class.getName());
|
||||
private static DNSResolver dnsResolver = null;
|
||||
|
||||
/**
|
||||
* International Domain Name transformer.
|
||||
* <p>
|
||||
* Used to transform Unicode representations of the Domain Name to ASCII in
|
||||
* order to perform a DNS request with the ASCII representation.
|
||||
* 'java.net.IDN' is available since Android API 9, but as long as Smack
|
||||
* requires API 8, we are going to need this. This part is going to get
|
||||
* removed once Smack depends on Android API 9 or higher.
|
||||
* </p>
|
||||
*/
|
||||
private static StringTransformer idnaTransformer = new StringTransformer() {
|
||||
@Override
|
||||
public String transform(String string) {
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the DNS resolver that should be used to perform DNS lookups.
|
||||
*
|
||||
|
@ -57,6 +74,27 @@ public class DNSUtil {
|
|||
return dnsResolver;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the IDNA (Internatiionalizing Domain Names in Applications, RFC 3490) transformer.
|
||||
* <p>
|
||||
* You usually want to wrap 'java.net.IDN.toASCII()' into a StringTransformer here.
|
||||
* </p>
|
||||
* @param idnaTransformer
|
||||
*/
|
||||
public static void setIdnaTransformer(StringTransformer idnaTransformer) {
|
||||
if (idnaTransformer == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
DNSUtil.idnaTransformer = idnaTransformer;
|
||||
}
|
||||
|
||||
private static enum DomainType {
|
||||
Server,
|
||||
Client,
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of HostAddresses under which the specified XMPP server can be
|
||||
* reached at for client-to-server communication. A DNS lookup for a SRV
|
||||
|
@ -75,13 +113,15 @@ public class DNSUtil {
|
|||
* XMPP server can be reached at for the specified domain.
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<HostAddress> resolveXMPPDomain(final String domain) throws Exception {
|
||||
public static List<HostAddress> resolveXMPPDomain(String domain) throws Exception {
|
||||
domain = idnaTransformer.transform(domain);
|
||||
if (dnsResolver == null) {
|
||||
LOGGER.warning("No DNS Resolver active in Smack, will be unable to perform DNS SRV lookups");
|
||||
List<HostAddress> addresses = new ArrayList<HostAddress>(1);
|
||||
addresses.add(new HostAddress(domain, 5222));
|
||||
return addresses;
|
||||
}
|
||||
return resolveDomain(domain, 'c');
|
||||
return resolveDomain(domain, DomainType.Client);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,26 +142,31 @@ public class DNSUtil {
|
|||
* XMPP server can be reached at for the specified domain.
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<HostAddress> resolveXMPPServerDomain(final String domain) throws Exception {
|
||||
public static List<HostAddress> resolveXMPPServerDomain(String domain) throws Exception {
|
||||
domain = idnaTransformer.transform(domain);
|
||||
if (dnsResolver == null) {
|
||||
LOGGER.warning("No DNS Resolver active in Smack, will be unable to perform DNS SRV lookups");
|
||||
List<HostAddress> addresses = new ArrayList<HostAddress>(1);
|
||||
addresses.add(new HostAddress(domain, 5269));
|
||||
return addresses;
|
||||
}
|
||||
return resolveDomain(domain, 's');
|
||||
return resolveDomain(domain, DomainType.Server);
|
||||
}
|
||||
|
||||
private static List<HostAddress> resolveDomain(String domain, char keyPrefix) throws Exception {
|
||||
private static List<HostAddress> resolveDomain(String domain, DomainType domainType) throws Exception {
|
||||
List<HostAddress> addresses = new ArrayList<HostAddress>();
|
||||
|
||||
// Step one: Do SRV lookups
|
||||
String srvDomain;
|
||||
if (keyPrefix == 's') {
|
||||
switch (domainType) {
|
||||
case Server:
|
||||
srvDomain = "_xmpp-server._tcp." + domain;
|
||||
} else if (keyPrefix == 'c') {
|
||||
break;
|
||||
case Client:
|
||||
srvDomain = "_xmpp-client._tcp." + domain;
|
||||
} else {
|
||||
srvDomain = domain;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
try {
|
||||
List<SRVRecord> srvRecords = dnsResolver.lookupSRVRecords(srvDomain);
|
||||
|
@ -225,4 +270,5 @@ public class DNSUtil {
|
|||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2014 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.util;
|
||||
|
||||
public interface StringTransformer {
|
||||
|
||||
public String transform(String string);
|
||||
|
||||
}
|
Loading…
Reference in a new issue