def test_non_srv_answer(self): """ test the behaviour when the dns server gives us a spurious non-SRV response """ service_name = b"test_service.example.com" lookup_deferred = Deferred() dns_client_mock = Mock() dns_client_mock.lookupService.return_value = lookup_deferred cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) resolve_d = resolver.resolve_service(service_name) self.assertNoResult(resolve_d) lookup_deferred.callback( ( [ dns.RRHeader(type=dns.A, payload=dns.Record_A()), dns.RRHeader(type=dns.SRV, payload=dns.Record_SRV(target=b"host")), ], None, None, ) ) servers = self.successResultOf(resolve_d) self.assertEquals(len(servers), 1) self.assertEquals(servers, cache[service_name]) self.assertEquals(servers[0].host, b"host")
def test_disabled_service(self): """ test the behaviour when there is a single record which is ".". """ service_name = b"test_service.example.com" lookup_deferred = Deferred() dns_client_mock = Mock() dns_client_mock.lookupService.return_value = lookup_deferred cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) # Old versions of Twisted don't have an ensureDeferred in failureResultOf. resolve_d = defer.ensureDeferred(resolver.resolve_service(service_name)) # returning a single "." should make the lookup fail with a ConenctError lookup_deferred.callback( ( [dns.RRHeader(type=dns.SRV, payload=dns.Record_SRV(target=b"."))], None, None, ) ) self.failureResultOf(resolve_d, ConnectError)
def test_from_cache(self): clock = MockClock() dns_client_mock = Mock(spec_set=["lookupService"]) dns_client_mock.lookupService = Mock(spec_set=[]) service_name = b"test_service.example.com" entry = Mock(spec_set=["expires", "priority", "weight"]) entry.expires = 999999999 entry.priority = 0 entry.weight = 0 cache = {service_name: [entry]} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache, get_time=clock.time) servers = yield defer.ensureDeferred( resolver.resolve_service(service_name)) self.assertFalse(dns_client_mock.lookupService.called) self.assertEquals(len(servers), 1) self.assertEquals(servers, cache[service_name])
def test_disabled_service(self): """ test the behaviour when there is a single record which is ".". """ service_name = b"test_service.example.com" lookup_deferred = Deferred() dns_client_mock = Mock() dns_client_mock.lookupService.return_value = lookup_deferred cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) resolve_d = resolver.resolve_service(service_name) self.assertNoResult(resolve_d) # returning a single "." should make the lookup fail with a ConenctError lookup_deferred.callback( ( [dns.RRHeader(type=dns.SRV, payload=dns.Record_SRV(target=b"."))], None, None, ) ) self.failureResultOf(resolve_d, ConnectError)
def test_non_srv_answer(self): """ test the behaviour when the dns server gives us a spurious non-SRV response """ service_name = b"test_service.example.com" lookup_deferred = Deferred() dns_client_mock = Mock() dns_client_mock.lookupService.return_value = lookup_deferred cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) resolve_d = resolver.resolve_service(service_name) self.assertNoResult(resolve_d) lookup_deferred.callback(( [ dns.RRHeader(type=dns.A, payload=dns.Record_A()), dns.RRHeader(type=dns.SRV, payload=dns.Record_SRV(target=b"host")), ], None, None, )) servers = self.successResultOf(resolve_d) self.assertEquals(len(servers), 1) self.assertEquals(servers, cache[service_name]) self.assertEquals(servers[0].host, b"host")
def test_empty_cache(self): dns_client_mock = Mock() dns_client_mock.lookupService.return_value = defer.fail(error.DNSServerError()) service_name = b"test_service.example.com" cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) with self.assertRaises(error.DNSServerError): yield defer.ensureDeferred(resolver.resolve_service(service_name))
def test_empty_cache(self): dns_client_mock = Mock() dns_client_mock.lookupService.return_value = defer.fail(error.DNSServerError()) service_name = b"test_service.example.com" cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) with self.assertRaises(error.DNSServerError): yield resolver.resolve_service(service_name)
def test_name_error(self): dns_client_mock = Mock() dns_client_mock.lookupService.return_value = defer.fail(error.DNSNameError()) service_name = b"test_service.example.com" cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) servers = yield defer.ensureDeferred(resolver.resolve_service(service_name)) self.assertEqual(len(servers), 0) self.assertEqual(len(cache), 0)
def test_name_error(self): dns_client_mock = Mock() dns_client_mock.lookupService.return_value = defer.fail(error.DNSNameError()) service_name = b"test_service.example.com" cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) servers = yield resolver.resolve_service(service_name) self.assertEquals(len(servers), 0) self.assertEquals(len(cache), 0)
def __init__( self, reactor, tls_client_options_factory, _srv_resolver=None, _well_known_cache=None, ): self._reactor = reactor self._clock = Clock(reactor) self._tls_client_options_factory = tls_client_options_factory if _srv_resolver is None: _srv_resolver = SrvResolver() self._srv_resolver = _srv_resolver self._pool = HTTPConnectionPool(reactor) self._pool.retryAutomatically = False self._pool.maxPersistentPerHost = 5 self._pool.cachedConnectionTimeout = 2 * 60 self._well_known_resolver = WellKnownResolver( self._reactor, agent=Agent( self._reactor, pool=self._pool, contextFactory=tls_client_options_factory, ), well_known_cache=_well_known_cache, )
def __init__( self, reactor, tls_client_options_factory, _well_known_tls_policy=None, _srv_resolver=None, _well_known_cache=well_known_cache, ): self._reactor = reactor self._clock = Clock(reactor) self._tls_client_options_factory = tls_client_options_factory if _srv_resolver is None: _srv_resolver = SrvResolver() self._srv_resolver = _srv_resolver self._pool = HTTPConnectionPool(reactor) self._pool.retryAutomatically = False self._pool.maxPersistentPerHost = 5 self._pool.cachedConnectionTimeout = 2 * 60 agent_args = {} if _well_known_tls_policy is not None: # the param is called 'contextFactory', but actually passing a # contextfactory is deprecated, and it expects an IPolicyForHTTPS. agent_args['contextFactory'] = _well_known_tls_policy _well_known_agent = RedirectAgent( Agent(self._reactor, pool=self._pool, **agent_args), ) self._well_known_agent = _well_known_agent # our cache of .well-known lookup results, mapping from server name # to delegated name. The values can be: # `bytes`: a valid server-name # `None`: there is no (valid) .well-known here self._well_known_cache = _well_known_cache
def __init__(self, reactor, tls_client_options_factory, srv_resolver): self._reactor = reactor self._tls_client_options_factory = tls_client_options_factory if srv_resolver is None: srv_resolver = SrvResolver() self._srv_resolver = srv_resolver
def test_from_cache_expired_and_dns_fail(self): dns_client_mock = Mock() dns_client_mock.lookupService.return_value = defer.fail(error.DNSServerError()) service_name = b"test_service.example.com" entry = Mock(spec_set=["expires"]) entry.expires = 0 cache = {service_name: [entry]} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) servers = yield resolver.resolve_service(service_name) dns_client_mock.lookupService.assert_called_once_with(service_name) self.assertEquals(len(servers), 1) self.assertEquals(servers, cache[service_name])
def test_from_cache(self): clock = MockClock() dns_client_mock = Mock(spec_set=['lookupService']) dns_client_mock.lookupService = Mock(spec_set=[]) service_name = b"test_service.example.com" entry = Mock(spec_set=["expires"]) entry.expires = 999999999 cache = {service_name: [entry]} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache, get_time=clock.time) servers = yield resolver.resolve_service(service_name) self.assertFalse(dns_client_mock.lookupService.called) self.assertEquals(len(servers), 1) self.assertEquals(servers, cache[service_name])
def test_from_cache(self): clock = MockClock() dns_client_mock = Mock(spec_set=['lookupService']) dns_client_mock.lookupService = Mock(spec_set=[]) service_name = b"test_service.example.com" entry = Mock(spec_set=["expires"]) entry.expires = 999999999 cache = {service_name: [entry]} resolver = SrvResolver( dns_client=dns_client_mock, cache=cache, get_time=clock.time ) servers = yield resolver.resolve_service(service_name) self.assertFalse(dns_client_mock.lookupService.called) self.assertEquals(len(servers), 1) self.assertEquals(servers, cache[service_name])
def __init__( self, reactor: IReactorCore, tls_client_options_factory: Optional[FederationPolicyForHTTPS], srv_resolver: Optional[SrvResolver], ): self._reactor = reactor self._tls_client_options_factory = tls_client_options_factory if srv_resolver is None: srv_resolver = SrvResolver() self._srv_resolver = srv_resolver
def test_resolve(self): dns_client_mock = Mock() service_name = b"test_service.example.com" host_name = b"example.com" answer_srv = dns.RRHeader(type=dns.SRV, payload=dns.Record_SRV(target=host_name)) result_deferred = Deferred() dns_client_mock.lookupService.return_value = result_deferred cache = {} resolver = SrvResolver(dns_client=dns_client_mock, cache=cache) @defer.inlineCallbacks def do_lookup(): with LoggingContext("one") as ctx: resolve_d = resolver.resolve_service(service_name) self.assertNoResult(resolve_d) # should have reset to the sentinel context self.assertIs(LoggingContext.current_context(), LoggingContext.sentinel) result = yield resolve_d # should have restored our context self.assertIs(LoggingContext.current_context(), ctx) defer.returnValue(result) test_d = do_lookup() self.assertNoResult(test_d) dns_client_mock.lookupService.assert_called_once_with(service_name) result_deferred.callback(([answer_srv], None, None)) servers = self.successResultOf(test_d) self.assertEquals(len(servers), 1) self.assertEquals(servers, cache[service_name]) self.assertEquals(servers[0].host, host_name)
def __init__( self, reactor: IReactorCore, proxy_reactor: IReactorCore, tls_client_options_factory: Optional[FederationPolicyForHTTPS], srv_resolver: Optional[SrvResolver], https_proxy: Optional[bytes] = None, ): self._reactor = reactor self._tls_client_options_factory = tls_client_options_factory if srv_resolver is None: srv_resolver = SrvResolver() self._srv_resolver = srv_resolver self.https_proxy_creds, https_proxy = parse_username_password(https_proxy) self.https_proxy_endpoint = proxyagent.http_proxy_endpoint( https_proxy, proxy_reactor )