diff --git a/composer.json b/composer.json index 7603398..5e2a479 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,7 @@ } ], "require": { - "php": ">=7.0", + "php": ">=8.1", "amphp/cache": "^v2-dev", "amphp/parser": "^1", "danog/libdns-json": "^0.1", diff --git a/lib/DoHConfig.php b/lib/DoHConfig.php index 793eb45..2f1f657 100644 --- a/lib/DoHConfig.php +++ b/lib/DoHConfig.php @@ -15,7 +15,7 @@ use Amp\Http\Client\HttpClientBuilder; final class DoHConfig { /** - * @var non-empty-array $nameservers + * @var non-empty-array $nameservers */ private readonly array $nameservers; private readonly DelegateHttpClient $httpClient; @@ -24,15 +24,17 @@ final class DoHConfig private readonly Cache $cache; /** - * @param non-empty-array $nameservers + * @param non-empty-array $nameservers */ public function __construct(array $nameservers, ?DelegateHttpClient $httpClient = null, ?Rfc1035StubResolver $resolver = null, ?ConfigLoader $configLoader = null, ?Cache $cache = null) { + /** @psalm-suppress TypeDoesNotContainType */ if (\count($nameservers) < 1) { throw new ConfigException("At least one nameserver is required for a valid config"); } foreach ($nameservers as $nameserver) { + /** @psalm-suppress DocblockContradiction */ if (!($nameserver instanceof Nameserver)) { throw new ConfigException("Invalid nameserver: {$nameserver}"); } diff --git a/lib/Nameserver.php b/lib/Nameserver.php index e118984..583fc11 100644 --- a/lib/Nameserver.php +++ b/lib/Nameserver.php @@ -6,6 +6,10 @@ use Amp\Dns\ConfigException; final class Nameserver { + public const RFC8484_GET = NameserverType::RFC8484_GET; + public const RFC8484_POST = NameserverType::RFC8484_POST; + public const GOOGLE_JSON = NameserverType::GOOGLE_JSON; + private readonly string $host; public function __construct( diff --git a/lib/Rfc8484StubResolver.php b/lib/Rfc8484StubResolver.php index bc7d6fa..3dba1de 100644 --- a/lib/Rfc8484StubResolver.php +++ b/lib/Rfc8484StubResolver.php @@ -18,10 +18,8 @@ use Amp\Future; use Amp\Http\Client\DelegateHttpClient; use Amp\Http\Client\Request; use Amp\NullCancellation; -use Amp\Promise; use danog\LibDNSJson\JsonDecoder; use danog\LibDNSJson\JsonDecoderFactory; -use danog\LibDNSJson\QueryEncoder; use danog\LibDNSJson\QueryEncoderFactory; use LibDNS\Decoder\Decoder; use LibDNS\Decoder\DecoderFactory; @@ -48,13 +46,13 @@ final class Rfc8484StubResolver implements Resolver private Cache $cache; - /** @var Promise[] */ + /** @var Future[] */ private array $pendingQueries = []; private Rfc1035StubResolver $subResolver; private Encoder $encoder; private Decoder $decoder; - private QueryEncoder $encoderJson; + private Encoder $encoderJson; private JsonDecoder $decoderJson; private MessageFactory $messageFactory; private DelegateHttpClient $httpClient; @@ -234,6 +232,7 @@ final class Rfc8484StubResolver implements Resolver private function queryHosts(string $name, int $typeRestriction = null): array { + \assert($this->config !== null); $hosts = $this->config->getKnownHosts(); $records = []; @@ -271,6 +270,8 @@ final class Rfc8484StubResolver implements Resolver } } + \assert($this->config !== null); + $name = $this->normalizeName($name, $type); $question = $this->createQuestion($name, $type); @@ -301,7 +302,6 @@ final class Rfc8484StubResolver implements Resolver $result = []; $ttls = []; - /** @var \LibDNS\Records\Resource $record */ foreach ($answers as $record) { $recordType = $record->getType(); $result[$recordType][] = (string) $record->getData(); @@ -351,6 +351,7 @@ final class Rfc8484StubResolver implements Resolver private function ask(Nameserver $nameserver, Question $question, Cancellation $cancellation): Message { $message = $this->createMessage($question, \random_int(0, 0xffff)); + $request = null; switch ($nameserver->getType()) { case NameserverType::RFC8484_GET: $data = $this->encoder->encode($message); @@ -364,7 +365,7 @@ final class Rfc8484StubResolver implements Resolver $request->setBody($data); $request->setHeader('content-type', 'application/dns-message'); $request->setHeader('accept', 'application/dns-message'); - $request->setHeader('content-length', \strlen($data)); + $request->setHeader('content-length', (string) \strlen($data)); $request->setHeaders($nameserver->getHeaders()); break; case NameserverType::GOOGLE_JSON: @@ -374,6 +375,7 @@ final class Rfc8484StubResolver implements Resolver $request->setHeaders($nameserver->getHeaders()); break; } + \assert($request !== null); $response = $this->httpClient->request($request, $cancellation); if ($response->getStatus() !== 200) { @@ -390,7 +392,7 @@ final class Rfc8484StubResolver implements Resolver } } - private function normalizeName(string $name, int $type) + private function normalizeName(string $name, int $type): string { if ($type === Record::PTR) { if (($packedIp = @\inet_pton($name)) !== false) { @@ -434,7 +436,10 @@ final class Rfc8484StubResolver implements Resolver return self::CACHE_PREFIX.$name."#".$type; } - private function decodeCachedResult(string $name, int $type, string $encoded) + /** + * @return list + */ + private function decodeCachedResult(string $name, int $type, string $encoded): array { $decoded = \json_decode($encoded, true); diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..d6746fa --- /dev/null +++ b/psalm.xml @@ -0,0 +1,15 @@ + + + + + + + + +