diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java index c08096726..2817c5506 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/DNSUtil.java @@ -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. + *

+ * 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. + *

+ */ + 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. + *

+ * You usually want to wrap 'java.net.IDN.toASCII()' into a StringTransformer here. + *

+ * @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 resolveXMPPDomain(final String domain) throws Exception { + public static List 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 addresses = new ArrayList(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 resolveXMPPServerDomain(final String domain) throws Exception { + public static List 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 addresses = new ArrayList(1); addresses.add(new HostAddress(domain, 5269)); return addresses; } - return resolveDomain(domain, 's'); + return resolveDomain(domain, DomainType.Server); } - private static List resolveDomain(String domain, char keyPrefix) throws Exception { + private static List resolveDomain(String domain, DomainType domainType) throws Exception { List addresses = new ArrayList(); // 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 srvRecords = dnsResolver.lookupSRVRecords(srvDomain); @@ -225,4 +270,5 @@ public class DNSUtil { } return pos; } + } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringTransformer.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringTransformer.java new file mode 100644 index 000000000..701ee2953 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringTransformer.java @@ -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); + +}