From 8e75be0f9c8cdf0a42dfcb901578dbc961376eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Tue, 1 Mar 2022 15:03:05 +0100 Subject: [PATCH 1/9] add low-level `resolveQuery` function. this allows to extend the given classes and more flexible for owner use. --- src/Resolver/Factory.php | 18 +++++++++++++++--- src/Resolver/Resolver.php | 12 ++++++++---- src/Resolver/ResolverInterface.php | 20 ++++++++++++++++++++ tests/FunctionalResolverTest.php | 12 ++++++++++++ 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/Resolver/Factory.php b/src/Resolver/Factory.php index 5fe608cb..12135425 100644 --- a/src/Resolver/Factory.php +++ b/src/Resolver/Factory.php @@ -19,8 +19,20 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -final class Factory +class Factory { + + /** + * Allow the developer to specify a custom additional ExecutorInterface + * or ResolverInterface in an extended Class. + * @param ExecutorInterface $executor + * @return ResolverInterface + */ + protected function wrapInResolver(ExecutorInterface $executor) + { + return new Resolver($executor); + } + /** * Creates a DNS resolver instance for the given DNS config * @@ -40,7 +52,7 @@ public function create($config, LoopInterface $loop = null) { $executor = $this->decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get())); - return new Resolver($executor); + return $this->wrapInResolver($executor); } /** @@ -70,7 +82,7 @@ public function createCached($config, LoopInterface $loop = null, CacheInterface $executor = new CachingExecutor($executor, $cache); $executor = $this->decorateHostsFileExecutor($executor); - return new Resolver($executor); + return $this->wrapInResolver($executor); } /** diff --git a/src/Resolver/Resolver.php b/src/Resolver/Resolver.php index 92926f3f..5a110bdf 100644 --- a/src/Resolver/Resolver.php +++ b/src/Resolver/Resolver.php @@ -12,7 +12,7 @@ */ final class Resolver implements ResolverInterface { - private $executor; + protected $executor; public function __construct(ExecutorInterface $executor) { @@ -31,13 +31,17 @@ public function resolveAll($domain, $type) $query = new Query($domain, $type, Message::CLASS_IN); $that = $this; - return $this->executor->query( - $query - )->then(function (Message $response) use ($query, $that) { + return $this->resolveQuery($query)->then(function (Message $response) use ($query, $that) { return $that->extractValues($query, $response); }); } + public function resolveQuery(Query $query) + { + return $this->executor->query($query); + } + + /** * [Internal] extract all resource record values from response for this query * diff --git a/src/Resolver/ResolverInterface.php b/src/Resolver/ResolverInterface.php index fe937dc7..011ab490 100644 --- a/src/Resolver/ResolverInterface.php +++ b/src/Resolver/ResolverInterface.php @@ -2,6 +2,9 @@ namespace React\Dns\Resolver; +use React\Dns\Model\Message; +use React\Dns\Query\Query; + interface ResolverInterface { /** @@ -91,4 +94,21 @@ public function resolve($domain); * Resolves with all record values on success or rejects with an Exception on error. */ public function resolveAll($domain, $type); + + /** + * @param Query $query + * @return \React\Promise\PromiseInterface + * + * This is the magic behind the main function of this package. It allows you to use low-level + * DNS query objects to send custom DNS queries to your DNS server. + * + * ```php + * $resolver->resolveQuery(new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN))->then(function (Message $message) { + * foreach($message->answers as $record) { + * echo 'IPv4 addresses for reactphp.org ' . $record->data . PHP_EOL; + * } + * }); + * ``` + */ + public function resolveQuery(Query $query); } diff --git a/tests/FunctionalResolverTest.php b/tests/FunctionalResolverTest.php index 9cb05615..8f848d66 100644 --- a/tests/FunctionalResolverTest.php +++ b/tests/FunctionalResolverTest.php @@ -2,6 +2,7 @@ namespace React\Tests\Dns; +use React\Dns\Query\Query; use React\EventLoop\Factory as LoopFactory; use React\Dns\Resolver\Factory; use React\Dns\RecordNotFoundException; @@ -47,6 +48,17 @@ public function testResolveGoogleResolves() $this->loop->run(); } + /** + * @group internet + */ + public function testResolveQueryGoogleResolves() + { + $promise = $this->resolver->resolveQuery(new Query('google.com', Message::TYPE_A, Message::CLASS_IN)); + $promise->then($this->expectCallableOnceWith($this->isInstanceOf('React\Dns\Model\Message')), $this->expectCallableNever()); + + $this->loop->run(); + } + /** * @group internet */ From 706f60bd20349abd6090bf7e84dcaa5adc68c3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Wed, 2 Mar 2022 10:08:04 +0100 Subject: [PATCH 2/9] Revert "add low-level `resolveQuery` function. this allows to extend the given classes and more flexible for owner use." This reverts commit 8e75be0f9c8cdf0a42dfcb901578dbc961376eb7. --- src/Resolver/Factory.php | 18 +++--------------- src/Resolver/Resolver.php | 12 ++++-------- src/Resolver/ResolverInterface.php | 20 -------------------- tests/FunctionalResolverTest.php | 12 ------------ 4 files changed, 7 insertions(+), 55 deletions(-) diff --git a/src/Resolver/Factory.php b/src/Resolver/Factory.php index 12135425..5fe608cb 100644 --- a/src/Resolver/Factory.php +++ b/src/Resolver/Factory.php @@ -19,20 +19,8 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -class Factory +final class Factory { - - /** - * Allow the developer to specify a custom additional ExecutorInterface - * or ResolverInterface in an extended Class. - * @param ExecutorInterface $executor - * @return ResolverInterface - */ - protected function wrapInResolver(ExecutorInterface $executor) - { - return new Resolver($executor); - } - /** * Creates a DNS resolver instance for the given DNS config * @@ -52,7 +40,7 @@ public function create($config, LoopInterface $loop = null) { $executor = $this->decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get())); - return $this->wrapInResolver($executor); + return new Resolver($executor); } /** @@ -82,7 +70,7 @@ public function createCached($config, LoopInterface $loop = null, CacheInterface $executor = new CachingExecutor($executor, $cache); $executor = $this->decorateHostsFileExecutor($executor); - return $this->wrapInResolver($executor); + return new Resolver($executor); } /** diff --git a/src/Resolver/Resolver.php b/src/Resolver/Resolver.php index 5a110bdf..92926f3f 100644 --- a/src/Resolver/Resolver.php +++ b/src/Resolver/Resolver.php @@ -12,7 +12,7 @@ */ final class Resolver implements ResolverInterface { - protected $executor; + private $executor; public function __construct(ExecutorInterface $executor) { @@ -31,17 +31,13 @@ public function resolveAll($domain, $type) $query = new Query($domain, $type, Message::CLASS_IN); $that = $this; - return $this->resolveQuery($query)->then(function (Message $response) use ($query, $that) { + return $this->executor->query( + $query + )->then(function (Message $response) use ($query, $that) { return $that->extractValues($query, $response); }); } - public function resolveQuery(Query $query) - { - return $this->executor->query($query); - } - - /** * [Internal] extract all resource record values from response for this query * diff --git a/src/Resolver/ResolverInterface.php b/src/Resolver/ResolverInterface.php index 011ab490..fe937dc7 100644 --- a/src/Resolver/ResolverInterface.php +++ b/src/Resolver/ResolverInterface.php @@ -2,9 +2,6 @@ namespace React\Dns\Resolver; -use React\Dns\Model\Message; -use React\Dns\Query\Query; - interface ResolverInterface { /** @@ -94,21 +91,4 @@ public function resolve($domain); * Resolves with all record values on success or rejects with an Exception on error. */ public function resolveAll($domain, $type); - - /** - * @param Query $query - * @return \React\Promise\PromiseInterface - * - * This is the magic behind the main function of this package. It allows you to use low-level - * DNS query objects to send custom DNS queries to your DNS server. - * - * ```php - * $resolver->resolveQuery(new Query('reactphp.org', Message::TYPE_A, Message::CLASS_IN))->then(function (Message $message) { - * foreach($message->answers as $record) { - * echo 'IPv4 addresses for reactphp.org ' . $record->data . PHP_EOL; - * } - * }); - * ``` - */ - public function resolveQuery(Query $query); } diff --git a/tests/FunctionalResolverTest.php b/tests/FunctionalResolverTest.php index 8f848d66..9cb05615 100644 --- a/tests/FunctionalResolverTest.php +++ b/tests/FunctionalResolverTest.php @@ -2,7 +2,6 @@ namespace React\Tests\Dns; -use React\Dns\Query\Query; use React\EventLoop\Factory as LoopFactory; use React\Dns\Resolver\Factory; use React\Dns\RecordNotFoundException; @@ -48,17 +47,6 @@ public function testResolveGoogleResolves() $this->loop->run(); } - /** - * @group internet - */ - public function testResolveQueryGoogleResolves() - { - $promise = $this->resolver->resolveQuery(new Query('google.com', Message::TYPE_A, Message::CLASS_IN)); - $promise->then($this->expectCallableOnceWith($this->isInstanceOf('React\Dns\Model\Message')), $this->expectCallableNever()); - - $this->loop->run(); - } - /** * @group internet */ From 4a9886fc1def0f5450a8deaf8cc8c0e925f3cbae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Wed, 2 Mar 2022 10:22:27 +0100 Subject: [PATCH 3/9] split Resolver-Factory and Executer-Factory --- src/Query/ExecuterFactory.php | 203 ++++++++++++++++++++++++++++++++++ src/Resolver/Factory.php | 174 ++--------------------------- 2 files changed, 210 insertions(+), 167 deletions(-) create mode 100644 src/Query/ExecuterFactory.php diff --git a/src/Query/ExecuterFactory.php b/src/Query/ExecuterFactory.php new file mode 100644 index 00000000..643336b6 --- /dev/null +++ b/src/Query/ExecuterFactory.php @@ -0,0 +1,203 @@ +decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get())); + } + + /** + * Creates a cached DNS executer instance for the given DNS config and cache + * + * As of v1.7.0 it's recommended to pass a `Config` object instead of a + * single nameserver address. If the given config contains more than one DNS + * nameserver, all DNS nameservers will be used in order. The primary DNS + * server will always be used first before falling back to the secondary or + * tertiary DNS server. + * + * @param Config|string $config DNS Config object (recommended) or single nameserver address + * @param ?LoopInterface $loop + * @param ?CacheInterface $cache + * @return ExecutorInterface|HostsFileExecutor + * @throws \InvalidArgumentException for invalid DNS server address + * @throws \UnderflowException when given DNS Config object has an empty list of nameservers + */ + public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null) + { + // default to keeping maximum of 256 responses in cache unless explicitly given + if (!($cache instanceof CacheInterface)) { + $cache = new ArrayCache(256); + } + + $executor = $this->createExecutor($config, $loop ?: Loop::get()); + $executor = new CachingExecutor($executor, $cache); + $executor = $this->decorateHostsFileExecutor($executor); + + return $executor; + } + + /** + * Tries to load the hosts file and decorates the given executor on success + * + * @param ExecutorInterface $executor + * @return ExecutorInterface + * @codeCoverageIgnore + */ + protected function decorateHostsFileExecutor(ExecutorInterface $executor) + { + try { + $executor = new HostsFileExecutor( + HostsFile::loadFromPathBlocking(), + $executor + ); + } catch (\RuntimeException $e) { + // ignore this file if it can not be loaded + } + + // Windows does not store localhost in hosts file by default but handles this internally + // To compensate for this, we explicitly use hard-coded defaults for localhost + if (DIRECTORY_SEPARATOR === '\\') { + $executor = new HostsFileExecutor( + new HostsFile("127.0.0.1 localhost\n::1 localhost"), + $executor + ); + } + + return $executor; + } + + /** + * @param Config|string $nameserver + * @param LoopInterface $loop + * @return CoopExecutor + * @throws \InvalidArgumentException for invalid DNS server address + * @throws \UnderflowException when given DNS Config object has an empty list of nameservers + */ + protected function createExecutor($nameserver, LoopInterface $loop) + { + if ($nameserver instanceof Config) { + if (!$nameserver->nameservers) { + throw new \UnderflowException('Empty config with no DNS servers'); + } + + // Hard-coded to check up to 3 DNS servers to match default limits in place in most systems (see MAXNS config). + // Note to future self: Recursion isn't too hard, but how deep do we really want to go? + $primary = reset($nameserver->nameservers); + $secondary = next($nameserver->nameservers); + $tertiary = next($nameserver->nameservers); + + if ($tertiary !== false) { + // 3 DNS servers given => nest first with fallback for second and third + return new CoopExecutor( + new RetryExecutor( + new FallbackExecutor( + $this->createSingleExecutor($primary, $loop), + new FallbackExecutor( + $this->createSingleExecutor($secondary, $loop), + $this->createSingleExecutor($tertiary, $loop) + ) + ) + ) + ); + } elseif ($secondary !== false) { + // 2 DNS servers given => fallback from first to second + return new CoopExecutor( + new RetryExecutor( + new FallbackExecutor( + $this->createSingleExecutor($primary, $loop), + $this->createSingleExecutor($secondary, $loop) + ) + ) + ); + } else { + // 1 DNS server given => use single executor + $nameserver = $primary; + } + } + + return new CoopExecutor(new RetryExecutor($this->createSingleExecutor($nameserver, $loop))); + } + + /** + * @param string $nameserver + * @param LoopInterface $loop + * @return ExecutorInterface + * @throws \InvalidArgumentException for invalid DNS server address + */ + protected function createSingleExecutor($nameserver, LoopInterface $loop) + { + $parts = \parse_url($nameserver); + + if (isset($parts['scheme']) && $parts['scheme'] === 'tcp') { + $executor = $this->createTcpExecutor($nameserver, $loop); + } elseif (isset($parts['scheme']) && $parts['scheme'] === 'udp') { + $executor = $this->createUdpExecutor($nameserver, $loop); + } else { + $executor = new SelectiveTransportExecutor( + $this->createUdpExecutor($nameserver, $loop), + $this->createTcpExecutor($nameserver, $loop) + ); + } + + return $executor; + } + + /** + * @param string $nameserver + * @param LoopInterface $loop + * @return TimeoutExecutor + * @throws \InvalidArgumentException for invalid DNS server address + */ + protected function createTcpExecutor($nameserver, LoopInterface $loop) + { + return new TimeoutExecutor( + new TcpTransportExecutor($nameserver, $loop), + 5.0, + $loop + ); + } + + /** + * @param string $nameserver + * @param LoopInterface $loop + * @return TimeoutExecutor + * @throws \InvalidArgumentException for invalid DNS server address + */ + protected function createUdpExecutor($nameserver, LoopInterface $loop) + { + return new TimeoutExecutor( + new UdpTransportExecutor( + $nameserver, + $loop + ), + 5.0, + $loop + ); + } +} \ No newline at end of file diff --git a/src/Resolver/Factory.php b/src/Resolver/Factory.php index 5fe608cb..8ab4534b 100644 --- a/src/Resolver/Factory.php +++ b/src/Resolver/Factory.php @@ -2,24 +2,12 @@ namespace React\Dns\Resolver; -use React\Cache\ArrayCache; use React\Cache\CacheInterface; use React\Dns\Config\Config; -use React\Dns\Config\HostsFile; -use React\Dns\Query\CachingExecutor; -use React\Dns\Query\CoopExecutor; -use React\Dns\Query\ExecutorInterface; -use React\Dns\Query\FallbackExecutor; -use React\Dns\Query\HostsFileExecutor; -use React\Dns\Query\RetryExecutor; -use React\Dns\Query\SelectiveTransportExecutor; -use React\Dns\Query\TcpTransportExecutor; -use React\Dns\Query\TimeoutExecutor; -use React\Dns\Query\UdpTransportExecutor; -use React\EventLoop\Loop; +use React\Dns\Query\ExecuterFactory; use React\EventLoop\LoopInterface; -final class Factory +final class Factory extends ExecuterFactory { /** * Creates a DNS resolver instance for the given DNS config @@ -30,7 +18,7 @@ final class Factory * server will always be used first before falling back to the secondary or * tertiary DNS server. * - * @param Config|string $config DNS Config object (recommended) or single nameserver address + * @param Config|string $config DNS Config object (recommended) or single nameserver address * @param ?LoopInterface $loop * @return \React\Dns\Resolver\ResolverInterface * @throws \InvalidArgumentException for invalid DNS server address @@ -38,9 +26,7 @@ final class Factory */ public function create($config, LoopInterface $loop = null) { - $executor = $this->decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get())); - - return new Resolver($executor); + return new Resolver(parent::create($config, $loop)); } /** @@ -52,8 +38,8 @@ public function create($config, LoopInterface $loop = null) * server will always be used first before falling back to the secondary or * tertiary DNS server. * - * @param Config|string $config DNS Config object (recommended) or single nameserver address - * @param ?LoopInterface $loop + * @param Config|string $config DNS Config object (recommended) or single nameserver address + * @param ?LoopInterface $loop * @param ?CacheInterface $cache * @return \React\Dns\Resolver\ResolverInterface * @throws \InvalidArgumentException for invalid DNS server address @@ -61,154 +47,8 @@ public function create($config, LoopInterface $loop = null) */ public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null) { - // default to keeping maximum of 256 responses in cache unless explicitly given - if (!($cache instanceof CacheInterface)) { - $cache = new ArrayCache(256); - } - - $executor = $this->createExecutor($config, $loop ?: Loop::get()); - $executor = new CachingExecutor($executor, $cache); - $executor = $this->decorateHostsFileExecutor($executor); - - return new Resolver($executor); - } - - /** - * Tries to load the hosts file and decorates the given executor on success - * - * @param ExecutorInterface $executor - * @return ExecutorInterface - * @codeCoverageIgnore - */ - private function decorateHostsFileExecutor(ExecutorInterface $executor) - { - try { - $executor = new HostsFileExecutor( - HostsFile::loadFromPathBlocking(), - $executor - ); - } catch (\RuntimeException $e) { - // ignore this file if it can not be loaded - } - - // Windows does not store localhost in hosts file by default but handles this internally - // To compensate for this, we explicitly use hard-coded defaults for localhost - if (DIRECTORY_SEPARATOR === '\\') { - $executor = new HostsFileExecutor( - new HostsFile("127.0.0.1 localhost\n::1 localhost"), - $executor - ); - } - - return $executor; - } - - /** - * @param Config|string $nameserver - * @param LoopInterface $loop - * @return CoopExecutor - * @throws \InvalidArgumentException for invalid DNS server address - * @throws \UnderflowException when given DNS Config object has an empty list of nameservers - */ - private function createExecutor($nameserver, LoopInterface $loop) - { - if ($nameserver instanceof Config) { - if (!$nameserver->nameservers) { - throw new \UnderflowException('Empty config with no DNS servers'); - } - - // Hard-coded to check up to 3 DNS servers to match default limits in place in most systems (see MAXNS config). - // Note to future self: Recursion isn't too hard, but how deep do we really want to go? - $primary = reset($nameserver->nameservers); - $secondary = next($nameserver->nameservers); - $tertiary = next($nameserver->nameservers); - - if ($tertiary !== false) { - // 3 DNS servers given => nest first with fallback for second and third - return new CoopExecutor( - new RetryExecutor( - new FallbackExecutor( - $this->createSingleExecutor($primary, $loop), - new FallbackExecutor( - $this->createSingleExecutor($secondary, $loop), - $this->createSingleExecutor($tertiary, $loop) - ) - ) - ) - ); - } elseif ($secondary !== false) { - // 2 DNS servers given => fallback from first to second - return new CoopExecutor( - new RetryExecutor( - new FallbackExecutor( - $this->createSingleExecutor($primary, $loop), - $this->createSingleExecutor($secondary, $loop) - ) - ) - ); - } else { - // 1 DNS server given => use single executor - $nameserver = $primary; - } - } - - return new CoopExecutor(new RetryExecutor($this->createSingleExecutor($nameserver, $loop))); - } - - /** - * @param string $nameserver - * @param LoopInterface $loop - * @return ExecutorInterface - * @throws \InvalidArgumentException for invalid DNS server address - */ - private function createSingleExecutor($nameserver, LoopInterface $loop) - { - $parts = \parse_url($nameserver); - - if (isset($parts['scheme']) && $parts['scheme'] === 'tcp') { - $executor = $this->createTcpExecutor($nameserver, $loop); - } elseif (isset($parts['scheme']) && $parts['scheme'] === 'udp') { - $executor = $this->createUdpExecutor($nameserver, $loop); - } else { - $executor = new SelectiveTransportExecutor( - $this->createUdpExecutor($nameserver, $loop), - $this->createTcpExecutor($nameserver, $loop) - ); - } - - return $executor; + return new Resolver(parent::createCached($config, $loop, $cache)); } - /** - * @param string $nameserver - * @param LoopInterface $loop - * @return TimeoutExecutor - * @throws \InvalidArgumentException for invalid DNS server address - */ - private function createTcpExecutor($nameserver, LoopInterface $loop) - { - return new TimeoutExecutor( - new TcpTransportExecutor($nameserver, $loop), - 5.0, - $loop - ); - } - /** - * @param string $nameserver - * @param LoopInterface $loop - * @return TimeoutExecutor - * @throws \InvalidArgumentException for invalid DNS server address - */ - private function createUdpExecutor($nameserver, LoopInterface $loop) - { - return new TimeoutExecutor( - new UdpTransportExecutor( - $nameserver, - $loop - ), - 5.0, - $loop - ); - } } From 83bd2e1f65eae6b07da569f351a620a289870392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Thu, 3 Mar 2022 10:01:16 +0100 Subject: [PATCH 4/9] split Resolver-Factory and Executer-Factory --- ...xecuterFactory.php => ExecutorFactory.php} | 2 +- src/Resolver/Factory.php | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) rename src/Query/{ExecuterFactory.php => ExecutorFactory.php} (99%) diff --git a/src/Query/ExecuterFactory.php b/src/Query/ExecutorFactory.php similarity index 99% rename from src/Query/ExecuterFactory.php rename to src/Query/ExecutorFactory.php index 643336b6..d97043b9 100644 --- a/src/Query/ExecuterFactory.php +++ b/src/Query/ExecutorFactory.php @@ -9,7 +9,7 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -class ExecuterFactory +class ExecutorFactory { /** diff --git a/src/Resolver/Factory.php b/src/Resolver/Factory.php index 8ab4534b..9e9c4085 100644 --- a/src/Resolver/Factory.php +++ b/src/Resolver/Factory.php @@ -4,11 +4,22 @@ use React\Cache\CacheInterface; use React\Dns\Config\Config; -use React\Dns\Query\ExecuterFactory; +use React\Dns\Query\ExecutorFactory; use React\EventLoop\LoopInterface; -final class Factory extends ExecuterFactory +final class Factory { + + private $executorFactory; + + /** + * @param ExecutorFactory $executorFactory + */ + public function __construct(ExecutorFactory $executorFactory = null) + { + $this->executorFactory = $executorFactory ?: new ExecutorFactory(); + } + /** * Creates a DNS resolver instance for the given DNS config * @@ -26,7 +37,7 @@ final class Factory extends ExecuterFactory */ public function create($config, LoopInterface $loop = null) { - return new Resolver(parent::create($config, $loop)); + return new Resolver($this->executorFactory->create($config, $loop)); } /** @@ -47,7 +58,7 @@ public function create($config, LoopInterface $loop = null) */ public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null) { - return new Resolver(parent::createCached($config, $loop, $cache)); + return new Resolver($this->executorFactory->createCached($config, $loop, $cache)); } From 400acf394b2eedc130bec4964395775137cb74b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Thu, 3 Mar 2022 10:04:27 +0100 Subject: [PATCH 5/9] fix tests --- tests/FunctionalResolverTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/FunctionalResolverTest.php b/tests/FunctionalResolverTest.php index 9cb05615..df674486 100644 --- a/tests/FunctionalResolverTest.php +++ b/tests/FunctionalResolverTest.php @@ -52,7 +52,7 @@ public function testResolveGoogleResolves() */ public function testResolveGoogleOverUdpResolves() { - $factory = new Factory($this->loop); + $factory = new Factory(); $this->resolver = $factory->create('udp://8.8.8.8', $this->loop); $promise = $this->resolver->resolve('google.com'); @@ -66,7 +66,7 @@ public function testResolveGoogleOverUdpResolves() */ public function testResolveGoogleOverTcpResolves() { - $factory = new Factory($this->loop); + $factory = new Factory(); $this->resolver = $factory->create('tcp://8.8.8.8', $this->loop); $promise = $this->resolver->resolve('google.com'); From 5ea88cb720e3ce7ac418494651c860bca6382c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Thu, 3 Mar 2022 10:08:10 +0100 Subject: [PATCH 6/9] simplify ResolverFactory --- src/Resolver/Factory.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Resolver/Factory.php b/src/Resolver/Factory.php index 9e9c4085..ec282f1b 100644 --- a/src/Resolver/Factory.php +++ b/src/Resolver/Factory.php @@ -12,12 +12,9 @@ final class Factory private $executorFactory; - /** - * @param ExecutorFactory $executorFactory - */ - public function __construct(ExecutorFactory $executorFactory = null) + public function __construct() { - $this->executorFactory = $executorFactory ?: new ExecutorFactory(); + $this->executorFactory = new ExecutorFactory(); } /** From 6e10fb5fce03cfd6a85b757e04407fdc794863a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Mon, 7 Mar 2022 09:56:53 +0100 Subject: [PATCH 7/9] re-order factory params --- src/Query/ExecutorFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Query/ExecutorFactory.php b/src/Query/ExecutorFactory.php index d97043b9..8e7684a6 100644 --- a/src/Query/ExecutorFactory.php +++ b/src/Query/ExecutorFactory.php @@ -48,7 +48,7 @@ public function create($config, LoopInterface $loop = null) * @throws \InvalidArgumentException for invalid DNS server address * @throws \UnderflowException when given DNS Config object has an empty list of nameservers */ - public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null) + public function createCached($config, CacheInterface $cache = null, LoopInterface $loop = null) { // default to keeping maximum of 256 responses in cache unless explicitly given if (!($cache instanceof CacheInterface)) { From 9cb8ca439aaa476bd630da90da7898aaf38f5364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Mon, 7 Mar 2022 09:58:10 +0100 Subject: [PATCH 8/9] re-order factory params --- src/Resolver/Factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resolver/Factory.php b/src/Resolver/Factory.php index ec282f1b..61a29f82 100644 --- a/src/Resolver/Factory.php +++ b/src/Resolver/Factory.php @@ -55,7 +55,7 @@ public function create($config, LoopInterface $loop = null) */ public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null) { - return new Resolver($this->executorFactory->createCached($config, $loop, $cache)); + return new Resolver($this->executorFactory->createCached($config, $cache, $loop)); } From ee53f20669e2408819f86f981ac22b0dc6be1d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20von=20Hoe=C3=9Flin?= Date: Tue, 8 Mar 2022 13:53:44 +0100 Subject: [PATCH 9/9] define `ExecutorFactory` as `final` --- src/Query/ExecutorFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Query/ExecutorFactory.php b/src/Query/ExecutorFactory.php index 8e7684a6..21c8d752 100644 --- a/src/Query/ExecutorFactory.php +++ b/src/Query/ExecutorFactory.php @@ -9,7 +9,7 @@ use React\EventLoop\Loop; use React\EventLoop\LoopInterface; -class ExecutorFactory +final class ExecutorFactory { /**