Initial Commit
This commit is contained in:
1
dependencies/remotelyliving/php-dns/_config.yml
vendored
Normal file
1
dependencies/remotelyliving/php-dns/_config.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
theme: jekyll-theme-cayman
|
37
dependencies/remotelyliving/php-dns/bootstrap/repl.php
vendored
Normal file
37
dependencies/remotelyliving/php-dns/bootstrap/repl.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace WP_Ultimo\Dependencies;
|
||||
|
||||
require_once './vendor/autoload.php';
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Factories\SpatieDNS;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers\Dig;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Subscribers\STDIOSubscriber;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Cached;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Chain;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\CloudFlare;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\GoogleDNS;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\LocalSystem;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
\class_alias(Hostname::class, 'WP_Ultimo\\Dependencies\\Hostname');
|
||||
\class_alias(DNSRecord::class, 'WP_Ultimo\\Dependencies\\DNSRecord');
|
||||
\class_alias(DNSRecordType::class, 'WP_Ultimo\\Dependencies\\DNSRecordType');
|
||||
\class_alias(DNSRecordCollection::class, 'WP_Ultimo\\Dependencies\\DNSRecordCollection');
|
||||
$stdOut = new \SplFileObject('php://stdout');
|
||||
$stdErr = new \SplFileObject('php://stderr');
|
||||
$IOSubscriber = new STDIOSubscriber($stdOut, $stdErr);
|
||||
$localSystemResolver = new LocalSystem();
|
||||
$localSystemResolver->addSubscriber($IOSubscriber);
|
||||
$googleDNSResolver = new GoogleDNS();
|
||||
$googleDNSResolver->addSubscriber($IOSubscriber);
|
||||
$cloudFlareResolver = new CloudFlare();
|
||||
$cloudFlareResolver->addSubscriber($IOSubscriber);
|
||||
$digResolver = new \WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Dig(new SpatieDNS(), new Dig());
|
||||
$digResolver->addSubscriber($IOSubscriber);
|
||||
$chainResolver = new Chain($cloudFlareResolver, $googleDNSResolver, $localSystemResolver);
|
||||
$cachedResolver = new Cached(new FilesystemAdapter(), $chainResolver);
|
||||
$cachedResolver->addSubscriber($IOSubscriber);
|
56
dependencies/remotelyliving/php-dns/churn.yml
vendored
Normal file
56
dependencies/remotelyliving/php-dns/churn.yml
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
# The maximum number of files to display in the results table.
|
||||
# Default: 10
|
||||
filesToShow: 20
|
||||
|
||||
# The minimum score a file need to display in the results table.
|
||||
# Disabled if null.
|
||||
# Default: 0.1
|
||||
minScoreToShow: 0
|
||||
|
||||
# The command returns an 1 exit code if the highest score is greater than the threshold.
|
||||
# Disabled if null.
|
||||
# Default: null
|
||||
maxScoreThreshold: 0.9
|
||||
|
||||
# The number of parallel jobs to use when processing files.
|
||||
# Default: 10
|
||||
parallelJobs: 10
|
||||
|
||||
# How far back in the VCS history to count the number of commits to a file
|
||||
# Can be a human readable date like 'One week ago' or a date like '2017-07-12'
|
||||
# Default: '10 Years ago'
|
||||
commitsSince: One year ago
|
||||
|
||||
# Files to ignore when processing. The full path to the file relative to the root of your project is required.
|
||||
# Also supports regular expressions.
|
||||
# Default: All PHP files in the path provided to churn-php are processed.
|
||||
#filesToIgnore:
|
||||
|
||||
# File extensions to use when processing.
|
||||
# Default: php
|
||||
fileExtensions:
|
||||
- php
|
||||
- inc
|
||||
|
||||
# This list is used only if there is no argument when running churn.
|
||||
# Default: <empty>
|
||||
directoriesToScan:
|
||||
- src
|
||||
- tests/
|
||||
|
||||
# List of user-defined hooks.
|
||||
# They can be referenced by their full qualified class name if churn has access to the autoloader.
|
||||
# Otherwise the file path can be used as well.
|
||||
# See below the section about hooks for more details.
|
||||
# Default: <empty>
|
||||
#hooks:
|
||||
|
||||
# The version control system used for your project.
|
||||
# Accepted values: fossil, git, mercurial, subversion, none
|
||||
# Default: git
|
||||
vcs: git
|
||||
|
||||
# The path of the cache file. It doesn't need to exist before running churn.
|
||||
# Disabled if null.
|
||||
# Default: null
|
||||
cachePath: .churn.cache
|
4
dependencies/remotelyliving/php-dns/phpstan.neon
vendored
Normal file
4
dependencies/remotelyliving/php-dns/phpstan.neon
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
parameters:
|
||||
checkMissingIterableValueType: false
|
||||
checkGenericClassInNonGenericObjectType: false
|
||||
ignoreErrors:
|
61
dependencies/remotelyliving/php-dns/psalm.xml
vendored
Normal file
61
dependencies/remotelyliving/php-dns/psalm.xml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
totallyTyped="false"
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
|
||||
<issueHandlers>
|
||||
<LessSpecificReturnType errorLevel="info" />
|
||||
|
||||
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||
|
||||
<DeprecatedMethod errorLevel="info" />
|
||||
<DeprecatedProperty errorLevel="info" />
|
||||
<DeprecatedClass errorLevel="info" />
|
||||
<DeprecatedConstant errorLevel="info" />
|
||||
<DeprecatedFunction errorLevel="info" />
|
||||
<DeprecatedInterface errorLevel="info" />
|
||||
<DeprecatedTrait errorLevel="info" />
|
||||
|
||||
<InternalMethod errorLevel="info" />
|
||||
<InternalProperty errorLevel="info" />
|
||||
<InternalClass errorLevel="info" />
|
||||
|
||||
<MissingClosureReturnType errorLevel="info" />
|
||||
<MissingReturnType errorLevel="info" />
|
||||
<MissingPropertyType errorLevel="info" />
|
||||
<InvalidDocblock errorLevel="info" />
|
||||
|
||||
<PropertyNotSetInConstructor errorLevel="info" />
|
||||
<MissingConstructor errorLevel="info" />
|
||||
<MissingClosureParamType errorLevel="info" />
|
||||
<MissingParamType errorLevel="info" />
|
||||
<RedundantPropertyInitializationCheck errorLevel="suppress"/>
|
||||
<RedundantCondition errorLevel="info" />
|
||||
|
||||
<DocblockTypeContradiction errorLevel="info" />
|
||||
<RedundantConditionGivenDocblockType errorLevel="info" />
|
||||
|
||||
<UnresolvableInclude errorLevel="info" />
|
||||
|
||||
<RawObjectIteration errorLevel="info" />
|
||||
|
||||
<InvalidStringClass errorLevel="info" />
|
||||
<TypeDoesNotContainType errorLevel="info" />
|
||||
|
||||
<TooManyArguments>
|
||||
<errorLevel type="suppress">
|
||||
<referencedFunction name="WP_Ultimo\Dependencies\Symfony\Component\EventDispatcher\EventDispatcherInterface::dispatch" />
|
||||
</errorLevel>
|
||||
</TooManyArguments>
|
||||
</issueHandlers>
|
||||
</psalm>
|
20
dependencies/remotelyliving/php-dns/rector.php
vendored
Normal file
20
dependencies/remotelyliving/php-dns/rector.php
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace WP_Ultimo\Dependencies;
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Php74\Rector\Property\TypedPropertyRector;
|
||||
use Rector\Set\ValueObject\LevelSetList;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
return static function (ContainerConfigurator $containerConfigurator) : void {
|
||||
// get parameters
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::PATHS, [__DIR__ . '/src']);
|
||||
// Define what rule sets will be applied
|
||||
$containerConfigurator->import(LevelSetList::UP_TO_PHP_81);
|
||||
// get services (needed for register a single rule)
|
||||
$services = $containerConfigurator->services();
|
||||
// register a single rule
|
||||
$services->set(TypedPropertyRector::class);
|
||||
};
|
64
dependencies/remotelyliving/php-dns/src/Entities/CAAData.php
vendored
Normal file
64
dependencies/remotelyliving/php-dns/src/Entities/CAAData.php
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions;
|
||||
use function preg_match;
|
||||
use function serialize;
|
||||
use function str_ireplace;
|
||||
use function trim;
|
||||
use function unserialize;
|
||||
final class CAAData extends DataAbstract
|
||||
{
|
||||
private int $flags;
|
||||
private string $tag;
|
||||
private ?string $value;
|
||||
public function __construct(int $flags, string $tag, string $value = null)
|
||||
{
|
||||
$this->flags = $flags;
|
||||
$this->tag = $tag;
|
||||
$this->value = $value ? $this->normalizeValue($value) : null;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return "{$this->flags} {$this->tag} \"{$this->value}\"";
|
||||
}
|
||||
public function getFlags() : int
|
||||
{
|
||||
return $this->flags;
|
||||
}
|
||||
public function getTag() : string
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
public function getValue() : ?string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['flags' => $this->flags, 'tag' => $this->tag, 'value' => $this->value];
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$unserialized = unserialize($serialized);
|
||||
$this->flags = $unserialized['flags'];
|
||||
$this->tag = $unserialized['tag'];
|
||||
$this->value = $unserialized['value'];
|
||||
}
|
||||
private function normalizeValue(string $value) : string
|
||||
{
|
||||
$normalized = trim(str_ireplace('"', '', $value));
|
||||
if (preg_match('/\\s/m', $normalized)) {
|
||||
throw new Exceptions\InvalidArgumentException("{$value} is not a valid CAA value");
|
||||
}
|
||||
return $normalized;
|
||||
}
|
||||
}
|
39
dependencies/remotelyliving/php-dns/src/Entities/CNAMEData.php
vendored
Normal file
39
dependencies/remotelyliving/php-dns/src/Entities/CNAMEData.php
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
final class CNAMEData extends DataAbstract
|
||||
{
|
||||
private Hostname $hostname;
|
||||
public function __construct(Hostname $hostname)
|
||||
{
|
||||
$this->hostname = $hostname;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return (string) $this->hostname;
|
||||
}
|
||||
public function getHostname() : Hostname
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['hostname' => (string) $this->hostname];
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
/** @var array{'hostname': string} $unserialized */
|
||||
$unserialized = unserialize($serialized);
|
||||
$this->hostname = new Hostname($unserialized['hostname']);
|
||||
}
|
||||
}
|
103
dependencies/remotelyliving/php-dns/src/Entities/DNSRecord.php
vendored
Normal file
103
dependencies/remotelyliving/php-dns/src/Entities/DNSRecord.php
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
final class DNSRecord extends EntityAbstract implements DNSRecordInterface
|
||||
{
|
||||
private DNSRecordType $recordType;
|
||||
private Hostname $hostname;
|
||||
private int $TTL;
|
||||
private ?IPAddress $IPAddress;
|
||||
private string $class;
|
||||
private ?DataAbstract $data;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const DATA = 'data';
|
||||
public function __construct(DNSRecordType $recordType, Hostname $hostname, int $ttl, IPAddress $IPAddress = null, string $class = 'IN', DataAbstract $data = null)
|
||||
{
|
||||
$this->recordType = $recordType;
|
||||
$this->hostname = $hostname;
|
||||
$this->TTL = $ttl;
|
||||
$this->IPAddress = $IPAddress;
|
||||
$this->class = $class;
|
||||
$this->data = $data;
|
||||
}
|
||||
public static function createFromPrimitives(string $recordType, string $hostname, int $ttl, string $IPAddress = null, string $class = 'IN', string $data = null) : DNSRecord
|
||||
{
|
||||
$type = DNSRecordType::createFromString($recordType);
|
||||
$hostname = Hostname::createFromString($hostname);
|
||||
$data = $data !== null ? DataAbstract::createFromTypeAndString($type, $data) : null;
|
||||
return new self($type, $hostname, $ttl, $IPAddress ? IPAddress::createFromString($IPAddress) : null, $class, $data);
|
||||
}
|
||||
public function getType() : DNSRecordType
|
||||
{
|
||||
return $this->recordType;
|
||||
}
|
||||
public function getHostname() : Hostname
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
public function getTTL() : int
|
||||
{
|
||||
return $this->TTL;
|
||||
}
|
||||
public function getIPAddress() : ?IPAddress
|
||||
{
|
||||
return $this->IPAddress;
|
||||
}
|
||||
public function getClass() : string
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
public function getData() : ?DataAbstract
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
public function setTTL(int $ttl) : DNSRecordInterface
|
||||
{
|
||||
$this->TTL = $ttl;
|
||||
return $this;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
$formatted = ['hostname' => (string) $this->hostname, 'type' => (string) $this->recordType, 'TTL' => $this->TTL, 'class' => $this->class];
|
||||
if ($this->IPAddress) {
|
||||
$formatted['IPAddress'] = (string) $this->IPAddress;
|
||||
}
|
||||
if ($this->data) {
|
||||
$formatted[self::DATA] = (string) $this->data;
|
||||
}
|
||||
return $formatted;
|
||||
}
|
||||
public function equals(DNSRecordInterface $record) : bool
|
||||
{
|
||||
return $this->hostname->equals($record->getHostname()) && $this->recordType->equals($record->getType()) && (string) $this->data === (string) $record->getData() && (string) $this->IPAddress === (string) $record->getIPAddress();
|
||||
// could be null
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$unserialized = unserialize($serialized);
|
||||
$rawIPAddres = $unserialized['IPAddress'] ?? null;
|
||||
$this->recordType = DNSRecordType::createFromString($unserialized['type']);
|
||||
$this->hostname = Hostname::createFromString($unserialized['hostname']);
|
||||
$this->TTL = (int) $unserialized['TTL'];
|
||||
$this->IPAddress = $rawIPAddres ? IPAddress::createFromString($rawIPAddres) : null;
|
||||
$this->class = $unserialized['class'];
|
||||
$this->data = isset($unserialized[self::DATA]) ? DataAbstract::createFromTypeAndString($this->recordType, $unserialized[self::DATA]) : null;
|
||||
}
|
||||
public function jsonSerialize() : array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
}
|
151
dependencies/remotelyliving/php-dns/src/Entities/DNSRecordCollection.php
vendored
Normal file
151
dependencies/remotelyliving/php-dns/src/Entities/DNSRecordCollection.php
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use Countable;
|
||||
use Iterator;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\Arrayable;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\Serializable;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException;
|
||||
use function array_filter;
|
||||
use function array_shift;
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
final class DNSRecordCollection extends EntityAbstract implements ArrayAccess, Iterator, Countable, Arrayable, Serializable
|
||||
{
|
||||
private ArrayIterator $records;
|
||||
public function __construct(DNSRecordInterface ...$records)
|
||||
{
|
||||
$this->records = new ArrayIterator($records);
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return $this->records->getArrayCopy();
|
||||
}
|
||||
public function pickFirst() : ?DNSRecordInterface
|
||||
{
|
||||
$copy = $this->records->getArrayCopy();
|
||||
return array_shift($copy);
|
||||
}
|
||||
public function filteredByType(DNSRecordType $type) : self
|
||||
{
|
||||
$fn = fn(DNSRecordInterface $record) => $record->getType()->equals($type);
|
||||
return new self(...array_filter($this->records->getArrayCopy(), $fn));
|
||||
}
|
||||
public function has(DNSRecordInterface $lookupRecord) : bool
|
||||
{
|
||||
foreach ($this->records->getArrayCopy() as $record) {
|
||||
if ($lookupRecord->equals($record)) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function current() : ?DNSRecordInterface
|
||||
{
|
||||
return $this->records->current();
|
||||
}
|
||||
public function next() : void
|
||||
{
|
||||
$this->records->next();
|
||||
}
|
||||
/**
|
||||
* @return int|string|bool
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->records->key();
|
||||
}
|
||||
public function valid() : bool
|
||||
{
|
||||
return $this->records->valid();
|
||||
}
|
||||
public function rewind() : void
|
||||
{
|
||||
$this->records->rewind();
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset) : bool
|
||||
{
|
||||
return $this->records->offsetExists($offset);
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return \RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface
|
||||
*/
|
||||
public function offsetGet($offset) : DNSRecordInterface
|
||||
{
|
||||
return $this->records->offsetGet($offset);
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @throws \RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function offsetSet($offset, $value) : void
|
||||
{
|
||||
if (!$value instanceof DNSRecordInterface) {
|
||||
throw new InvalidArgumentException('Invalid value');
|
||||
}
|
||||
$this->records->offsetSet(
|
||||
$offset,
|
||||
/** @scrutinizer ignore-type */
|
||||
$value
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*/
|
||||
public function offsetUnset($offset) : void
|
||||
{
|
||||
$this->records->offsetUnset($offset);
|
||||
}
|
||||
public function count() : int
|
||||
{
|
||||
return $this->records->count();
|
||||
}
|
||||
public function isEmpty() : bool
|
||||
{
|
||||
return $this->count() === 0;
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->records->getArrayCopy());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$this->records = new ArrayIterator(unserialize($serialized));
|
||||
}
|
||||
public function jsonSerialize() : array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
public function withUniqueValuesExcluded() : self
|
||||
{
|
||||
return $this->filterValues(fn(DNSRecordInterface $candidateRecord, DNSRecordCollection $remaining): bool => $remaining->has($candidateRecord))->withUniqueValues();
|
||||
}
|
||||
public function withUniqueValues() : self
|
||||
{
|
||||
return $this->filterValues(fn(DNSRecordInterface $candidateRecord, DNSRecordCollection $remaining): bool => !$remaining->has($candidateRecord));
|
||||
}
|
||||
private function filterValues(callable $eval) : self
|
||||
{
|
||||
$filtered = new self();
|
||||
$records = $this->records->getArrayCopy();
|
||||
while ($record = array_shift($records)) {
|
||||
if ($eval($record, new self(...$records))) {
|
||||
$filtered[] = $record;
|
||||
}
|
||||
}
|
||||
return $filtered;
|
||||
}
|
||||
}
|
124
dependencies/remotelyliving/php-dns/src/Entities/DNSRecordType.php
vendored
Normal file
124
dependencies/remotelyliving/php-dns/src/Entities/DNSRecordType.php
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException;
|
||||
use function array_flip;
|
||||
use function in_array;
|
||||
use function strtoupper;
|
||||
final class DNSRecordType extends EntityAbstract
|
||||
{
|
||||
public const TYPE_A = 'A';
|
||||
public const TYPE_CNAME = 'CNAME';
|
||||
public const TYPE_HINFO = 'HINFO';
|
||||
public const TYPE_CAA = 'CAA';
|
||||
public const TYPE_MX = 'MX';
|
||||
public const TYPE_NS = 'NS';
|
||||
public const TYPE_PTR = 'PTR';
|
||||
public const TYPE_SOA = 'SOA';
|
||||
public const TYPE_TXT = 'TXT';
|
||||
public const TYPE_AAAA = 'AAAA';
|
||||
public const TYPE_SRV = 'SRV';
|
||||
public const TYPE_NAPTR = 'NAPTR';
|
||||
public const TYPE_A6 = 'A6';
|
||||
public const TYPE_ANY = 'ANY';
|
||||
public const VALID_TYPES = [self::TYPE_A, self::TYPE_CNAME, self::TYPE_HINFO, self::TYPE_CAA, self::TYPE_MX, self::TYPE_NS, self::TYPE_PTR, self::TYPE_SOA, self::TYPE_TXT, self::TYPE_AAAA, self::TYPE_SRV, self::TYPE_NAPTR, self::TYPE_A6, self::TYPE_ANY];
|
||||
protected const CODE_TYPE_MAP = [1 => DNSRecordType::TYPE_A, 5 => DNSRecordType::TYPE_CNAME, 13 => DNSRecordType::TYPE_HINFO, 257 => DNSRecordType::TYPE_CAA, 15 => DNSRecordType::TYPE_MX, 2 => DNSRecordType::TYPE_NS, 12 => DNSRecordType::TYPE_PTR, 6 => DNSRecordType::TYPE_SOA, 16 => DNSRecordType::TYPE_TXT, 28 => DNSRecordType::TYPE_AAAA, 33 => DNSRecordType::TYPE_SRV, 35 => DNSRecordType::TYPE_NAPTR, 38 => DNSRecordType::TYPE_A6, 255 => DNSRecordType::TYPE_ANY];
|
||||
private string $type;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(string $type)
|
||||
{
|
||||
if (!in_array($type, self::VALID_TYPES, \true)) {
|
||||
throw new InvalidArgumentException("{$type} is not an existing DNS record type");
|
||||
}
|
||||
$this->type = $type;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function createFromInt(int $code) : DNSRecordType
|
||||
{
|
||||
if (!isset(self::CODE_TYPE_MAP[$code])) {
|
||||
throw new InvalidArgumentException("{$code} is not able to be mapped to an existing DNS record type");
|
||||
}
|
||||
return new self(self::CODE_TYPE_MAP[$code]);
|
||||
}
|
||||
public static function createFromString(string $type) : DNSRecordType
|
||||
{
|
||||
return new self($type);
|
||||
}
|
||||
public function toInt() : int
|
||||
{
|
||||
return array_flip(self::CODE_TYPE_MAP)[$this->type];
|
||||
}
|
||||
public function isA(string $type) : bool
|
||||
{
|
||||
return $this->type === strtoupper($type);
|
||||
}
|
||||
public function equals(DNSRecordType $recordType) : bool
|
||||
{
|
||||
return $this->type === (string) $recordType;
|
||||
}
|
||||
public static function createA() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_A);
|
||||
}
|
||||
public static function createCNAME() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_CNAME);
|
||||
}
|
||||
public static function createHINFO() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_HINFO);
|
||||
}
|
||||
public static function createCAA() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_CAA);
|
||||
}
|
||||
public static function createMX() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_MX);
|
||||
}
|
||||
public static function createNS() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_NS);
|
||||
}
|
||||
public static function createPTR() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_PTR);
|
||||
}
|
||||
public static function createSOA() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_SOA);
|
||||
}
|
||||
public static function createTXT() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_TXT);
|
||||
}
|
||||
public static function createAAAA() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_AAAA);
|
||||
}
|
||||
public static function createSRV() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_SRV);
|
||||
}
|
||||
public static function createNAPTR() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_NAPTR);
|
||||
}
|
||||
public static function createA6() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_A6);
|
||||
}
|
||||
public static function createANY() : self
|
||||
{
|
||||
return self::createFromString(self::TYPE_ANY);
|
||||
}
|
||||
}
|
59
dependencies/remotelyliving/php-dns/src/Entities/DataAbstract.php
vendored
Normal file
59
dependencies/remotelyliving/php-dns/src/Entities/DataAbstract.php
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\Arrayable;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\Serializable;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function trim;
|
||||
abstract class DataAbstract implements Arrayable, Serializable
|
||||
{
|
||||
public abstract function __toString() : string;
|
||||
public abstract function toArray() : array;
|
||||
public function equals(DataAbstract $dataAbstract) : bool
|
||||
{
|
||||
return (string) $this === (string) $dataAbstract;
|
||||
}
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public static function createFromTypeAndString(DNSRecordType $recordType, string $data) : self
|
||||
{
|
||||
if ($recordType->isA(DNSRecordType::TYPE_TXT)) {
|
||||
return new TXTData(trim($data, '"'));
|
||||
}
|
||||
if ($recordType->isA(DNSRecordType::TYPE_NS)) {
|
||||
return new NSData(new Hostname($data));
|
||||
}
|
||||
if ($recordType->isA(DNSRecordType::TYPE_CNAME)) {
|
||||
return new CNAMEData(new Hostname($data));
|
||||
}
|
||||
$parsed = self::parseDataToArray($data);
|
||||
if ($recordType->isA(DNSRecordType::TYPE_MX)) {
|
||||
return new MXData(new Hostname($parsed[1]), (int) $parsed[0]);
|
||||
}
|
||||
if ($recordType->isA(DNSRecordType::TYPE_SOA)) {
|
||||
return new SOAData(new Hostname($parsed[0]), new Hostname($parsed[1]), (int) ($parsed[2] ?? 0), (int) ($parsed[3] ?? 0), (int) ($parsed[4] ?? 0), (int) ($parsed[5] ?? 0), (int) ($parsed[6] ?? 0));
|
||||
}
|
||||
if ($recordType->isA(DNSRecordType::TYPE_CAA) && count($parsed) === 3) {
|
||||
return new CAAData((int) $parsed[0], (string) $parsed[1], $parsed[2]);
|
||||
}
|
||||
if ($recordType->isA(DNSRecordType::TYPE_SRV)) {
|
||||
return new SRVData((int) $parsed[0] ?: 0, (int) $parsed[1] ?: 0, (int) $parsed[2] ?: 0, new Hostname($parsed[3]));
|
||||
}
|
||||
if ($recordType->isA(DNSRecordType::TYPE_PTR)) {
|
||||
return new PTRData(new Hostname($data));
|
||||
}
|
||||
throw new InvalidArgumentException("{$data} could not be created with type {$recordType}");
|
||||
}
|
||||
public function jsonSerialize() : array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
private static function parseDataToArray(string $data) : array
|
||||
{
|
||||
return explode(' ', $data);
|
||||
}
|
||||
}
|
7
dependencies/remotelyliving/php-dns/src/Entities/EntityAbstract.php
vendored
Normal file
7
dependencies/remotelyliving/php-dns/src/Entities/EntityAbstract.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
abstract class EntityAbstract
|
||||
{
|
||||
}
|
66
dependencies/remotelyliving/php-dns/src/Entities/Hostname.php
vendored
Normal file
66
dependencies/remotelyliving/php-dns/src/Entities/Hostname.php
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException;
|
||||
use function filter_var;
|
||||
use function idn_to_ascii;
|
||||
use function idn_to_utf8;
|
||||
use function mb_strtolower;
|
||||
use function substr;
|
||||
use function trim;
|
||||
final class Hostname extends EntityAbstract
|
||||
{
|
||||
private string $hostname;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(string $hostname)
|
||||
{
|
||||
$hostname = $this->normalizeHostName($hostname);
|
||||
if (filter_var($hostname, \FILTER_VALIDATE_DOMAIN) !== $hostname) {
|
||||
throw new InvalidArgumentException("{$hostname} is not a valid hostname");
|
||||
}
|
||||
$this->hostname = $hostname;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
public function equals(Hostname $hostname) : bool
|
||||
{
|
||||
return $this->hostname === (string) $hostname;
|
||||
}
|
||||
public static function createFromString(string $hostname) : Hostname
|
||||
{
|
||||
return new self($hostname);
|
||||
}
|
||||
public function getHostName() : string
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
public function getHostnameWithoutTrailingDot() : string
|
||||
{
|
||||
return substr($this->hostname, 0, -1);
|
||||
}
|
||||
public function isPunycoded() : bool
|
||||
{
|
||||
return $this->toUTF8() !== $this->hostname;
|
||||
}
|
||||
public function toUTF8() : string
|
||||
{
|
||||
return (string) idn_to_utf8($this->hostname, \IDNA_ERROR_PUNYCODE, \INTL_IDNA_VARIANT_UTS46);
|
||||
}
|
||||
private static function punyCode(string $hostname) : string
|
||||
{
|
||||
return (string) idn_to_ascii($hostname, \IDNA_ERROR_PUNYCODE, \INTL_IDNA_VARIANT_UTS46);
|
||||
}
|
||||
private function normalizeHostName(string $hostname) : string
|
||||
{
|
||||
$hostname = self::punyCode(mb_strtolower(trim($hostname)));
|
||||
if (substr($hostname, -1) !== '.') {
|
||||
return "{$hostname}.";
|
||||
}
|
||||
return $hostname;
|
||||
}
|
||||
}
|
50
dependencies/remotelyliving/php-dns/src/Entities/IPAddress.php
vendored
Normal file
50
dependencies/remotelyliving/php-dns/src/Entities/IPAddress.php
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException;
|
||||
use function filter_var;
|
||||
use function trim;
|
||||
final class IPAddress extends EntityAbstract
|
||||
{
|
||||
private string $IPAddress;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function __construct(string $IPAddress)
|
||||
{
|
||||
$IPAddress = trim($IPAddress);
|
||||
if (self::isValid($IPAddress) === \false) {
|
||||
throw new InvalidArgumentException("{$IPAddress} is not a valid IP address");
|
||||
}
|
||||
$this->IPAddress = $IPAddress;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return $this->IPAddress;
|
||||
}
|
||||
public static function isValid(string $IPAddress) : bool
|
||||
{
|
||||
return (bool) filter_var($IPAddress, \FILTER_VALIDATE_IP);
|
||||
}
|
||||
public static function createFromString(string $IPAddress) : IPAddress
|
||||
{
|
||||
return new self($IPAddress);
|
||||
}
|
||||
public function equals(IPAddress $IPAddress) : bool
|
||||
{
|
||||
return $this->IPAddress === (string) $IPAddress;
|
||||
}
|
||||
public function getIPAddress() : string
|
||||
{
|
||||
return $this->IPAddress;
|
||||
}
|
||||
public function isIPv6() : bool
|
||||
{
|
||||
return (bool) filter_var($this->IPAddress, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6);
|
||||
}
|
||||
public function isIPv4() : bool
|
||||
{
|
||||
return (bool) filter_var($this->IPAddress, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4);
|
||||
}
|
||||
}
|
8
dependencies/remotelyliving/php-dns/src/Entities/Interfaces/Arrayable.php
vendored
Normal file
8
dependencies/remotelyliving/php-dns/src/Entities/Interfaces/Arrayable.php
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces;
|
||||
|
||||
interface Arrayable
|
||||
{
|
||||
public function toArray() : array;
|
||||
}
|
20
dependencies/remotelyliving/php-dns/src/Entities/Interfaces/DNSRecordInterface.php
vendored
Normal file
20
dependencies/remotelyliving/php-dns/src/Entities/Interfaces/DNSRecordInterface.php
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DataAbstract;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\IPAddress;
|
||||
interface DNSRecordInterface extends Arrayable, Serializable
|
||||
{
|
||||
public function getType() : DNSRecordType;
|
||||
public function getHostname() : Hostname;
|
||||
public function getTTL() : int;
|
||||
public function getIPAddress() : ?IPAddress;
|
||||
public function getClass() : string;
|
||||
public function getData() : ?DataAbstract;
|
||||
public function setTTL(int $ttl) : DNSRecordInterface;
|
||||
public function toArray() : array;
|
||||
public function equals(DNSRecordInterface $record) : bool;
|
||||
}
|
11
dependencies/remotelyliving/php-dns/src/Entities/Interfaces/Serializable.php
vendored
Normal file
11
dependencies/remotelyliving/php-dns/src/Entities/Interfaces/Serializable.php
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces;
|
||||
|
||||
use JsonSerializable;
|
||||
interface Serializable extends \Serializable, JsonSerializable
|
||||
{
|
||||
public function serialize() : string;
|
||||
public function unserialize($serialized) : void;
|
||||
public function jsonSerialize() : array;
|
||||
}
|
45
dependencies/remotelyliving/php-dns/src/Entities/MXData.php
vendored
Normal file
45
dependencies/remotelyliving/php-dns/src/Entities/MXData.php
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
final class MXData extends DataAbstract
|
||||
{
|
||||
private Hostname $target;
|
||||
private int $priority;
|
||||
public function __construct(Hostname $target, int $priority = 0)
|
||||
{
|
||||
$this->target = $target;
|
||||
$this->priority = $priority;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return "{$this->priority} {$this->target}";
|
||||
}
|
||||
public function getTarget() : Hostname
|
||||
{
|
||||
return $this->target;
|
||||
}
|
||||
public function getPriority() : int
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['target' => (string) $this->target, 'priority' => $this->priority];
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$unserialized = unserialize($serialized);
|
||||
$this->target = new Hostname($unserialized['target']);
|
||||
$this->priority = $unserialized['priority'];
|
||||
}
|
||||
}
|
38
dependencies/remotelyliving/php-dns/src/Entities/NSData.php
vendored
Normal file
38
dependencies/remotelyliving/php-dns/src/Entities/NSData.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
final class NSData extends DataAbstract
|
||||
{
|
||||
private Hostname $target;
|
||||
public function __construct(Hostname $target)
|
||||
{
|
||||
$this->target = $target;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return (string) $this->target;
|
||||
}
|
||||
public function getTarget() : Hostname
|
||||
{
|
||||
return $this->target;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['target' => (string) $this->target];
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$unserialized = unserialize($serialized);
|
||||
$this->target = new Hostname($unserialized['target']);
|
||||
}
|
||||
}
|
38
dependencies/remotelyliving/php-dns/src/Entities/PTRData.php
vendored
Normal file
38
dependencies/remotelyliving/php-dns/src/Entities/PTRData.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
final class PTRData extends DataAbstract
|
||||
{
|
||||
private Hostname $hostname;
|
||||
public function __construct(Hostname $hostname)
|
||||
{
|
||||
$this->hostname = $hostname;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return (string) $this->hostname;
|
||||
}
|
||||
public function getHostname() : Hostname
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['hostname' => (string) $this->hostname];
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$unserialized = unserialize($serialized);
|
||||
$this->hostname = new Hostname($unserialized['hostname']);
|
||||
}
|
||||
}
|
106
dependencies/remotelyliving/php-dns/src/Entities/SOAData.php
vendored
Normal file
106
dependencies/remotelyliving/php-dns/src/Entities/SOAData.php
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
use function vsprintf;
|
||||
final class SOAData extends DataAbstract
|
||||
{
|
||||
private Hostname $mname;
|
||||
private Hostname $rname;
|
||||
private int $serial;
|
||||
private int $refresh;
|
||||
private int $retry;
|
||||
private int $expire;
|
||||
private int $minTTL;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const TEMPLATE = '%s %s %s %s %s %s %s';
|
||||
public function __construct(Hostname $mname, Hostname $rname, int $serial, int $refresh, int $retry, int $expire, int $minTTL)
|
||||
{
|
||||
$this->mname = $mname;
|
||||
$this->rname = $rname;
|
||||
$this->serial = $serial;
|
||||
$this->refresh = $refresh;
|
||||
$this->retry = $retry;
|
||||
$this->expire = $expire;
|
||||
$this->minTTL = $minTTL;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return vsprintf(self::TEMPLATE, $this->toArray());
|
||||
}
|
||||
/**
|
||||
* @return \RemotelyLiving\PHPDNS\Entities\Hostname
|
||||
*/
|
||||
public function getMname() : Hostname
|
||||
{
|
||||
return $this->mname;
|
||||
}
|
||||
/**
|
||||
* @return \RemotelyLiving\PHPDNS\Entities\Hostname
|
||||
*/
|
||||
public function getRname() : Hostname
|
||||
{
|
||||
return $this->rname;
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSerial() : int
|
||||
{
|
||||
return $this->serial;
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRefresh() : int
|
||||
{
|
||||
return $this->refresh;
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRetry() : int
|
||||
{
|
||||
return $this->retry;
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getExpire() : int
|
||||
{
|
||||
return $this->expire;
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMinTTL() : int
|
||||
{
|
||||
return $this->minTTL;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['mname' => (string) $this->mname, 'rname' => (string) $this->rname, 'serial' => $this->serial, 'refresh' => $this->refresh, 'retry' => $this->retry, 'expire' => $this->expire, 'minimumTTL' => $this->minTTL];
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$unserialized = unserialize($serialized);
|
||||
$this->mname = new Hostname($unserialized['mname']);
|
||||
$this->rname = new Hostname($unserialized['rname']);
|
||||
$this->serial = $unserialized['serial'];
|
||||
$this->refresh = $unserialized['refresh'];
|
||||
$this->retry = $unserialized['retry'];
|
||||
$this->expire = $unserialized['expire'];
|
||||
$this->minTTL = $unserialized['minimumTTL'];
|
||||
}
|
||||
}
|
59
dependencies/remotelyliving/php-dns/src/Entities/SRVData.php
vendored
Normal file
59
dependencies/remotelyliving/php-dns/src/Entities/SRVData.php
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
final class SRVData extends DataAbstract
|
||||
{
|
||||
private int $priority;
|
||||
private int $weight;
|
||||
private int $port;
|
||||
private Hostname $target;
|
||||
public function __construct(int $priority, int $weight, int $port, Hostname $target)
|
||||
{
|
||||
$this->priority = $priority;
|
||||
$this->weight = $weight;
|
||||
$this->port = $port;
|
||||
$this->target = $target;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return "{$this->priority} {$this->weight} {$this->port} {$this->target}";
|
||||
}
|
||||
public function getPriority() : int
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
public function getWeight() : int
|
||||
{
|
||||
return $this->weight;
|
||||
}
|
||||
public function getPort() : int
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
public function getTarget() : Hostname
|
||||
{
|
||||
return $this->target;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['priority' => $this->priority, 'weight' => $this->weight, 'port' => $this->port, 'target' => (string) $this->target];
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$unserialized = unserialize($serialized);
|
||||
$this->priority = $unserialized['priority'];
|
||||
$this->weight = $unserialized['weight'];
|
||||
$this->port = $unserialized['port'];
|
||||
$this->target = new Hostname($unserialized['target']);
|
||||
}
|
||||
}
|
38
dependencies/remotelyliving/php-dns/src/Entities/TXTData.php
vendored
Normal file
38
dependencies/remotelyliving/php-dns/src/Entities/TXTData.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;
|
||||
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
final class TXTData extends DataAbstract
|
||||
{
|
||||
private string $value;
|
||||
public function __construct(string $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
public function getValue() : string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['value' => $this->value];
|
||||
}
|
||||
public function serialize() : string
|
||||
{
|
||||
return serialize($this->toArray());
|
||||
}
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized) : void
|
||||
{
|
||||
$unserialized = unserialize($serialized);
|
||||
$this->value = $unserialized['value'];
|
||||
}
|
||||
}
|
12
dependencies/remotelyliving/php-dns/src/Exceptions/Exception.php
vendored
Normal file
12
dependencies/remotelyliving/php-dns/src/Exceptions/Exception.php
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions;
|
||||
|
||||
use JsonSerializable;
|
||||
class Exception extends \Exception implements JsonSerializable
|
||||
{
|
||||
public function jsonSerialize() : array
|
||||
{
|
||||
return ['message' => $this->getMessage(), 'code' => $this->getCode(), 'file' => $this->getFile(), 'line' => $this->getLine(), 'trace' => $this->getTraceAsString()];
|
||||
}
|
||||
}
|
7
dependencies/remotelyliving/php-dns/src/Exceptions/InvalidArgumentException.php
vendored
Normal file
7
dependencies/remotelyliving/php-dns/src/Exceptions/InvalidArgumentException.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions;
|
||||
|
||||
final class InvalidArgumentException extends Exception
|
||||
{
|
||||
}
|
13
dependencies/remotelyliving/php-dns/src/Factories/SpatieDNS.php
vendored
Normal file
13
dependencies/remotelyliving/php-dns/src/Factories/SpatieDNS.php
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Factories;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\Spatie\Dns\Dns;
|
||||
class SpatieDNS
|
||||
{
|
||||
public function createResolver(Hostname $domain, Hostname $nameserver = null) : Dns
|
||||
{
|
||||
return new Dns((string) $domain, (string) $nameserver);
|
||||
}
|
||||
}
|
23
dependencies/remotelyliving/php-dns/src/Mappers/CloudFlare.php
vendored
Normal file
23
dependencies/remotelyliving/php-dns/src/Mappers/CloudFlare.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\IPAddress;
|
||||
use function str_ireplace;
|
||||
final class CloudFlare extends MapperAbstract
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const DATA = 'data';
|
||||
public function toDNSRecord() : DNSRecordInterface
|
||||
{
|
||||
$type = DNSRecordType::createFromInt((int) $this->fields['type']);
|
||||
$IPAddress = isset($this->fields[self::DATA]) && IPAddress::isValid($this->fields[self::DATA]) ? $this->fields[self::DATA] : null;
|
||||
$value = isset($this->fields[self::DATA]) && !$IPAddress ? str_ireplace('"', '', (string) $this->fields[self::DATA]) : null;
|
||||
return DNSRecord::createFromPrimitives((string) $type, $this->fields['name'], $this->fields['TTL'], $IPAddress, 'IN', $value);
|
||||
}
|
||||
}
|
18
dependencies/remotelyliving/php-dns/src/Mappers/Dig.php
vendored
Normal file
18
dependencies/remotelyliving/php-dns/src/Mappers/Dig.php
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
final class Dig extends MapperAbstract
|
||||
{
|
||||
public function toDNSRecord() : DNSRecordInterface
|
||||
{
|
||||
$type = new DNSRecordType($this->fields[3]);
|
||||
if ($type->isA(DNSRecordType::TYPE_A) || $type->isA(DNSRecordType::TYPE_AAAA)) {
|
||||
return DNSRecord::createFromPrimitives($this->fields[3], (string) $this->fields[0], (int) $this->fields[1], $this->fields[4]);
|
||||
}
|
||||
return DNSRecord::createFromPrimitives($this->fields[3], (string) $this->fields[0], (int) $this->fields[1], null, 'IN', $this->fields[4]);
|
||||
}
|
||||
}
|
24
dependencies/remotelyliving/php-dns/src/Mappers/GoogleDNS.php
vendored
Normal file
24
dependencies/remotelyliving/php-dns/src/Mappers/GoogleDNS.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\IPAddress;
|
||||
use function str_ireplace;
|
||||
final class GoogleDNS extends MapperAbstract
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const DATA = 'data';
|
||||
public function toDNSRecord() : DNSRecordInterface
|
||||
{
|
||||
$type = DNSRecordType::createFromInt((int) $this->fields['type']);
|
||||
$IPAddress = isset($this->fields[self::DATA]) && IPAddress::isValid($this->fields[self::DATA]) ? $this->fields[self::DATA] : null;
|
||||
$value = isset($this->fields[self::DATA]) && !$IPAddress ? str_ireplace('"', '', (string) $this->fields[self::DATA]) : null;
|
||||
return DNSRecord::createFromPrimitives((string) $type, $this->fields['name'], $this->fields['TTL'], $IPAddress, 'IN', $value);
|
||||
}
|
||||
}
|
76
dependencies/remotelyliving/php-dns/src/Mappers/LocalSystem.php
vendored
Normal file
76
dependencies/remotelyliving/php-dns/src/Mappers/LocalSystem.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use function array_flip;
|
||||
use function sprintf;
|
||||
use const DNS_A;
|
||||
use const DNS_A6;
|
||||
use const DNS_AAAA;
|
||||
use const DNS_ANY;
|
||||
use const DNS_CAA;
|
||||
use const DNS_CNAME;
|
||||
use const DNS_HINFO;
|
||||
use const DNS_MX;
|
||||
use const DNS_NAPTR;
|
||||
use const DNS_NS;
|
||||
use const DNS_PTR;
|
||||
use const DNS_SOA;
|
||||
use const DNS_SRV;
|
||||
use const DNS_TXT;
|
||||
final class LocalSystem extends MapperAbstract
|
||||
{
|
||||
private const PHP_CODE_TYPE_MAP = [DNS_A => DNSRecordType::TYPE_A, DNS_CNAME => DNSRecordType::TYPE_CNAME, DNS_HINFO => DNSRecordType::TYPE_HINFO, DNS_CAA => DNSRecordType::TYPE_CAA, DNS_MX => DNSRecordType::TYPE_MX, DNS_NS => DNSRecordType::TYPE_NS, DNS_PTR => DNSRecordType::TYPE_PTR, DNS_SOA => DNSRecordType::TYPE_SOA, DNS_TXT => DNSRecordType::TYPE_TXT, DNS_AAAA => DNSRecordType::TYPE_AAAA, DNS_SRV => DNSRecordType::TYPE_SRV, DNS_NAPTR => DNSRecordType::TYPE_NAPTR, DNS_A6 => DNSRecordType::TYPE_A6, DNS_ANY => DNSRecordType::TYPE_ANY];
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const TARGET = 'target';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const PRI = 'pri';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const TEMPLATE = '%s %s %s %s %s %s %s';
|
||||
public function toDNSRecord() : DNSRecordInterface
|
||||
{
|
||||
$IPAddress = null;
|
||||
if (isset($this->fields['ipv6'])) {
|
||||
$IPAddress = $this->fields['ipv6'];
|
||||
}
|
||||
if (isset($this->fields['ip'])) {
|
||||
$IPAddress = $this->fields['ip'];
|
||||
}
|
||||
return DNSRecord::createFromPrimitives($this->fields['type'], $this->fields['host'], $this->fields['ttl'], $IPAddress, $this->fields['class'], $this->formatData($this->fields));
|
||||
}
|
||||
public function getTypeCodeFromType(DNSRecordType $type) : int
|
||||
{
|
||||
return array_flip(self::PHP_CODE_TYPE_MAP)[(string) $type] ?? DNS_ANY;
|
||||
}
|
||||
private function formatData(array $fields) : ?string
|
||||
{
|
||||
if (isset($this->fields['flags'], $fields['tag'], $fields['value'])) {
|
||||
return "{$fields['flags']} {$fields['tag']} \"{$fields['value']}\"";
|
||||
}
|
||||
if (isset($fields['mname'])) {
|
||||
return sprintf(self::TEMPLATE, $fields['mname'], $fields['rname'], $fields['serial'], $fields['refresh'], $fields['retry'], $fields['expire'], $fields['minimum-ttl']);
|
||||
}
|
||||
if (isset($fields[self::TARGET], $fields[self::PRI], $fields['weight'], $fields['port'])) {
|
||||
return "{$fields[self::PRI]} {$fields['weight']} {$fields['port']} {$fields[self::TARGET]}";
|
||||
}
|
||||
if (isset($fields[self::TARGET], $fields[self::PRI])) {
|
||||
return "{$fields[self::PRI]} {$fields[self::TARGET]}";
|
||||
}
|
||||
if (isset($fields[self::TARGET])) {
|
||||
return $fields[self::TARGET];
|
||||
}
|
||||
if (isset($fields['txt'])) {
|
||||
return $fields['txt'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
18
dependencies/remotelyliving/php-dns/src/Mappers/MapperAbstract.php
vendored
Normal file
18
dependencies/remotelyliving/php-dns/src/Mappers/MapperAbstract.php
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
abstract class MapperAbstract implements MapperInterface
|
||||
{
|
||||
protected array $fields = [];
|
||||
public final function __construct(array $fields = [])
|
||||
{
|
||||
$this->fields = $fields;
|
||||
}
|
||||
public function mapFields(array $fields) : MapperInterface
|
||||
{
|
||||
return new static($fields);
|
||||
}
|
||||
public abstract function toDNSRecord() : DNSRecordInterface;
|
||||
}
|
10
dependencies/remotelyliving/php-dns/src/Mappers/MapperInterface.php
vendored
Normal file
10
dependencies/remotelyliving/php-dns/src/Mappers/MapperInterface.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
interface MapperInterface
|
||||
{
|
||||
public function mapFields(array $fields) : MapperInterface;
|
||||
public function toDNSRecord() : DNSRecordInterface;
|
||||
}
|
58
dependencies/remotelyliving/php-dns/src/Observability/Events/DNSQueried.php
vendored
Normal file
58
dependencies/remotelyliving/php-dns/src/Observability/Events/DNSQueried.php
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces\Resolver;
|
||||
final class DNSQueried extends ObservableEventAbstract
|
||||
{
|
||||
public const NAME = 'dns.queried';
|
||||
private Resolver $resolver;
|
||||
private Hostname $hostname;
|
||||
private DNSRecordType $recordType;
|
||||
private DNSRecordCollection $recordCollection;
|
||||
public function __construct(Resolver $resolver, Hostname $hostname, DNSRecordType $recordType, DNSRecordCollection $recordCollection = null)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->resolver = $resolver;
|
||||
$this->hostname = $hostname;
|
||||
$this->recordType = $recordType;
|
||||
$this->recordCollection = $recordCollection ?? new DNSRecordCollection();
|
||||
}
|
||||
public function getResolver() : Resolver
|
||||
{
|
||||
return $this->resolver;
|
||||
}
|
||||
public function getHostname() : Hostname
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
public function getRecordType() : DNSRecordType
|
||||
{
|
||||
return $this->recordType;
|
||||
}
|
||||
public function getRecordCollection() : DNSRecordCollection
|
||||
{
|
||||
return $this->recordCollection;
|
||||
}
|
||||
public static function getName() : string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['resolver' => $this->resolver->getName(), 'hostname' => (string) $this->hostname, 'type' => (string) $this->recordType, 'records' => $this->formatCollection($this->recordCollection), 'empty' => $this->recordCollection->isEmpty()];
|
||||
}
|
||||
private function formatCollection(DNSRecordCollection $recordCollection) : array
|
||||
{
|
||||
$formatted = [];
|
||||
foreach ($recordCollection as $record) {
|
||||
if ($record) {
|
||||
$formatted[] = $record->toArray();
|
||||
}
|
||||
}
|
||||
return $formatted;
|
||||
}
|
||||
}
|
48
dependencies/remotelyliving/php-dns/src/Observability/Events/DNSQueryFailed.php
vendored
Normal file
48
dependencies/remotelyliving/php-dns/src/Observability/Events/DNSQueryFailed.php
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\Exception;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces\Resolver;
|
||||
final class DNSQueryFailed extends ObservableEventAbstract
|
||||
{
|
||||
public const NAME = 'dns.query.failed';
|
||||
private Resolver $resolver;
|
||||
private Hostname $hostname;
|
||||
private DNSRecordType $recordType;
|
||||
private Exception $error;
|
||||
public function __construct(Resolver $resolver, Hostname $hostname, DNSRecordType $recordType, Exception $error)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->resolver = $resolver;
|
||||
$this->hostname = $hostname;
|
||||
$this->recordType = $recordType;
|
||||
$this->error = $error;
|
||||
}
|
||||
public function getResolver() : Resolver
|
||||
{
|
||||
return $this->resolver;
|
||||
}
|
||||
public function getHostName() : Hostname
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
public function getRecordType() : DNSRecordType
|
||||
{
|
||||
return $this->recordType;
|
||||
}
|
||||
public function getError() : Exception
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
public static function getName() : string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['resolver' => $this->resolver->getName(), 'hostname' => (string) $this->hostname, 'type' => (string) $this->recordType, 'error' => $this->error];
|
||||
}
|
||||
}
|
28
dependencies/remotelyliving/php-dns/src/Observability/Events/DNSQueryProfiled.php
vendored
Normal file
28
dependencies/remotelyliving/php-dns/src/Observability/Events/DNSQueryProfiled.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\Interfaces\ProfileInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\Profile;
|
||||
final class DNSQueryProfiled extends ObservableEventAbstract
|
||||
{
|
||||
public const NAME = 'dns.query.profiled';
|
||||
private ProfileInterface $profile;
|
||||
public function __construct(ProfileInterface $profile)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->profile = $profile;
|
||||
}
|
||||
public function getProfile() : ProfileInterface
|
||||
{
|
||||
return $this->profile;
|
||||
}
|
||||
public static function getName() : string
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
public function toArray() : array
|
||||
{
|
||||
return ['elapsedSeconds' => $this->profile->getElapsedSeconds(), 'transactionName' => $this->profile->getTransactionName(), 'peakMemoryUsage' => $this->profile->getPeakMemoryUsage()];
|
||||
}
|
||||
}
|
15
dependencies/remotelyliving/php-dns/src/Observability/Events/ObservableEventAbstract.php
vendored
Normal file
15
dependencies/remotelyliving/php-dns/src/Observability/Events/ObservableEventAbstract.php
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events;
|
||||
|
||||
use JsonSerializable;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\Arrayable;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\EventDispatcher\GenericEvent;
|
||||
abstract class ObservableEventAbstract extends GenericEvent implements JsonSerializable, Arrayable
|
||||
{
|
||||
public static abstract function getName() : string;
|
||||
public function jsonSerialize() : array
|
||||
{
|
||||
return [$this::getName() => $this->toArray()];
|
||||
}
|
||||
}
|
10
dependencies/remotelyliving/php-dns/src/Observability/Interfaces/Observable.php
vendored
Normal file
10
dependencies/remotelyliving/php-dns/src/Observability/Interfaces/Observable.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Interfaces;
|
||||
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
interface Observable
|
||||
{
|
||||
public function addSubscriber(EventSubscriberInterface $subscriber) : void;
|
||||
public function addListener(string $eventName, callable $listener, int $priority = 0) : void;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\Interfaces;
|
||||
|
||||
interface ProfileInterface
|
||||
{
|
||||
public function startTransaction() : void;
|
||||
public function endTransaction() : void;
|
||||
public function getTransactionName() : string;
|
||||
public function getElapsedSeconds() : float;
|
||||
public function samplePeakMemoryUsage() : void;
|
||||
public function getPeakMemoryUsage() : int;
|
||||
}
|
10
dependencies/remotelyliving/php-dns/src/Observability/Performance/Interfaces/Time.php
vendored
Normal file
10
dependencies/remotelyliving/php-dns/src/Observability/Performance/Interfaces/Time.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\Interfaces;
|
||||
|
||||
use DateTimeInterface;
|
||||
interface Time
|
||||
{
|
||||
public function getMicrotime() : float;
|
||||
public function now() : DateTimeInterface;
|
||||
}
|
44
dependencies/remotelyliving/php-dns/src/Observability/Performance/Profile.php
vendored
Normal file
44
dependencies/remotelyliving/php-dns/src/Observability/Performance/Profile.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\Interfaces\ProfileInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\Interfaces\Time;
|
||||
use function memory_get_peak_usage;
|
||||
final class Profile implements ProfileInterface
|
||||
{
|
||||
private string $transactionName;
|
||||
private float $startTime = 0.0;
|
||||
private float $stopTime = 0.0;
|
||||
private int $peakMemoryUsage = 0;
|
||||
private Time $time;
|
||||
public function __construct(string $transactionName, Time $time = null)
|
||||
{
|
||||
$this->transactionName = $transactionName;
|
||||
$this->time = $time ?? new Timer();
|
||||
}
|
||||
public function startTransaction() : void
|
||||
{
|
||||
$this->startTime = $this->time->getMicroTime();
|
||||
}
|
||||
public function endTransaction() : void
|
||||
{
|
||||
$this->stopTime = $this->time->getMicroTime();
|
||||
}
|
||||
public function getTransactionName() : string
|
||||
{
|
||||
return $this->transactionName;
|
||||
}
|
||||
public function getElapsedSeconds() : float
|
||||
{
|
||||
return $this->stopTime - $this->startTime;
|
||||
}
|
||||
public function samplePeakMemoryUsage() : void
|
||||
{
|
||||
$this->peakMemoryUsage = memory_get_peak_usage();
|
||||
}
|
||||
public function getPeakMemoryUsage() : int
|
||||
{
|
||||
return $this->peakMemoryUsage;
|
||||
}
|
||||
}
|
11
dependencies/remotelyliving/php-dns/src/Observability/Performance/ProfileFactory.php
vendored
Normal file
11
dependencies/remotelyliving/php-dns/src/Observability/Performance/ProfileFactory.php
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance;
|
||||
|
||||
class ProfileFactory
|
||||
{
|
||||
public function create(string $transactionName) : Profile
|
||||
{
|
||||
return new Profile($transactionName);
|
||||
}
|
||||
}
|
19
dependencies/remotelyliving/php-dns/src/Observability/Performance/Timer.php
vendored
Normal file
19
dependencies/remotelyliving/php-dns/src/Observability/Performance/Timer.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\Interfaces\Time;
|
||||
use function microtime;
|
||||
final class Timer implements Time
|
||||
{
|
||||
public function getMicroTime() : float
|
||||
{
|
||||
return microtime(\true);
|
||||
}
|
||||
public function now() : DateTimeInterface
|
||||
{
|
||||
return new DateTimeImmutable('now');
|
||||
}
|
||||
}
|
37
dependencies/remotelyliving/php-dns/src/Observability/Subscribers/STDIOSubscriber.php
vendored
Normal file
37
dependencies/remotelyliving/php-dns/src/Observability/Subscribers/STDIOSubscriber.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Subscribers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events\DNSQueried;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events\DNSQueryFailed;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events\DNSQueryProfiled;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events\ObservableEventAbstract;
|
||||
use SplFileObject;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use function json_encode;
|
||||
final class STDIOSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
private SplFileObject $STDOUT;
|
||||
private SplFileObject $STDERR;
|
||||
public function __construct(SplFileObject $stdOut, SplFileObject $stdErr)
|
||||
{
|
||||
$this->STDOUT = $stdOut;
|
||||
$this->STDERR = $stdErr;
|
||||
}
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [DNSQueryFailed::getName() => 'onDNSQueryFailed', DNSQueried::getName() => 'onDNSQueried', DNSQueryProfiled::getName() => 'onDNSQueryProfiled'];
|
||||
}
|
||||
public function onDNSQueryFailed(ObservableEventAbstract $event) : void
|
||||
{
|
||||
$this->STDERR->fwrite(json_encode($event, \JSON_PRETTY_PRINT) . \PHP_EOL);
|
||||
}
|
||||
public function onDNSQueried(ObservableEventAbstract $event) : void
|
||||
{
|
||||
$this->STDOUT->fwrite(json_encode($event, \JSON_PRETTY_PRINT) . \PHP_EOL);
|
||||
}
|
||||
public function onDNSQueryProfiled(ObservableEventAbstract $event) : void
|
||||
{
|
||||
$this->STDOUT->fwrite(json_encode($event, \JSON_PRETTY_PRINT) . \PHP_EOL);
|
||||
}
|
||||
}
|
53
dependencies/remotelyliving/php-dns/src/Observability/Traits/Dispatcher.php
vendored
Normal file
53
dependencies/remotelyliving/php-dns/src/Observability/Traits/Dispatcher.php
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Traits;
|
||||
|
||||
use LogicException;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events\ObservableEventAbstract;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use function call_user_func_array;
|
||||
trait Dispatcher
|
||||
{
|
||||
private ?EventDispatcherInterface $dispatcher = null;
|
||||
public function setDispatcher(EventDispatcherInterface $dispatcher) : void
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
public function addSubscriber(EventSubscriberInterface $subscriber) : void
|
||||
{
|
||||
$this->getDispatcher()->addSubscriber($subscriber);
|
||||
}
|
||||
public function addListener(string $eventName, callable $listener, int $priority = 0) : void
|
||||
{
|
||||
$this->getDispatcher()->addListener($eventName, $listener, $priority);
|
||||
}
|
||||
public function dispatch(ObservableEventAbstract $event) : void
|
||||
{
|
||||
call_user_func_array([$this->getDispatcher(), 'dispatch'], $this->getOrderedDispatcherArguments($event));
|
||||
}
|
||||
private function getOrderedDispatcherArguments(ObservableEventAbstract $event) : array
|
||||
{
|
||||
$reflection = new ReflectionClass($this->getDispatcher());
|
||||
foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
|
||||
if ($method->getName() !== 'dispatch') {
|
||||
continue;
|
||||
}
|
||||
// handle the reverse argument BC from symfony dispatcher 3.* to 4.*
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
return $parameter->getName() === 'event' ? [$event, $event::getName()] : [$event::getName(), $event];
|
||||
}
|
||||
}
|
||||
throw new LogicException('Could not determine argument order for dispatcher');
|
||||
}
|
||||
private function getDispatcher() : EventDispatcherInterface
|
||||
{
|
||||
if ($this->dispatcher === null) {
|
||||
$this->dispatcher = new EventDispatcher();
|
||||
}
|
||||
return $this->dispatcher;
|
||||
}
|
||||
}
|
21
dependencies/remotelyliving/php-dns/src/Observability/Traits/Logger.php
vendored
Normal file
21
dependencies/remotelyliving/php-dns/src/Observability/Traits/Logger.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Traits;
|
||||
|
||||
use WP_Ultimo\Dependencies\Psr\Log\LoggerInterface;
|
||||
use WP_Ultimo\Dependencies\Psr\Log\NullLogger;
|
||||
trait Logger
|
||||
{
|
||||
private ?LoggerInterface $logger = null;
|
||||
public function setLogger(LoggerInterface $logger) : void
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
protected function getLogger() : LoggerInterface
|
||||
{
|
||||
if ($this->logger === null) {
|
||||
$this->logger = new NullLogger();
|
||||
}
|
||||
return $this->logger;
|
||||
}
|
||||
}
|
25
dependencies/remotelyliving/php-dns/src/Observability/Traits/Profileable.php
vendored
Normal file
25
dependencies/remotelyliving/php-dns/src/Observability/Traits/Profileable.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Traits;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\Profile;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Performance\ProfileFactory;
|
||||
trait Profileable
|
||||
{
|
||||
private ?ProfileFactory $profileFactory = null;
|
||||
public function createProfile(string $transactionName) : Profile
|
||||
{
|
||||
return $this->getProfileFactory()->create($transactionName);
|
||||
}
|
||||
public function setProfileFactory(ProfileFactory $profileFactory) : void
|
||||
{
|
||||
$this->profileFactory = $profileFactory;
|
||||
}
|
||||
private function getProfileFactory() : ProfileFactory
|
||||
{
|
||||
if ($this->profileFactory === null) {
|
||||
$this->profileFactory = new ProfileFactory();
|
||||
}
|
||||
return $this->profileFactory;
|
||||
}
|
||||
}
|
94
dependencies/remotelyliving/php-dns/src/Resolvers/Cached.php
vendored
Normal file
94
dependencies/remotelyliving/php-dns/src/Resolvers/Cached.php
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers;
|
||||
|
||||
use WP_Ultimo\Dependencies\Psr\Cache\CacheItemPoolInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Traits\Time;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces\Resolver;
|
||||
use function count;
|
||||
use function max;
|
||||
use function md5;
|
||||
use function min;
|
||||
use function sprintf;
|
||||
final class Cached extends ResolverAbstract
|
||||
{
|
||||
use Time;
|
||||
protected const DEFAULT_CACHE_TTL = 300;
|
||||
private const CACHE_KEY_TEMPLATE = '%s:%s:%s';
|
||||
private CacheItemPoolInterface $cache;
|
||||
private Resolver $resolver;
|
||||
/**
|
||||
* Bump this number on breaking changes to invalidate cache
|
||||
*/
|
||||
private const NAMESPACE = 'php-dns-v4.0.1';
|
||||
private ?int $ttlSeconds;
|
||||
private bool $shouldCacheEmptyResults = \true;
|
||||
public function __construct(CacheItemPoolInterface $cache, Resolver $resolver, int $ttlSeconds = null)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
$this->resolver = $resolver;
|
||||
$this->ttlSeconds = $ttlSeconds;
|
||||
}
|
||||
public function flush() : void
|
||||
{
|
||||
$this->cache->clear();
|
||||
}
|
||||
public function withEmptyResultCachingDisabled() : self
|
||||
{
|
||||
$emptyCachingDisabled = new self($this->cache, $this->resolver, $this->ttlSeconds);
|
||||
$emptyCachingDisabled->shouldCacheEmptyResults = \false;
|
||||
return $emptyCachingDisabled;
|
||||
}
|
||||
protected function doQuery(Hostname $hostname, DNSRecordType $recordType) : DNSRecordCollection
|
||||
{
|
||||
$cachedResult = $this->cache->getItem($this->buildCacheKey($hostname, $recordType));
|
||||
if ($cachedResult->isHit()) {
|
||||
return $this->unwrapResults($cachedResult->get());
|
||||
}
|
||||
$dnsRecords = $this->resolver->getRecords((string) $hostname, (string) $recordType);
|
||||
if ($dnsRecords->isEmpty() && $this->shouldCacheEmptyResults === \false) {
|
||||
return $dnsRecords;
|
||||
}
|
||||
$ttlSeconds = $this->ttlSeconds ?? $this->extractLowestTTL($dnsRecords);
|
||||
$cachedResult->expiresAfter($ttlSeconds);
|
||||
$cachedResult->set(['recordCollection' => $dnsRecords, 'timestamp' => $this->getTimeStamp()]);
|
||||
$this->cache->save($cachedResult);
|
||||
return $dnsRecords;
|
||||
}
|
||||
private function buildCacheKey(Hostname $hostname, DNSRecordType $recordType) : string
|
||||
{
|
||||
return md5(sprintf(self::CACHE_KEY_TEMPLATE, self::NAMESPACE, (string) $hostname, (string) $recordType));
|
||||
}
|
||||
private function extractLowestTTL(DNSRecordCollection $recordCollection) : int
|
||||
{
|
||||
$ttls = [];
|
||||
/** @var \RemotelyLiving\PHPDNS\Entities\DNSRecord $record */
|
||||
foreach ($recordCollection as $record) {
|
||||
/** @scrutinizer ignore-call */
|
||||
if ($record->getTTL() <= 0) {
|
||||
continue;
|
||||
}
|
||||
$ttls[] = $record->getTTL();
|
||||
}
|
||||
return count($ttls) ? min($ttls) : self::DEFAULT_CACHE_TTL;
|
||||
}
|
||||
/**
|
||||
* @param array $results ['recordCollection' => $recordCollection, 'timestamp' => $timeStamp]
|
||||
*/
|
||||
private function unwrapResults(array $results) : DNSRecordCollection
|
||||
{
|
||||
/** @var DNSRecordCollection $records */
|
||||
$records = $results['recordCollection'];
|
||||
/**
|
||||
* @var int $key
|
||||
* @var \RemotelyLiving\PHPDNS\Entities\DNSRecord $record
|
||||
*/
|
||||
foreach ($records as $key => $record) {
|
||||
$records[$key] = $record->setTTL(max($record->getTTL() - ($this->getTimeStamp() - (int) $results['timestamp']), 0));
|
||||
}
|
||||
return $records;
|
||||
}
|
||||
}
|
119
dependencies/remotelyliving/php-dns/src/Resolvers/Chain.php
vendored
Normal file
119
dependencies/remotelyliving/php-dns/src/Resolvers/Chain.php
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers;
|
||||
|
||||
use WP_Ultimo\Dependencies\Psr\Log\LoggerAwareInterface;
|
||||
use WP_Ultimo\Dependencies\Psr\Log\LoggerInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\Exception;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Interfaces\Observable;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces\Resolver;
|
||||
use WP_Ultimo\Dependencies\Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use function json_encode;
|
||||
use function shuffle;
|
||||
final class Chain extends ResolverAbstract implements Interfaces\Chain
|
||||
{
|
||||
public const STRATEGY_FIRST_TO_FIND = 0;
|
||||
public const STRATEGY_ALL_RESULTS = 1;
|
||||
public const STRATEGY_CONSENSUS = 2;
|
||||
/**
|
||||
* @var \RemotelyLiving\PHPDNS\Resolvers\Interfaces\Resolver[]
|
||||
*/
|
||||
private array $resolvers = [];
|
||||
private int $callThroughStrategy = self::STRATEGY_FIRST_TO_FIND;
|
||||
public function __construct(Resolver ...$resolvers)
|
||||
{
|
||||
foreach ($resolvers as $resolver) {
|
||||
$this->pushResolver($resolver);
|
||||
}
|
||||
}
|
||||
public function pushResolver(Resolver ...$resolvers) : void
|
||||
{
|
||||
foreach ($resolvers as $resolver) {
|
||||
$this->resolvers[] = $resolver;
|
||||
}
|
||||
}
|
||||
public function withAllResults() : Interfaces\Chain
|
||||
{
|
||||
$all = new self(...$this->resolvers);
|
||||
$all->callThroughStrategy = self::STRATEGY_ALL_RESULTS;
|
||||
return $all;
|
||||
}
|
||||
public function withFirstResults() : Interfaces\Chain
|
||||
{
|
||||
$first = new self(...$this->resolvers);
|
||||
$first->callThroughStrategy = self::STRATEGY_FIRST_TO_FIND;
|
||||
return $first;
|
||||
}
|
||||
public function withConsensusResults() : Interfaces\Chain
|
||||
{
|
||||
$consensus = new self(...$this->resolvers);
|
||||
$consensus->callThroughStrategy = self::STRATEGY_CONSENSUS;
|
||||
return $consensus;
|
||||
}
|
||||
public function randomly() : Interfaces\Chain
|
||||
{
|
||||
$randomized = clone $this;
|
||||
shuffle($randomized->resolvers);
|
||||
return $randomized;
|
||||
}
|
||||
public function addSubscriber(EventSubscriberInterface $subscriber) : void
|
||||
{
|
||||
foreach ($this->resolvers as $resolver) {
|
||||
if ($resolver instanceof Observable) {
|
||||
$resolver->addSubscriber($subscriber);
|
||||
}
|
||||
}
|
||||
}
|
||||
public function addListener(string $eventName, callable $listener, int $priority = 0) : void
|
||||
{
|
||||
foreach ($this->resolvers as $resolver) {
|
||||
if ($resolver instanceof Observable) {
|
||||
$resolver->addListener($eventName, $listener, $priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
public function setLogger(LoggerInterface $logger) : void
|
||||
{
|
||||
foreach ($this->resolvers as $resolver) {
|
||||
if ($resolver instanceof LoggerAwareInterface) {
|
||||
$resolver->setLogger($logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
public function hasRecord(DNSRecordInterface $record) : bool
|
||||
{
|
||||
foreach ($this->resolvers as $resolver) {
|
||||
if ($resolver->hasRecord($record)) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
protected function doQuery(Hostname $hostname, DNSRecordType $recordType) : DNSRecordCollection
|
||||
{
|
||||
$merged = [];
|
||||
foreach ($this->resolvers as $resolver) {
|
||||
try {
|
||||
$records = $resolver->getRecords((string) $hostname, (string) $recordType);
|
||||
} catch (Exception $e) {
|
||||
$this->getLogger()->error('Something went wrong in the chain of resolvers', ['exception' => json_encode($e), 'resolver' => $resolver->getName()]);
|
||||
continue;
|
||||
}
|
||||
if ($this->callThroughStrategy === self::STRATEGY_FIRST_TO_FIND && !$records->isEmpty()) {
|
||||
return $records;
|
||||
}
|
||||
/** @var DNSRecord $record */
|
||||
foreach ($records as $record) {
|
||||
$merged[] = $record;
|
||||
}
|
||||
}
|
||||
$collection = new DNSRecordCollection(...$merged);
|
||||
return $this->callThroughStrategy === self::STRATEGY_CONSENSUS ? $collection->withUniqueValuesExcluded() : $collection->withUniqueValues();
|
||||
}
|
||||
}
|
83
dependencies/remotelyliving/php-dns/src/Resolvers/CloudFlare.php
vendored
Normal file
83
dependencies/remotelyliving/php-dns/src/Resolvers/CloudFlare.php
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers;
|
||||
|
||||
use Generator;
|
||||
use WP_Ultimo\Dependencies\GuzzleHttp\Client;
|
||||
use WP_Ultimo\Dependencies\GuzzleHttp\ClientInterface;
|
||||
use WP_Ultimo\Dependencies\GuzzleHttp\Promise\EachPromise;
|
||||
use WP_Ultimo\Dependencies\Psr\Http\Message\ResponseInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers\CloudFlare as CloudFlareMapper;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure;
|
||||
use Throwable;
|
||||
use function array_merge;
|
||||
use function http_build_query;
|
||||
use function json_decode;
|
||||
final class CloudFlare extends ResolverAbstract
|
||||
{
|
||||
protected const BASE_URI = 'https://cloudflare-dns.com';
|
||||
protected const DEFAULT_TIMEOUT = 5.0;
|
||||
public const DEFAULT_OPTIONS = ['base_uri' => self::BASE_URI, 'connect_timeout' => self::DEFAULT_TIMEOUT, 'strict' => \true, 'allow_redirects' => \false, 'protocols' => ['https'], 'headers' => ['Accept' => 'application/dns-json']];
|
||||
private ClientInterface $http;
|
||||
private CloudFlareMapper $mapper;
|
||||
/**
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
private array $options;
|
||||
public function __construct(ClientInterface $http = null, CloudFlareMapper $mapper = null, array $options = self::DEFAULT_OPTIONS)
|
||||
{
|
||||
$this->http = $http ?? new Client();
|
||||
$this->mapper = $mapper ?? new CloudFlareMapper();
|
||||
$this->options = $options;
|
||||
}
|
||||
protected function doQuery(Hostname $hostname, DNSRecordType $recordType) : DNSRecordCollection
|
||||
{
|
||||
try {
|
||||
return !$recordType->isA(DNSRecordType::TYPE_ANY) ? $this->doApiQuery($hostname, $recordType) : $this->doAnyApiQuery($hostname);
|
||||
} catch (Throwable $e) {
|
||||
throw new QueryFailure("Unable to query CloudFlare API", 0, $e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Cloudflare does not support ANY queries, so we must ask for all record types individually
|
||||
*/
|
||||
private function doAnyApiQuery(Hostname $hostname) : DNSRecordCollection
|
||||
{
|
||||
$results = [];
|
||||
$eachPromise = new EachPromise($this->generateEachTypeQuery($hostname), ['concurrency' => 4, 'fulfilled' => function (ResponseInterface $response) use(&$results) {
|
||||
$results = array_merge($results, $this->parseResult((array) json_decode((string) $response->getBody(), \true)));
|
||||
}, 'rejected' => function (Throwable $e) : void {
|
||||
throw $e;
|
||||
}]);
|
||||
$eachPromise->promise()->wait(\true);
|
||||
return $this->mapResults($this->mapper, $results);
|
||||
}
|
||||
private function generateEachTypeQuery(Hostname $hostname) : Generator
|
||||
{
|
||||
foreach (DNSRecordType::VALID_TYPES as $type) {
|
||||
if ($type === DNSRecordType::TYPE_ANY) {
|
||||
continue 1;
|
||||
}
|
||||
(yield $this->http->requestAsync('GET', '/dns-query?' . http_build_query(['name' => (string) $hostname, 'type' => $type]), $this->options));
|
||||
}
|
||||
}
|
||||
private function doApiQuery(Hostname $hostname, DNSRecordType $type) : DNSRecordCollection
|
||||
{
|
||||
$url = '/dns-query?' . http_build_query(['name' => (string) $hostname, 'type' => (string) $type]);
|
||||
$decoded = (array) json_decode((string) $this->http->requestAsync('GET', $url, $this->options)->wait(\true)->getBody(), \true);
|
||||
return $this->mapResults($this->mapper, $this->parseResult($decoded));
|
||||
}
|
||||
private function parseResult(array $result) : array
|
||||
{
|
||||
if (isset($result['Answer'])) {
|
||||
return $result['Answer'];
|
||||
}
|
||||
if (isset($result['Authority'])) {
|
||||
return $result['Authority'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
73
dependencies/remotelyliving/php-dns/src/Resolvers/Dig.php
vendored
Normal file
73
dependencies/remotelyliving/php-dns/src/Resolvers/Dig.php
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Factories\SpatieDNS;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers\Dig as DigMapper;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure;
|
||||
use Throwable;
|
||||
use function array_slice;
|
||||
use function explode;
|
||||
use function implode;
|
||||
use function preg_replace;
|
||||
use function trim;
|
||||
final class Dig extends ResolverAbstract
|
||||
{
|
||||
public const SUPPORTED_QUERY_TYPES = [DNSRecordType::TYPE_A, DNSRecordType::TYPE_AAAA, DNSRecordType::TYPE_CNAME, DNSRecordType::TYPE_NS, DNSRecordType::TYPE_SOA, DNSRecordType::TYPE_MX, DNSRecordType::TYPE_SRV, DNSRecordType::TYPE_TXT, DNSRecordType::TYPE_CAA, DNSRecordType::TYPE_NAPTR];
|
||||
private SpatieDNS $spatieDNSFactory;
|
||||
private DigMapper $mapper;
|
||||
private ?Hostname $nameserver;
|
||||
public function __construct(SpatieDNS $spatieDNSFactory = null, DigMapper $mapper = null, Hostname $nameserver = null)
|
||||
{
|
||||
$this->spatieDNSFactory = $spatieDNSFactory ?? new SpatieDNS();
|
||||
$this->mapper = $mapper ?? new DigMapper();
|
||||
$this->nameserver = $nameserver;
|
||||
}
|
||||
protected function doQuery(Hostname $hostname, DNSRecordType $recordType) : DNSRecordCollection
|
||||
{
|
||||
if (!self::isSupportedQueryType($recordType)) {
|
||||
return new DNSRecordCollection();
|
||||
}
|
||||
$dig = $this->spatieDNSFactory->createResolver($hostname, $this->nameserver);
|
||||
try {
|
||||
$response = $recordType->equals(DNSRecordType::createANY()) ? $dig->getRecords(...self::SUPPORTED_QUERY_TYPES) : $dig->getRecords((string) $recordType);
|
||||
} catch (Throwable $e) {
|
||||
throw new QueryFailure($e->getMessage(), 0, $e);
|
||||
}
|
||||
return $this->mapResults($this->mapper, self::parseDigResponseToRows($response));
|
||||
}
|
||||
private static function parseDigResponseToRows(string $digResponse) : array
|
||||
{
|
||||
$rows = [];
|
||||
foreach (explode(\PHP_EOL, self::normalizeColumns($digResponse)) as $line) {
|
||||
if (!trim($line)) {
|
||||
continue;
|
||||
}
|
||||
$columns = explode(' ', $line);
|
||||
$rows[] = [$columns[0], $columns[1], $columns[2], $columns[3], implode(' ', array_slice($columns, 4))];
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
private static function normalizeColumns(string $response) : string
|
||||
{
|
||||
$keysRemoved = preg_replace('/;(.*)/m', ' ', trim($response));
|
||||
$tabsRemoved = preg_replace('/(\\t+)/m', ' ', (string) $keysRemoved);
|
||||
$breaksRemoved = preg_replace('/\\s\\s/m', '', (string) $tabsRemoved);
|
||||
return (string) preg_replace('/(\\(\\s|(\\s\\)))/m', '', (string) $breaksRemoved);
|
||||
}
|
||||
private static function isSupportedQueryType(DNSRecordType $type) : bool
|
||||
{
|
||||
if ($type->isA(DNSRecordType::TYPE_ANY)) {
|
||||
return \true;
|
||||
}
|
||||
foreach (self::SUPPORTED_QUERY_TYPES as $queryType) {
|
||||
if ($type->isA($queryType)) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
8
dependencies/remotelyliving/php-dns/src/Resolvers/Exceptions/QueryFailure.php
vendored
Normal file
8
dependencies/remotelyliving/php-dns/src/Resolvers/Exceptions/QueryFailure.php
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Exceptions;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\Exception;
|
||||
class QueryFailure extends Exception
|
||||
{
|
||||
}
|
7
dependencies/remotelyliving/php-dns/src/Resolvers/Exceptions/ReverseLookupFailure.php
vendored
Normal file
7
dependencies/remotelyliving/php-dns/src/Resolvers/Exceptions/ReverseLookupFailure.php
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Exceptions;
|
||||
|
||||
final class ReverseLookupFailure extends QueryFailure
|
||||
{
|
||||
}
|
73
dependencies/remotelyliving/php-dns/src/Resolvers/GoogleDNS.php
vendored
Normal file
73
dependencies/remotelyliving/php-dns/src/Resolvers/GoogleDNS.php
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers;
|
||||
|
||||
use WP_Ultimo\Dependencies\GuzzleHttp\Client;
|
||||
use WP_Ultimo\Dependencies\GuzzleHttp\ClientInterface;
|
||||
use WP_Ultimo\Dependencies\GuzzleHttp\Exception\RequestException;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers\GoogleDNS as GoogleDNSMapper;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure;
|
||||
use Throwable;
|
||||
use function http_build_query;
|
||||
use function json_decode;
|
||||
final class GoogleDNS extends ResolverAbstract
|
||||
{
|
||||
protected const BASE_URI = 'https://dns.google.com';
|
||||
protected const DEFAULT_TIMEOUT = 5.0;
|
||||
public const DEFAULT_OPTIONS = ['base_uri' => self::BASE_URI, 'strict' => \true, 'allow_redirects' => \false, 'connect_timeout' => self::DEFAULT_TIMEOUT, 'protocols' => ['https'], 'headers' => ['Accept' => 'application/json']];
|
||||
private ClientInterface $http;
|
||||
private GoogleDNSMapper $mapper;
|
||||
private int $consensusAttempts;
|
||||
/**
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
private array $options;
|
||||
public function __construct(ClientInterface $http = null, GoogleDNSMapper $mapper = null, int $consensusAttempts = 3, array $options = self::DEFAULT_OPTIONS)
|
||||
{
|
||||
$this->http = $http ?? new Client();
|
||||
$this->mapper = $mapper ?? new GoogleDNSMapper();
|
||||
$this->consensusAttempts = $consensusAttempts;
|
||||
$this->options = $options;
|
||||
}
|
||||
/**
|
||||
* Google DNS has consistency issues so this tries a few times to get an answer
|
||||
*/
|
||||
public function hasRecord(DNSRecordInterface $record) : bool
|
||||
{
|
||||
$attempts = 0;
|
||||
do {
|
||||
$hasRecord = $this->getRecords((string) $record->getHostname(), (string) $record->getType())->has($record);
|
||||
++$attempts;
|
||||
} while ($hasRecord === \false && $attempts < $this->consensusAttempts);
|
||||
return $hasRecord;
|
||||
}
|
||||
protected function doQuery(Hostname $hostname, DNSRecordType $recordType) : DNSRecordCollection
|
||||
{
|
||||
$results = $this->doApiQuery(['name' => (string) $hostname, 'type' => (string) $recordType]);
|
||||
return $this->mapResults($this->mapper, $results);
|
||||
}
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
private function doApiQuery(array $query = []) : array
|
||||
{
|
||||
try {
|
||||
$response = $this->http->request('GET', '/resolve?' . http_build_query($query), $this->options);
|
||||
} catch (Throwable $e) {
|
||||
throw new QueryFailure("Unable to query GoogleDNS API", 0, $e);
|
||||
}
|
||||
$result = (array) json_decode((string) $response->getBody(), \true);
|
||||
if (isset($result['Answer'])) {
|
||||
return $result['Answer'];
|
||||
}
|
||||
if (isset($result['Authority'])) {
|
||||
return $result['Authority'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
26
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/Chain.php
vendored
Normal file
26
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/Chain.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces;
|
||||
|
||||
interface Chain extends Resolver
|
||||
{
|
||||
/**
|
||||
* Randomizes the order in with the chain is called
|
||||
*/
|
||||
public function randomly() : Chain;
|
||||
/**
|
||||
* Returns all the records from each Resolver together.
|
||||
* This calls all Resolvers in the chain.
|
||||
*/
|
||||
public function withAllResults() : Chain;
|
||||
/**
|
||||
* Returns the results from the first Resolver to have results.
|
||||
* This calls as many Resolvers as it needs to find the first result.
|
||||
*/
|
||||
public function withFirstResults() : Chain;
|
||||
/**
|
||||
* Returns only the common results between Resolvers that had results.
|
||||
* This calls through all Resolvers in the chain
|
||||
*/
|
||||
public function withConsensusResults() : Chain;
|
||||
}
|
44
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/DNSQuery.php
vendored
Normal file
44
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/DNSQuery.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
interface DNSQuery
|
||||
{
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getARecords(string $hostname) : DNSRecordCollection;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getAAAARecords(string $hostname) : DNSRecordCollection;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getCNAMERecords(string $hostname) : DNSRecordCollection;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getTXTRecords(string $hostname) : DNSRecordCollection;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getMXRecords(string $hostname) : DNSRecordCollection;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getRecords(string $hostname, string $recordType = null) : DNSRecordCollection;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function recordTypeExists(string $hostname, string $recordType) : bool;
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function hasRecord(DNSRecordInterface $record) : bool;
|
||||
}
|
9
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/ObservableResolver.php
vendored
Normal file
9
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/ObservableResolver.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces;
|
||||
|
||||
use WP_Ultimo\Dependencies\Psr\Log\LoggerAwareInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Interfaces\Observable;
|
||||
interface ObservableResolver extends Resolver, Observable, LoggerAwareInterface
|
||||
{
|
||||
}
|
8
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/Resolver.php
vendored
Normal file
8
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/Resolver.php
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces;
|
||||
|
||||
interface Resolver extends DNSQuery
|
||||
{
|
||||
public function getName() : string;
|
||||
}
|
13
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/ReverseDNSQuery.php
vendored
Normal file
13
dependencies/remotelyliving/php-dns/src/Resolvers/Interfaces/ReverseDNSQuery.php
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\IPAddress;
|
||||
interface ReverseDNSQuery
|
||||
{
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\ReverseLookupFailure
|
||||
*/
|
||||
public function getHostnameByAddress(string $IPAddress) : Hostname;
|
||||
}
|
40
dependencies/remotelyliving/php-dns/src/Resolvers/LocalSystem.php
vendored
Normal file
40
dependencies/remotelyliving/php-dns/src/Resolvers/LocalSystem.php
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\IPAddress;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers\LocalSystem as LocalMapper;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces\ReverseDNSQuery;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Services\Interfaces\LocalSystemDNS;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Services\LocalSystemDNS as LocalDNSService;
|
||||
final class LocalSystem extends ResolverAbstract implements ReverseDNSQuery
|
||||
{
|
||||
private LocalSystemDNS $systemDNS;
|
||||
private LocalMapper $mapper;
|
||||
public function __construct(LocalSystemDNS $systemDNS = null, LocalMapper $mapper = null)
|
||||
{
|
||||
$this->systemDNS = $systemDNS ?? new LocalDNSService();
|
||||
$this->mapper = $mapper ?? new LocalMapper();
|
||||
}
|
||||
public function getHostnameByAddress(string $IPAddress) : Hostname
|
||||
{
|
||||
$result = $this->systemDNS->getHostnameByAddress((string) new IPAddress($IPAddress));
|
||||
return Hostname::createFromString($result);
|
||||
}
|
||||
protected function doQuery(Hostname $hostname, DNSRecordType $recordType) : DNSRecordCollection
|
||||
{
|
||||
$results = $this->systemDNS->getRecord(
|
||||
$hostname->getHostnameWithoutTrailingDot(),
|
||||
// dns_get_record doesn't like trailing dot as much!
|
||||
$this->mapper->getTypeCodeFromType($recordType)
|
||||
);
|
||||
$collection = new DNSRecordCollection();
|
||||
foreach ($results as $result) {
|
||||
$collection[] = $this->mapper->mapFields($result)->toDNSRecord();
|
||||
}
|
||||
return $collection;
|
||||
}
|
||||
}
|
115
dependencies/remotelyliving/php-dns/src/Resolvers/ResolverAbstract.php
vendored
Normal file
115
dependencies/remotelyliving/php-dns/src/Resolvers/ResolverAbstract.php
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecord;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Interfaces\DNSRecordInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\DNSRecordType;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities\Hostname;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Mappers\MapperInterface;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events\DNSQueried;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events\DNSQueryFailed;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Events\DNSQueryProfiled;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Traits\Dispatcher;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Traits\Logger;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Observability\Traits\Profileable;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Interfaces\ObservableResolver;
|
||||
use function array_map;
|
||||
use function array_pop;
|
||||
use function explode;
|
||||
use function get_class;
|
||||
use function json_encode;
|
||||
abstract class ResolverAbstract implements ObservableResolver
|
||||
{
|
||||
use Logger;
|
||||
use Dispatcher;
|
||||
use Profileable;
|
||||
private string $name;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const EVENT = 'event';
|
||||
public function getName() : string
|
||||
{
|
||||
if (!isset($this->name)) {
|
||||
$explodedClass = explode('\\', get_class($this));
|
||||
$this->name = array_pop($explodedClass);
|
||||
}
|
||||
return $this->name;
|
||||
}
|
||||
public function getARecords(string $hostname) : DNSRecordCollection
|
||||
{
|
||||
return $this->getRecords($hostname, (string) DNSRecordType::createA());
|
||||
}
|
||||
public function getAAAARecords(string $hostname) : DNSRecordCollection
|
||||
{
|
||||
return $this->getRecords($hostname, (string) DNSRecordType::createAAAA());
|
||||
}
|
||||
public function getCNAMERecords(string $hostname) : DNSRecordCollection
|
||||
{
|
||||
return $this->getRecords($hostname, (string) DNSRecordType::createCNAME());
|
||||
}
|
||||
public function getTXTRecords(string $hostname) : DNSRecordCollection
|
||||
{
|
||||
return $this->getRecords($hostname, (string) DNSRecordType::createTXT());
|
||||
}
|
||||
public function getMXRecords(string $hostname) : DNSRecordCollection
|
||||
{
|
||||
return $this->getRecords($hostname, (string) DNSRecordType::createMX());
|
||||
}
|
||||
public function recordTypeExists(string $hostname, string $recordType) : bool
|
||||
{
|
||||
return !$this->getRecords($hostname, $recordType)->isEmpty();
|
||||
}
|
||||
public function hasRecord(DNSRecordInterface $record) : bool
|
||||
{
|
||||
return $this->getRecords((string) $record->getHostname(), (string) $record->getType())->has($record);
|
||||
}
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getRecords(string $hostname, string $recordType = null) : DNSRecordCollection
|
||||
{
|
||||
$recordType = DNSRecordType::createFromString($recordType ?? 'ANY');
|
||||
$hostname = Hostname::createFromString($hostname);
|
||||
$profile = $this->createProfile("{$this->getName()}:{$hostname}:{$recordType}");
|
||||
$profile->startTransaction();
|
||||
try {
|
||||
$result = $recordType->equals(DNSRecordType::createANY()) ? $this->doQuery($hostname, $recordType) : $this->doQuery($hostname, $recordType)->filteredByType($recordType);
|
||||
} catch (QueryFailure $e) {
|
||||
$dnsQueryFailureEvent = new DNSQueryFailed($this, $hostname, $recordType, $e);
|
||||
$this->dispatch($dnsQueryFailureEvent);
|
||||
$this->getLogger()->error('DNS query failed', [self::EVENT => json_encode($dnsQueryFailureEvent), 'exception' => $e]);
|
||||
throw $e;
|
||||
} finally {
|
||||
$profile->endTransaction();
|
||||
$profile->samplePeakMemoryUsage();
|
||||
$dnsQueryProfiledEvent = new DNSQueryProfiled($profile);
|
||||
$this->dispatch($dnsQueryProfiledEvent);
|
||||
$this->getLogger()->info('DNS query profiled', [self::EVENT => json_encode($dnsQueryProfiledEvent)]);
|
||||
}
|
||||
$dnsQueriedEvent = new DNSQueried($this, $hostname, $recordType, $result);
|
||||
$this->dispatch($dnsQueriedEvent);
|
||||
$this->getLogger()->info('DNS queried', [self::EVENT => json_encode($dnsQueriedEvent)]);
|
||||
return $result;
|
||||
}
|
||||
public function mapResults(MapperInterface $mapper, array $results) : DNSRecordCollection
|
||||
{
|
||||
$collection = new DNSRecordCollection();
|
||||
array_map(function (array $fields) use(&$collection, $mapper) {
|
||||
try {
|
||||
$collection[] = $mapper->mapFields($fields)->toDNSRecord();
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$this->getLogger()->warning('Invalid fields passed to mapper', $fields);
|
||||
}
|
||||
}, $results);
|
||||
return $collection;
|
||||
}
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
protected abstract function doQuery(Hostname $hostname, DNSRecordType $recordType) : DNSRecordCollection;
|
||||
}
|
24
dependencies/remotelyliving/php-dns/src/Resolvers/Traits/Time.php
vendored
Normal file
24
dependencies/remotelyliving/php-dns/src/Resolvers/Traits/Time.php
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Traits;
|
||||
|
||||
use DateTimeImmutable;
|
||||
trait Time
|
||||
{
|
||||
private ?DateTimeImmutable $dateTimeImmutable = null;
|
||||
public function setDateTimeImmutable(DateTimeImmutable $dateTimeImmutable) : void
|
||||
{
|
||||
$this->dateTimeImmutable = $dateTimeImmutable;
|
||||
}
|
||||
public function getTimeStamp() : int
|
||||
{
|
||||
return $this->getNewDateTimeImmutable()->getTimestamp();
|
||||
}
|
||||
private function getNewDateTimeImmutable() : DateTimeImmutable
|
||||
{
|
||||
if (!$this->dateTimeImmutable) {
|
||||
$this->dateTimeImmutable = new DateTimeImmutable();
|
||||
}
|
||||
return $this->dateTimeImmutable->setTimestamp(\time());
|
||||
}
|
||||
}
|
23
dependencies/remotelyliving/php-dns/src/Services/Interfaces/LocalSystemDNS.php
vendored
Normal file
23
dependencies/remotelyliving/php-dns/src/Services/Interfaces/LocalSystemDNS.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Services\Interfaces;
|
||||
|
||||
interface LocalSystemDNS
|
||||
{
|
||||
/**
|
||||
* @param string $IPAddress
|
||||
* @return string
|
||||
*
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\ReverseLookupFailure
|
||||
*/
|
||||
public function getHostnameByAddress(string $IPAddress) : string;
|
||||
/**
|
||||
* @param string $hostname
|
||||
* @param int $type
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getRecord(string $hostname, int $type) : array;
|
||||
}
|
37
dependencies/remotelyliving/php-dns/src/Services/LocalSystemDNS.php
vendored
Normal file
37
dependencies/remotelyliving/php-dns/src/Services/LocalSystemDNS.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Services;
|
||||
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Resolvers\Exceptions\ReverseLookupFailure;
|
||||
use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Services\Interfaces\LocalSystemDNS as LocalSystemDNSInterface;
|
||||
use function dns_get_record;
|
||||
use function gethostbyaddr;
|
||||
final class LocalSystemDNS implements LocalSystemDNSInterface
|
||||
{
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure
|
||||
*/
|
||||
public function getRecord(string $hostname, int $type) : array
|
||||
{
|
||||
$results = @dns_get_record($hostname, $type);
|
||||
// this is untestable without creating a system networking failure
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($results === \false) {
|
||||
throw new QueryFailure();
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
return $results;
|
||||
}
|
||||
/**
|
||||
* @throws \RemotelyLiving\PHPDNS\Resolvers\Exceptions\ReverseLookupFailure
|
||||
*/
|
||||
public function getHostnameByAddress(string $IPAddress) : string
|
||||
{
|
||||
$hostname = @gethostbyaddr($IPAddress);
|
||||
if ($hostname === $IPAddress || $hostname === \false) {
|
||||
throw new ReverseLookupFailure();
|
||||
}
|
||||
return $hostname;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user