aboutsummaryrefslogtreecommitdiffhomepage
path: root/assets/php/vendor/react/dns/src/Resolver
diff options
context:
space:
mode:
Diffstat (limited to 'assets/php/vendor/react/dns/src/Resolver')
-rw-r--r--assets/php/vendor/react/dns/src/Resolver/Factory.php103
-rw-r--r--assets/php/vendor/react/dns/src/Resolver/Resolver.php100
2 files changed, 203 insertions, 0 deletions
diff --git a/assets/php/vendor/react/dns/src/Resolver/Factory.php b/assets/php/vendor/react/dns/src/Resolver/Factory.php
new file mode 100644
index 0000000..12a912f
--- /dev/null
+++ b/assets/php/vendor/react/dns/src/Resolver/Factory.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace React\Dns\Resolver;
+
+use React\Cache\ArrayCache;
+use React\Cache\CacheInterface;
+use React\Dns\Config\HostsFile;
+use React\Dns\Protocol\Parser;
+use React\Dns\Protocol\BinaryDumper;
+use React\Dns\Query\CachedExecutor;
+use React\Dns\Query\Executor;
+use React\Dns\Query\ExecutorInterface;
+use React\Dns\Query\HostsFileExecutor;
+use React\Dns\Query\RecordCache;
+use React\Dns\Query\RetryExecutor;
+use React\Dns\Query\TimeoutExecutor;
+use React\EventLoop\LoopInterface;
+
+class Factory
+{
+ public function create($nameserver, LoopInterface $loop)
+ {
+ $nameserver = $this->addPortToServerIfMissing($nameserver);
+ $executor = $this->decorateHostsFileExecutor($this->createRetryExecutor($loop));
+
+ return new Resolver($nameserver, $executor);
+ }
+
+ public function createCached($nameserver, LoopInterface $loop, CacheInterface $cache = null)
+ {
+ if (!($cache instanceof CacheInterface)) {
+ $cache = new ArrayCache();
+ }
+
+ $nameserver = $this->addPortToServerIfMissing($nameserver);
+ $executor = $this->decorateHostsFileExecutor($this->createCachedExecutor($loop, $cache));
+
+ return new Resolver($nameserver, $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;
+ }
+
+ protected function createExecutor(LoopInterface $loop)
+ {
+ return new TimeoutExecutor(
+ new Executor($loop, new Parser(), new BinaryDumper(), null),
+ 5.0,
+ $loop
+ );
+ }
+
+ protected function createRetryExecutor(LoopInterface $loop)
+ {
+ return new RetryExecutor($this->createExecutor($loop));
+ }
+
+ protected function createCachedExecutor(LoopInterface $loop, CacheInterface $cache)
+ {
+ return new CachedExecutor($this->createRetryExecutor($loop), new RecordCache($cache));
+ }
+
+ protected function addPortToServerIfMissing($nameserver)
+ {
+ if (strpos($nameserver, '[') === false && substr_count($nameserver, ':') >= 2) {
+ // several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets
+ $nameserver = '[' . $nameserver . ']';
+ }
+ // assume a dummy scheme when checking for the port, otherwise parse_url() fails
+ if (parse_url('dummy://' . $nameserver, PHP_URL_PORT) === null) {
+ $nameserver .= ':53';
+ }
+
+ return $nameserver;
+ }
+}
diff --git a/assets/php/vendor/react/dns/src/Resolver/Resolver.php b/assets/php/vendor/react/dns/src/Resolver/Resolver.php
new file mode 100644
index 0000000..4a4983a
--- /dev/null
+++ b/assets/php/vendor/react/dns/src/Resolver/Resolver.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace React\Dns\Resolver;
+
+use React\Dns\Query\ExecutorInterface;
+use React\Dns\Query\Query;
+use React\Dns\RecordNotFoundException;
+use React\Dns\Model\Message;
+
+class Resolver
+{
+ private $nameserver;
+ private $executor;
+
+ public function __construct($nameserver, ExecutorInterface $executor)
+ {
+ $this->nameserver = $nameserver;
+ $this->executor = $executor;
+ }
+
+ public function resolve($domain)
+ {
+ $query = new Query($domain, Message::TYPE_A, Message::CLASS_IN, time());
+ $that = $this;
+
+ return $this->executor
+ ->query($this->nameserver, $query)
+ ->then(function (Message $response) use ($query, $that) {
+ return $that->extractAddress($query, $response);
+ });
+ }
+
+ public function extractAddress(Query $query, Message $response)
+ {
+ $answers = $response->answers;
+
+ $addresses = $this->resolveAliases($answers, $query->name);
+
+ if (0 === count($addresses)) {
+ $message = 'DNS Request did not return valid answer.';
+ throw new RecordNotFoundException($message);
+ }
+
+ $address = $addresses[array_rand($addresses)];
+ return $address;
+ }
+
+ public function resolveAliases(array $answers, $name)
+ {
+ $named = $this->filterByName($answers, $name);
+ $aRecords = $this->filterByType($named, Message::TYPE_A);
+ $cnameRecords = $this->filterByType($named, Message::TYPE_CNAME);
+
+ if ($aRecords) {
+ return $this->mapRecordData($aRecords);
+ }
+
+ if ($cnameRecords) {
+ $aRecords = array();
+
+ $cnames = $this->mapRecordData($cnameRecords);
+ foreach ($cnames as $cname) {
+ $targets = $this->filterByName($answers, $cname);
+ $aRecords = array_merge(
+ $aRecords,
+ $this->resolveAliases($answers, $cname)
+ );
+ }
+
+ return $aRecords;
+ }
+
+ return array();
+ }
+
+ private function filterByName(array $answers, $name)
+ {
+ return $this->filterByField($answers, 'name', $name);
+ }
+
+ private function filterByType(array $answers, $type)
+ {
+ return $this->filterByField($answers, 'type', $type);
+ }
+
+ private function filterByField(array $answers, $field, $value)
+ {
+ $value = strtolower($value);
+ return array_filter($answers, function ($answer) use ($field, $value) {
+ return $value === strtolower($answer->$field);
+ });
+ }
+
+ private function mapRecordData(array $records)
+ {
+ return array_map(function ($record) {
+ return $record->data;
+ }, $records);
+ }
+}