Skip to content

Commit

Permalink
Add native types to public API
Browse files Browse the repository at this point in the history
This changeset adds native types to the public API as discussed in reactphp#219.

Once merged, I'm planning to add PHPStan in a follow-up PR which would take advantage of these types.

Builds on top of reactphp#222, reactphp#223 and reactphp/cache#60
  • Loading branch information
WyriHaximus committed May 27, 2024
1 parent d9681b1 commit fb61ef0
Show file tree
Hide file tree
Showing 16 changed files with 71 additions and 47 deletions.
9 changes: 6 additions & 3 deletions src/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ final class Config
* @return self
* @codeCoverageIgnore
*/
public static function loadSystemConfigBlocking()
public static function loadSystemConfigBlocking(): self
{
// Use WMIC output on Windows
if (DIRECTORY_SEPARATOR === '\\') {
Expand Down Expand Up @@ -71,7 +71,7 @@ public static function loadSystemConfigBlocking()
* @return self
* @throws RuntimeException if the path can not be loaded (does not exist)
*/
public static function loadResolvConfBlocking($path = null)
public static function loadResolvConfBlocking(?string $path = null): self
{
if ($path === null) {
$path = '/etc/resolv.conf';
Expand Down Expand Up @@ -122,7 +122,7 @@ public static function loadResolvConfBlocking($path = null)
* @return self
* @link https://ss64.com/nt/wmic.html
*/
public static function loadWmicBlocking($command = null)
public static function loadWmicBlocking(?string $command = null): self
{
$contents = shell_exec($command === null ? 'wmic NICCONFIG get "DNSServerSearchOrder" /format:CSV' : $command);
preg_match_all('/(?<=[{;,"])([\da-f.:]{4,})(?=[};,"])/i', $contents, $matches);
Expand All @@ -133,5 +133,8 @@ public static function loadWmicBlocking($command = null)
return $config;
}

/**
* @var array<string>
*/
public $nameservers = [];
}
26 changes: 15 additions & 11 deletions src/Config/HostsFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ class HostsFile
/**
* Returns the default path for the hosts file on this system
*
* @return string
* @codeCoverageIgnore
*/
public static function getDefaultPath()
public static function getDefaultPath(): string
{
// use static path for all Unix-based systems
if (DIRECTORY_SEPARATOR !== '\\') {
Expand Down Expand Up @@ -59,7 +58,7 @@ public static function getDefaultPath()
* @return self
* @throws RuntimeException if the path can not be loaded (does not exist)
*/
public static function loadFromPathBlocking($path = null)
public static function loadFromPathBlocking(?string $path = null): self
{
if ($path === null) {
$path = self::getDefaultPath();
Expand All @@ -73,16 +72,23 @@ public static function loadFromPathBlocking($path = null)
return new self($contents);
}

/**
* @var string
*/
private $contents;

/**
* Instantiate new hosts file with the given hosts file contents
*
* @param string $contents
*/
public function __construct($contents)
public function __construct(string $contents)
{
// remove all comments from the contents
/**
* remove all comments from the contents
*
* @var string $contents
*/
$contents = preg_replace('/[ \t]*#.*/', '', strtolower($contents));

$this->contents = $contents;
Expand All @@ -92,9 +98,9 @@ public function __construct($contents)
* Returns all IPs for the given hostname
*
* @param string $name
* @return string[]
* @return iterable<string>
*/
public function getIpsForHost($name)
public function getIpsForHost(string $name): iterable
{
$name = strtolower($name);

Expand All @@ -113,17 +119,15 @@ public function getIpsForHost($name)
}
}
}

return $ips;
}

/**
* Returns all hostnames for the given IPv4 or IPv6 address
*
* @param string $ip
* @return string[]
* @return iterable<string>
*/
public function getHostsForIp($ip)
public function getHostsForIp(string $ip): iterable
{
// check binary representation of IP to avoid string case and short notation
$ip = @inet_pton($ip);
Expand Down
12 changes: 6 additions & 6 deletions src/Model/Record.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,18 @@ final class Record
* considered a BC break. See the format definition of known types above
* for more details.
*
* @var string|string[]|array
* @var string|array<string>
*/
public $data;

/**
* @param string $name
* @param int $type
* @param int $class
* @param int $ttl
* @param string|string[]|array $data
* @param int $type
* @param int $class
* @param int $ttl
* @param string|array<string> $data
*/
public function __construct($name, $type, $class, $ttl, $data)
public function __construct(string $name, int $type, int $class, int $ttl, $data)
{
$this->name = $name;
$this->type = $type;
Expand Down
5 changes: 3 additions & 2 deletions src/Query/CachingExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use React\Cache\CacheInterface;
use React\Dns\Model\Message;
use React\Promise\Promise;
use React\Promise\PromiseInterface;

final class CachingExecutor implements ExecutorInterface
{
Expand All @@ -24,7 +25,7 @@ public function __construct(ExecutorInterface $executor, CacheInterface $cache)
$this->cache = $cache;
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
$id = $query->name . ':' . $query->type . ':' . $query->class;

Expand Down Expand Up @@ -65,7 +66,7 @@ function (Message $message) use ($id) {
* @return int
* @internal
*/
public function ttl(Message $message)
public function ttl(Message $message): int
{
// select TTL from answers (should all be the same), use smallest value if available
// @link https://tools.ietf.org/html/rfc2181#section-5.2
Expand Down
3 changes: 2 additions & 1 deletion src/Query/CoopExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace React\Dns\Query;

use React\Promise\Promise;
use React\Promise\PromiseInterface;

/**
* Cooperatively resolves hosts via the given base executor to ensure same query is not run concurrently
Expand Down Expand Up @@ -45,7 +46,7 @@ public function __construct(ExecutorInterface $base)
$this->executor = $base;
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
$key = $this->serializeQueryToIdentity($query);
if (isset($this->pending[$key])) {
Expand Down
7 changes: 5 additions & 2 deletions src/Query/ExecutorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace React\Dns\Query;

use React\Dns\Model\Message;
use React\Promise\PromiseInterface;

interface ExecutorInterface
{
/**
Expand Down Expand Up @@ -36,8 +39,8 @@ interface ExecutorInterface
* ```
*
* @param Query $query
* @return \React\Promise\PromiseInterface<\React\Dns\Model\Message>
* @return PromiseInterface<Message>
* resolves with response message on success or rejects with an Exception on error
*/
public function query(Query $query);
public function query(Query $query): PromiseInterface;
}
3 changes: 2 additions & 1 deletion src/Query/FallbackExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace React\Dns\Query;

use React\Promise\Promise;
use React\Promise\PromiseInterface;

final class FallbackExecutor implements ExecutorInterface
{
Expand All @@ -15,7 +16,7 @@ public function __construct(ExecutorInterface $executor, ExecutorInterface $fall
$this->fallback = $fallback;
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
$cancelled = false;
$promise = $this->executor->query($query);
Expand Down
3 changes: 2 additions & 1 deletion src/Query/HostsFileExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use React\Dns\Config\HostsFile;
use React\Dns\Model\Message;
use React\Dns\Model\Record;
use React\Promise\PromiseInterface;
use function React\Promise\resolve;

/**
Expand All @@ -25,7 +26,7 @@ public function __construct(HostsFile $hosts, ExecutorInterface $fallback)
$this->fallback = $fallback;
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
if ($query->class === Message::CLASS_IN && ($query->type === Message::TYPE_A || $query->type === Message::TYPE_AAAA)) {
// forward lookup for type A or AAAA
Expand Down
2 changes: 1 addition & 1 deletion src/Query/RetryExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function __construct(ExecutorInterface $executor, $retries = 2)
$this->retries = $retries;
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
return $this->tryQuery($query, $this->retries);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Query/SelectiveTransportExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace React\Dns\Query;

use React\Promise\Promise;
use React\Promise\PromiseInterface;

/**
* Send DNS queries over a UDP or TCP/IP stream transport.
Expand Down Expand Up @@ -61,7 +62,7 @@ public function __construct(ExecutorInterface $datagramExecutor, ExecutorInterfa
$this->streamExecutor = $streamExecutor;
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
$pending = $this->datagramExecutor->query($query);

Expand Down
6 changes: 3 additions & 3 deletions src/Query/TcpTransportExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
use React\Dns\Protocol\Parser;
use React\EventLoop\Loop;
use React\EventLoop\LoopInterface;
use React\EventLoop\TimerInterface;
use React\Promise\Deferred;
use React\Promise\PromiseInterface;
use function React\Promise\reject;

/**
Expand Down Expand Up @@ -153,7 +155,7 @@ public function __construct($nameserver, LoopInterface $loop = null)
$this->dumper = new BinaryDumper();
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
$request = Message::createRequestForQuery($query);

Expand Down Expand Up @@ -328,8 +330,6 @@ public function handleRead()

/**
* @internal
* @param string $reason
* @param int $code
*/
public function closeError($reason, $code = 0)
{
Expand Down
8 changes: 6 additions & 2 deletions src/Query/TimeoutExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@
use React\EventLoop\Loop;
use React\EventLoop\LoopInterface;
use React\Promise\Promise;
use React\Promise\PromiseInterface;

final class TimeoutExecutor implements ExecutorInterface
{
private $executor;
private $loop;
private $timeout;

public function __construct(ExecutorInterface $executor, $timeout, LoopInterface $loop = null)
/**
* @param float|int $timeout
*/
public function __construct(ExecutorInterface $executor, $timeout, ?LoopInterface $loop = null)
{
$this->executor = $executor;
$this->loop = $loop ?: Loop::get();
$this->timeout = $timeout;
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
$promise = $this->executor->query($query);

Expand Down
5 changes: 3 additions & 2 deletions src/Query/UdpTransportExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use React\EventLoop\Loop;
use React\EventLoop\LoopInterface;
use React\Promise\Deferred;
use React\Promise\PromiseInterface;
use function React\Promise\reject;

/**
Expand Down Expand Up @@ -99,7 +100,7 @@ final class UdpTransportExecutor implements ExecutorInterface
* @param string $nameserver
* @param ?LoopInterface $loop
*/
public function __construct($nameserver, LoopInterface $loop = null)
public function __construct(string $nameserver, ?LoopInterface $loop = null)
{
if (\strpos($nameserver, '[') === false && \substr_count($nameserver, ':') >= 2 && \strpos($nameserver, '://') === false) {
// several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets
Expand All @@ -117,7 +118,7 @@ public function __construct($nameserver, LoopInterface $loop = null)
$this->dumper = new BinaryDumper();
}

public function query(Query $query)
public function query(Query $query): PromiseInterface
{
$request = Message::createRequestForQuery($query);

Expand Down
8 changes: 4 additions & 4 deletions src/Resolver/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ final class Factory
*
* @param Config|string $config DNS Config object (recommended) or single nameserver address
* @param ?LoopInterface $loop
* @return \React\Dns\Resolver\ResolverInterface
* @return ResolverInterface
* @throws \InvalidArgumentException for invalid DNS server address
* @throws \UnderflowException when given DNS Config object has an empty list of nameservers
*/
public function create($config, LoopInterface $loop = null)
public function create($config, LoopInterface $loop = null): ResolverInterface
{
$executor = $this->decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get()));

Expand All @@ -55,11 +55,11 @@ public function create($config, LoopInterface $loop = null)
* @param Config|string $config DNS Config object (recommended) or single nameserver address
* @param ?LoopInterface $loop
* @param ?CacheInterface $cache
* @return \React\Dns\Resolver\ResolverInterface
* @return ResolverInterface
* @throws \InvalidArgumentException for invalid DNS server address
* @throws \UnderflowException when given DNS Config object has an empty list of nameservers
*/
public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null)
public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null): ResolverInterface
{
// default to keeping maximum of 256 responses in cache unless explicitly given
if (!($cache instanceof CacheInterface)) {
Expand Down
5 changes: 3 additions & 2 deletions src/Resolver/Resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use React\Dns\Query\ExecutorInterface;
use React\Dns\Query\Query;
use React\Dns\RecordNotFoundException;
use React\Promise\PromiseInterface;

/**
* @see ResolverInterface for the base interface
Expand All @@ -19,14 +20,14 @@ public function __construct(ExecutorInterface $executor)
$this->executor = $executor;
}

public function resolve($domain)
public function resolve(string $domain): PromiseInterface
{
return $this->resolveAll($domain, Message::TYPE_A)->then(function (array $ips) {
return $ips[array_rand($ips)];
});
}

public function resolveAll($domain, $type)
public function resolveAll(string $domain, int $type): PromiseInterface
{
$query = new Query($domain, $type, Message::CLASS_IN);

Expand Down
Loading

0 comments on commit fb61ef0

Please sign in to comment.