]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Add canonical_name() to async resolver too. 542/head
authorBob Halley <halley@dnspython.org>
Mon, 20 Jul 2020 13:12:32 +0000 (06:12 -0700)
committerBob Halley <halley@dnspython.org>
Mon, 20 Jul 2020 13:18:43 +0000 (06:18 -0700)
dns/asyncresolver.py
doc/async-resolver-functions.rst
tests/test_async.py

index 3ac334f505c42999aceb7eddea8fae03c28d70c3..0aaeb9c9637c4b6fdf2aa4172a1677a5c945e17b 100644 (file)
@@ -165,6 +165,28 @@ class Resolver(dns.resolver.Resolver):
                                   rdclass=dns.rdataclass.IN,
                                   *args, **kwargs)
 
+    async def canonical_name(self, name):
+        """Determine the canonical name of *name*.
+
+        The canonical name is the name the resolver uses for queries
+        after all CNAME and DNAME renamings have been applied.
+
+        *name*, a ``dns.name.Name`` or ``str``, the query name.
+
+        This method can raise any exception that ``resolve()`` can
+        raise, other than ``dns.resolver.NoAnswer`` and
+        ``dns.resolver.NXDOMAIN``.
+
+        Returns a ``dns.name.Name``.
+        """
+        try:
+            answer = await self.resolve(name, raise_on_no_answer=False)
+            canonical_name = answer.canonical_name
+        except dns.resolver.NXDOMAIN as e:
+            canonical_name = e.canonical_name
+        return canonical_name
+
+
 default_resolver = None
 
 
@@ -212,6 +234,14 @@ async def resolve_address(ipaddr, *args, **kwargs):
 
     return await get_default_resolver().resolve_address(ipaddr, *args, **kwargs)
 
+async def canonical_name(name):
+    """Determine the canonical name of *name*.
+
+    See ``dns.resolver.Resolver.canonical_name`` for more information on the
+    parameters and possible exceptions.
+    """
+
+    return await get_default_resolver().canonical_name(name)
 
 async def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False,
                         resolver=None, backend=None):
index fc5798ab35f5b9f37acf0d77ab87295e1a618878..b2669f32ec56722b50df5852c4a724b4595aaecd 100644 (file)
@@ -5,4 +5,5 @@ Asynchronous Resolver Functions
 
 .. autofunction:: dns.asyncresolver.resolve
 .. autofunction:: dns.asyncresolver.resolve_address
+.. autofunction:: dns.asyncresolver.canonical_name
 .. autofunction:: dns.asyncresolver.zone_for_name
index db108c8197abd919875cf65e1b045632d6bf3e5d..690a1ebdeb9435f7eee391a6cc990c6afd62219e 100644 (file)
@@ -182,6 +182,26 @@ class AsyncTests(unittest.TestCase):
         dnsgoogle = dns.name.from_text('dns.google.')
         self.assertEqual(answer[0].target, dnsgoogle)
 
+    def testCanonicalNameNoCNAME(self):
+        cname = dns.name.from_text('www.google.com')
+        async def run():
+            return await dns.asyncresolver.canonical_name('www.google.com')
+        self.assertEqual(self.async_run(run), cname)
+
+    def testCanonicalNameCNAME(self):
+        name = dns.name.from_text('www.dnspython.org')
+        cname = dns.name.from_text('dmfrjf4ips8xa.cloudfront.net')
+        async def run():
+            return await dns.asyncresolver.canonical_name(name)
+        self.assertEqual(self.async_run(run), cname)
+
+    def testCanonicalNameDangling(self):
+        name = dns.name.from_text('dangling-cname.dnspython.org')
+        cname = dns.name.from_text('dangling-target.dnspython.org')
+        async def run():
+            return await dns.asyncresolver.canonical_name(name)
+        self.assertEqual(self.async_run(run), cname)
+
     def testResolverBadScheme(self):
         res = dns.asyncresolver.Resolver(configure=False)
         res.nameservers = ['bogus://dns.google/dns-query']