summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/handlers/directory.py6
-rw-r--r--synapse/http/client.py25
-rw-r--r--tests/handlers/test_directory.py6
3 files changed, 29 insertions, 8 deletions
diff --git a/synapse/handlers/directory.py b/synapse/handlers/directory.py
index 7c89150d99..2e9c6b688b 100644
--- a/synapse/handlers/directory.py
+++ b/synapse/handlers/directory.py
@@ -18,6 +18,7 @@ from twisted.internet import defer
 from ._base import BaseHandler
 
 from synapse.api.errors import SynapseError
+from synapse.http.client import HttpClient
 
 import logging
 
@@ -68,7 +69,10 @@ class DirectoryHandler(BaseHandler):
             result = yield self.federation.make_query(
                 destination=room_alias.domain,
                 query_type="directory",
-                args={"room_alias": room_alias.to_string()},
+                args={
+                    "room_alias": room_alias.to_string(),
+                    HttpClient.RETRY_DNS_LOOKUP_FAILURES: False
+                }
             )
 
             if result and "room_id" in result and "servers" in result:
diff --git a/synapse/http/client.py b/synapse/http/client.py
index 709c952226..f74e3eca73 100644
--- a/synapse/http/client.py
+++ b/synapse/http/client.py
@@ -44,6 +44,7 @@ _destination_mappings = {
 class HttpClient(object):
     """ Interface for talking json over http
     """
+    RETRY_DNS_LOOKUP_FAILURES = "__retry_dns"
 
     def put_json(self, destination, path, data):
         """ Sends the specifed json data using PUT
@@ -143,13 +144,23 @@ class TwistedHttpClient(HttpClient):
             destination = _destination_mappings[destination]
 
         logger.debug("get_json args: %s", args)
+
+        retry_on_dns_fail = True
+        if HttpClient.RETRY_DNS_LOOKUP_FAILURES in args:
+            # FIXME: This isn't ideal, but the interface exposed in get_json
+            # isn't comprehensive enough to give caller's any control over
+            # their connection mechanics.
+            retry_on_dns_fail = args.pop(HttpClient.RETRY_DNS_LOOKUP_FAILURES)
+
         query_bytes = urllib.urlencode(args, True)
+        logger.debug("Query bytes: %s Retry DNS: %s", args, retry_on_dns_fail)
 
         response = yield self._create_request(
             destination.encode("ascii"),
             "GET",
             path.encode("ascii"),
-            query_bytes=query_bytes
+            query_bytes=query_bytes,
+            retry_on_dns_fail=retry_on_dns_fail
         )
 
         body = yield readBody(response)
@@ -158,7 +169,8 @@ class TwistedHttpClient(HttpClient):
 
     @defer.inlineCallbacks
     def _create_request(self, destination, method, path_bytes, param_bytes=b"",
-                        query_bytes=b"", producer=None, headers_dict={}):
+                        query_bytes=b"", producer=None, headers_dict={},
+                        retry_on_dns_fail=True):
         """ Creates and sends a request to the given url
         """
         headers_dict[b"User-Agent"] = [b"Synapse"]
@@ -199,11 +211,12 @@ class TwistedHttpClient(HttpClient):
 
                 logger.debug("Got response to %s", method)
                 break
-            except DNSLookupError as dns:
-                logger.warn("DNS Lookup failed to %s with %s", destination,
-                            dns)
-                raise SynapseError(400, "Domain specified not found.")
             except Exception as e:
+                if not retry_on_dns_fail and isinstance(e, DNSLookupError):
+                    logger.warn("DNS Lookup failed to %s with %s", destination,
+                                e)
+                    raise SynapseError(400, "Domain specified not found.")
+
                 logger.exception("Got error in _create_request")
                 _print_ex(e)
 
diff --git a/tests/handlers/test_directory.py b/tests/handlers/test_directory.py
index 88ac8933f8..e509c1b629 100644
--- a/tests/handlers/test_directory.py
+++ b/tests/handlers/test_directory.py
@@ -21,6 +21,7 @@ from mock import Mock
 import logging
 
 from synapse.server import HomeServer
+from synapse.http.client import HttpClient
 from synapse.handlers.directory import DirectoryHandler
 from synapse.storage.directory import RoomAliasMapping
 
@@ -92,7 +93,10 @@ class DirectoryTestCase(unittest.TestCase):
         self.mock_federation.make_query.assert_called_with(
             destination="remote",
             query_type="directory",
-            args={"room_alias": "#another:remote"}
+            args={
+                "room_alias": "#another:remote",
+                HttpClient.RETRY_DNS_LOOKUP_FAILURES: False
+            }
         )
 
     @defer.inlineCallbacks