mirror of
https://github.com/danog/dns-over-https.git
synced 2024-12-02 09:17:50 +01:00
Add tests
This commit is contained in:
parent
f5cbb3a9f5
commit
e431e1014e
@ -17,7 +17,7 @@ $domains = \array_map(function ($line) {
|
|||||||
\array_shift($domains);
|
\array_shift($domains);
|
||||||
|
|
||||||
// Set default resolver to DNS-over-HTTPS resolver
|
// Set default resolver to DNS-over-HTTPS resolver
|
||||||
$DohConfig = new DoH\DoHConfig([new DoH\Nameserver('https://cloudflare-dns.com/dns-query')]);
|
$DohConfig = new DoH\DoHConfig([new DoH\Nameserver('https://mozilla.cloudflare-dns.com/dns-query')]);
|
||||||
Dns\resolver(new DoH\Rfc8484StubResolver($DohConfig));
|
Dns\resolver(new DoH\Rfc8484StubResolver($DohConfig));
|
||||||
|
|
||||||
Loop::run(function () use ($domains) {
|
Loop::run(function () use ($domains) {
|
||||||
|
@ -24,7 +24,7 @@ $customConfigLoader = new class implements Dns\ConfigLoader {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Set default resolver to DNS-over-https resolver
|
// Set default resolver to DNS-over-https resolver
|
||||||
$DohConfig = new DoH\DoHConfig([new DoH\Nameserver('https://cloudflare-dns.com/dns-query')], null, null, $customConfigLoader);
|
$DohConfig = new DoH\DoHConfig([new DoH\Nameserver('https://mozilla.cloudflare-dns.com/dns-query')], null, null, $customConfigLoader);
|
||||||
Dns\resolver(new DoH\Rfc8484StubResolver($DohConfig));
|
Dns\resolver(new DoH\Rfc8484StubResolver($DohConfig));
|
||||||
|
|
||||||
Loop::run(function () {
|
Loop::run(function () {
|
||||||
|
23
examples/domain-fronting.php
Normal file
23
examples/domain-fronting.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require __DIR__ . "/_bootstrap.php";
|
||||||
|
|
||||||
|
use Amp\Dns;
|
||||||
|
use Amp\DoH;
|
||||||
|
use Amp\Loop;
|
||||||
|
use Amp\DoH\Nameserver;
|
||||||
|
|
||||||
|
// Set default resolver to DNS-over-https resolver
|
||||||
|
$DohConfig = new DoH\DoHConfig([new DoH\Nameserver('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"])]);
|
||||||
|
Dns\resolver(new DoH\Rfc8484StubResolver($DohConfig));
|
||||||
|
|
||||||
|
Loop::run(function () {
|
||||||
|
$hostname = "amphp.org";
|
||||||
|
|
||||||
|
try {
|
||||||
|
pretty_print_records($hostname, yield Dns\resolve($hostname));
|
||||||
|
} catch (Dns\DnsException $e) {
|
||||||
|
pretty_print_error($hostname, $e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -7,7 +7,7 @@ use Amp\DoH;
|
|||||||
use Amp\Loop;
|
use Amp\Loop;
|
||||||
|
|
||||||
// Set default resolver to DNS-over-HTTPS resolver
|
// Set default resolver to DNS-over-HTTPS resolver
|
||||||
$DohConfig = new DoH\DoHConfig([new DoH\Nameserver('https://cloudflare-dns.com/dns-query')]);
|
$DohConfig = new DoH\DoHConfig([new DoH\Nameserver('https://mozilla.cloudflare-dns.com/dns-query')]);
|
||||||
Dns\resolver(new DoH\Rfc8484StubResolver($DohConfig));
|
Dns\resolver(new DoH\Rfc8484StubResolver($DohConfig));
|
||||||
|
|
||||||
Loop::run(function () {
|
Loop::run(function () {
|
||||||
|
@ -11,6 +11,7 @@ use Amp\Dns\Resolver;
|
|||||||
use Amp\Dns\UnixConfigLoader;
|
use Amp\Dns\UnixConfigLoader;
|
||||||
use Amp\Dns\WindowsConfigLoader;
|
use Amp\Dns\WindowsConfigLoader;
|
||||||
use Amp\Dns\Rfc1035StubResolver;
|
use Amp\Dns\Rfc1035StubResolver;
|
||||||
|
use Amp\Dns\ConfigException;
|
||||||
|
|
||||||
final class DoHConfig
|
final class DoHConfig
|
||||||
{
|
{
|
||||||
@ -29,10 +30,12 @@ final class DoHConfig
|
|||||||
foreach ($nameservers as $nameserver) {
|
foreach ($nameservers as $nameserver) {
|
||||||
$this->validateNameserver($nameserver);
|
$this->validateNameserver($nameserver);
|
||||||
}
|
}
|
||||||
|
if ($resolver instanceof Rfc8484StubResolver) {
|
||||||
|
throw new ConfigException("Can't use Rfc8484StubResolver as subresolver for Rfc8484StubResolver");
|
||||||
|
}
|
||||||
|
|
||||||
$this->nameservers = $nameservers;
|
$this->nameservers = $nameservers;
|
||||||
$this->artax = $artax ?? new DefaultClient();
|
$this->artax = $artax ?? new DefaultClient();
|
||||||
|
|
||||||
$this->cache = $cache ?? new ArrayCache(5000/* default gc interval */, 256/* size */);
|
$this->cache = $cache ?? new ArrayCache(5000/* default gc interval */, 256/* size */);
|
||||||
$this->configLoader = $configLoader ?? (\stripos(PHP_OS, "win") === 0
|
$this->configLoader = $configLoader ?? (\stripos(PHP_OS, "win") === 0
|
||||||
? new WindowsConfigLoader
|
? new WindowsConfigLoader
|
||||||
|
@ -62,7 +62,7 @@ final class HttpsSocket extends Socket
|
|||||||
switch ($this->nameserver->getType()) {
|
switch ($this->nameserver->getType()) {
|
||||||
case Nameserver::RFC8484_GET:
|
case Nameserver::RFC8484_GET:
|
||||||
$data = $this->encoder->encode($message);
|
$data = $this->encoder->encode($message);
|
||||||
$request = (new Request($this->nameserver->getUri().'?'.http_build_query(['dns' => base64_encode($data), 'ct' => 'application/dns-message']), "GET"))
|
$request = (new Request($this->nameserver->getUri().'?'.\http_build_query(['dns' => \base64_encode($data), 'ct' => 'application/dns-message']), "GET"))
|
||||||
->withHeader('accept', 'application/dns-message')
|
->withHeader('accept', 'application/dns-message')
|
||||||
->withHeaders($this->nameserver->getHeaders());
|
->withHeaders($this->nameserver->getHeaders());
|
||||||
break;
|
break;
|
||||||
|
@ -23,6 +23,7 @@ use LibDNS\Records\Types\Type;
|
|||||||
use LibDNS\Records\Types\TypeBuilder;
|
use LibDNS\Records\Types\TypeBuilder;
|
||||||
use LibDNS\Records\Types\Types;
|
use LibDNS\Records\Types\Types;
|
||||||
use LibDNS\Messages\MessageTypes;
|
use LibDNS\Messages\MessageTypes;
|
||||||
|
use Amp\Dns\DnsException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes JSON DNS strings to Message objects
|
* Decodes JSON DNS strings to Message objects
|
||||||
@ -314,7 +315,15 @@ class JsonDecoder
|
|||||||
*/
|
*/
|
||||||
public function decode(string $result, int $requestId): Message
|
public function decode(string $result, int $requestId): Message
|
||||||
{
|
{
|
||||||
$result = json_decode($result, true);
|
$result = \json_decode($result, true);
|
||||||
|
if ($result === false) {
|
||||||
|
$error = \json_last_error_msg();
|
||||||
|
throw new DnsException("Could not decode JSON DNS payload ($error)");
|
||||||
|
}
|
||||||
|
if (!isset($result['Status'], $result['TC'], $result['RD'], $result['RA'])) {
|
||||||
|
throw new DnsException('Wrong reply from server, missing required fields');
|
||||||
|
}
|
||||||
|
|
||||||
$message = $this->messageFactory->create();
|
$message = $this->messageFactory->create();
|
||||||
$decodingContext = $this->decodingContextFactory->create($this->packetFactory->create());
|
$decodingContext = $this->decodingContextFactory->create($this->packetFactory->create());
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace Amp\DoH;
|
namespace Amp\DoH;
|
||||||
|
|
||||||
|
use Amp\Uri\InvalidDnsNameException;
|
||||||
|
use Amp\Dns\ConfigException;
|
||||||
|
|
||||||
final class Nameserver
|
final class Nameserver
|
||||||
{
|
{
|
||||||
const RFC8484_GET = 0;
|
const RFC8484_GET = 0;
|
||||||
@ -15,6 +18,12 @@ final class Nameserver
|
|||||||
|
|
||||||
public function __construct(string $uri, int $type = self::RFC8484_POST, array $headers = [])
|
public function __construct(string $uri, int $type = self::RFC8484_POST, array $headers = [])
|
||||||
{
|
{
|
||||||
|
if (parse_url($uri, PHP_URL_SCHEME) !== 'https') {
|
||||||
|
throw new ConfigException('Did not provide a valid HTTPS url!');
|
||||||
|
}
|
||||||
|
if (!in_array($type, [self::RFC8484_GET, self::RFC8484_POST, self::GOOGLE_JSON], true)) {
|
||||||
|
throw new ConfigException('Invalid nameserver type provided!');
|
||||||
|
}
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
$this->headers = $headers;
|
$this->headers = $headers;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?php declare(strict_types=1);
|
<?php declare (strict_types = 1);
|
||||||
/**
|
/**
|
||||||
* Encodes Message objects to raw network data
|
* Encodes Message objects to raw network data
|
||||||
*
|
*
|
||||||
@ -13,7 +13,9 @@
|
|||||||
*/
|
*/
|
||||||
namespace Amp\DoH;
|
namespace Amp\DoH;
|
||||||
|
|
||||||
|
use Amp\Dns\DnsException;
|
||||||
use \LibDNS\Messages\Message;
|
use \LibDNS\Messages\Message;
|
||||||
|
use LibDNS\Messages\MessageTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes Message objects to raw network data
|
* Encodes Message objects to raw network data
|
||||||
@ -32,12 +34,22 @@ class QueryEncoder
|
|||||||
*/
|
*/
|
||||||
public function encode(Message $message): string
|
public function encode(Message $message): string
|
||||||
{
|
{
|
||||||
return http_build_query([
|
if ($message->getType() !== MessageTypes::QUERY) {
|
||||||
|
throw new DnsException('Invalid question: is not a question record');
|
||||||
|
}
|
||||||
|
$questions = $message->getQuestionRecords();
|
||||||
|
if ($questions->count() === 0) {
|
||||||
|
throw new DnsException('Invalid question: 0 question records provided');
|
||||||
|
}
|
||||||
|
$question = $questions->getRecordByIndex(0);
|
||||||
|
return \http_build_query(
|
||||||
|
[
|
||||||
'cd' => 0, // Do not disable result validation
|
'cd' => 0, // Do not disable result validation
|
||||||
'do' => 0, // Do not send me DNSSEC data
|
'do' => 0, // Do not send me DNSSEC data
|
||||||
'type' => $message->getQuestionRecords()->getRecordByIndex(0)->getType(), // Record type being requested
|
'type' => $question->getType(), // Record type being requested
|
||||||
'name' => implode('.', $message->getQuestionRecords()->getRecordByIndex(0)->getName()->getLabels()), // Record name being requested
|
'name' => implode('.', $question->getName()->getLabels()), // Record name being requested
|
||||||
'ct' => 'application/dns-json', // Content-type of request
|
'ct' => 'application/dns-json', // Content-type of request
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Amp\Dns\Test;
|
|
||||||
|
|
||||||
use Amp\PHPUnit\TestCase;
|
|
||||||
use LibDNS\Decoder\DecoderFactory;
|
|
||||||
use LibDNS\Messages\Message;
|
|
||||||
|
|
||||||
class DecodeTest extends TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Regression test for https://github.com/amphp/dns/issues/53 and other reported issues.
|
|
||||||
*/
|
|
||||||
public function testDecodesEmptyDomains()
|
|
||||||
{
|
|
||||||
$message = \hex2bin("37ed818000010005000d000005676d61696c03636f6d00000f0001c00c000f000100000dff0020000a04616c74310d676d61696c2d736d74702d696e016c06676f6f676c65c012c00c000f000100000dff0009001404616c7432c02ec00c000f000100000dff0009002804616c7434c02ec00c000f000100000dff0009001e04616c7433c02ec00c000f000100000dff00040005c02e0000020001000026b50014016c0c726f6f742d73657276657273036e6574000000020001000026b500040163c0a30000020001000026b500040164c0a30000020001000026b50004016ac0a30000020001000026b500040162c0a30000020001000026b500040161c0a30000020001000026b500040167c0a30000020001000026b50004016bc0a30000020001000026b500040165c0a30000020001000026b50004016dc0a30000020001000026b500040169c0a30000020001000026b500040166c0a30000020001000026b500040168c0a3");
|
|
||||||
|
|
||||||
$decoder = (new DecoderFactory)->create();
|
|
||||||
$response = $decoder->decode($message);
|
|
||||||
|
|
||||||
$this->assertInstanceOf(Message::class, $response);
|
|
||||||
}
|
|
||||||
}
|
|
164
test/DoHConfigTest.php
Normal file
164
test/DoHConfigTest.php
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Amp\DoH\Test;
|
||||||
|
|
||||||
|
use Amp\Dns\Config;
|
||||||
|
use Amp\Dns\ConfigException;
|
||||||
|
use Amp\DoH\DoHConfig;
|
||||||
|
use Amp\DoH\Nameserver;
|
||||||
|
use Amp\PHPUnit\TestCase;
|
||||||
|
use Amp\Artax\DefaultClient;
|
||||||
|
use Amp\Dns\Rfc1035StubResolver;
|
||||||
|
use Amp\DoH\Rfc8484StubResolver;
|
||||||
|
use Amp\Cache\ArrayCache;
|
||||||
|
use Amp\Dns\WindowsConfigLoader;
|
||||||
|
use Amp\Dns\UnixConfigLoader;
|
||||||
|
|
||||||
|
class DoHConfigTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string[] $nameservers Valid server array.
|
||||||
|
*
|
||||||
|
* @dataProvider provideValidServers
|
||||||
|
*/
|
||||||
|
public function testAcceptsValidServers(array $nameservers)
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf(DoHConfig::class, new DoHConfig($nameservers));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideValidServers()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[[new Nameserver('https://cloudflare-dns.com/dns-query')]],
|
||||||
|
[[new Nameserver('https://cloudflare-dns.com/dns-query', Nameserver::RFC8484_POST)]],
|
||||||
|
[[new Nameserver('https://cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET)]],
|
||||||
|
[[new Nameserver('https://cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON)]],
|
||||||
|
[[new Nameserver('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["host" => "dns.google.com"])]],
|
||||||
|
[[new Nameserver('https://cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON), new Nameserver('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["host" => "dns.google.com"])]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $nameservers Invalid server array.
|
||||||
|
*
|
||||||
|
* @dataProvider provideInvalidServers
|
||||||
|
*/
|
||||||
|
public function testRejectsInvalidServers(array $nameservers)
|
||||||
|
{
|
||||||
|
$this->expectException(ConfigException::class);
|
||||||
|
new DoHConfig($nameservers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideInvalidServers()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[[]],
|
||||||
|
[[42]],
|
||||||
|
[[null]],
|
||||||
|
[[true]],
|
||||||
|
[["foobar"]],
|
||||||
|
[["foobar.com"]],
|
||||||
|
[["127.1.1:53"]],
|
||||||
|
[["127.1.1"]],
|
||||||
|
[["127.1.1.1.1"]],
|
||||||
|
[["126.0.0.5", "foobar"]],
|
||||||
|
[["42"]],
|
||||||
|
[["::1"]],
|
||||||
|
[["::1:53"]],
|
||||||
|
[["[::1]:53"]],
|
||||||
|
[["[::1]:"]],
|
||||||
|
[["[::1]:76235"]],
|
||||||
|
[["[::1]:0"]],
|
||||||
|
[["[::1]:-1"]],
|
||||||
|
[["[::1:51"]],
|
||||||
|
[["[::1]:abc"]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Amp\Artax\Client $client Valid artax instance
|
||||||
|
*
|
||||||
|
* @dataProvider provideValidArtax
|
||||||
|
*/
|
||||||
|
public function testAcceptsValidArtax($client)
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf(DoHConfig::class, new DoHConfig([new Nameserver('https://cloudflare-dns.com/dns-query')], $client));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideValidArtax()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[new DefaultClient()]
|
||||||
|
[null]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param \Amp\Dns\Resolver $resolver Valid resolver instance
|
||||||
|
*
|
||||||
|
* @dataProvider provideValidResolver
|
||||||
|
*/
|
||||||
|
public function testAcceptsValidResolver($resolver)
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf(DoHConfig::class, new DoHConfig([new Nameserver('https://cloudflare-dns.com/dns-query')], null, $resolver));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideValidResolver()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[new Rfc1035StubResolver()]
|
||||||
|
[null]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param $resolver any invalid resolver instance
|
||||||
|
*
|
||||||
|
* @dataProvider provideInvalidResolver
|
||||||
|
*/
|
||||||
|
public function testRejectsInvalidResolver($resolver)
|
||||||
|
{
|
||||||
|
$this->expectException(ConfigException::class);
|
||||||
|
new DoHConfig([new Nameserver('https://cloudflare-dns.com/dns-query')], null, $resolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideInvalidResolver()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[new Rfc8484StubResolver(new DoHConfig([new Nameserver('https://mozilla.cloudflare-dns.com/dns-query')]))]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param $configLoader Valid ConfigLoader instance
|
||||||
|
*
|
||||||
|
* @dataProvider provideValidConfigLoader
|
||||||
|
*/
|
||||||
|
public function testAcceptsValidConfigLoader($configLoader)
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf(DoHConfig::class, new DoHConfig([new Nameserver('https://cloudflare-dns.com/dns-query')], null, null, $configLoader));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideValidConfigLoader()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[new WindowsConfigLoader()]
|
||||||
|
[new UnixConfigLoader()]
|
||||||
|
[null]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param \Amp\Cache\Cache Valid cache instance
|
||||||
|
*
|
||||||
|
* @dataProvider provideValidCache
|
||||||
|
*/
|
||||||
|
public function testAcceptsValidCache($cache)
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf(DoHConfig::class, new DoHConfig([new Nameserver('https://cloudflare-dns.com/dns-query')], null, null, null, $cache));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideValidCache()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[new ArrayCache(5000/* default gc interval */, 256/* size */)]
|
||||||
|
[null]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Amp\Dns\Test;
|
|
||||||
|
|
||||||
use Amp\Dns\HostLoader;
|
|
||||||
use Amp\Dns\Record;
|
|
||||||
use Amp\Loop;
|
|
||||||
use Amp\PHPUnit\TestCase;
|
|
||||||
|
|
||||||
class HostLoaderTest extends TestCase
|
|
||||||
{
|
|
||||||
public function testIgnoresCommentsAndParsesBasicEntry()
|
|
||||||
{
|
|
||||||
Loop::run(function () {
|
|
||||||
$loader = new HostLoader(__DIR__ . "/data/hosts");
|
|
||||||
$this->assertSame([
|
|
||||||
Record::A => [
|
|
||||||
"localhost" => "127.0.0.1",
|
|
||||||
],
|
|
||||||
], yield $loader->loadHosts());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testReturnsEmptyErrorOnFileNotFound()
|
|
||||||
{
|
|
||||||
Loop::run(function () {
|
|
||||||
$loader = new HostLoader(__DIR__ . "/data/hosts.not.found");
|
|
||||||
$this->assertSame([], yield $loader->loadHosts());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testIgnoresInvalidNames()
|
|
||||||
{
|
|
||||||
Loop::run(function () {
|
|
||||||
$loader = new HostLoader(__DIR__ . "/data/hosts.invalid.name");
|
|
||||||
$this->assertSame([
|
|
||||||
Record::A => [
|
|
||||||
"localhost" => "127.0.0.1",
|
|
||||||
],
|
|
||||||
], yield $loader->loadHosts());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
15
test/JsonDecoderFactoryTest.php
Normal file
15
test/JsonDecoderFactoryTest.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Amp\Dns\Test;
|
||||||
|
|
||||||
|
use Amp\PHPUnit\TestCase;
|
||||||
|
use Amp\DoH\JsonDecoderFactory;
|
||||||
|
use Amp\DoH\JsonDecoder;
|
||||||
|
|
||||||
|
class JsonDecoderFactoryTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testJsonDecoderFactoryWorks()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf(JsonDecoder::class, (new JsonDecoderFactory)->create());
|
||||||
|
}
|
||||||
|
}
|
201
test/JsonDecoderTest.php
Normal file
201
test/JsonDecoderTest.php
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Amp\Dns\Test;
|
||||||
|
|
||||||
|
use Amp\DoH\JsonDecoderFactory;
|
||||||
|
use Amp\PHPUnit\TestCase;
|
||||||
|
use LibDNS\Messages\Message;
|
||||||
|
use Amp\Dns\DnsException;
|
||||||
|
use LibDNS\Messages\MessageTypes;
|
||||||
|
|
||||||
|
class JsonDecoderTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Test decoding of valid JSON DNS payloads
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
* @param int $requestId
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @dataProvider provideValidJsonPayloads
|
||||||
|
*/
|
||||||
|
public function testDecodesValidJsonPayloads(string $message, int $requestId)
|
||||||
|
{
|
||||||
|
$decoder = (new JsonDecoderFactory)->create();
|
||||||
|
$response = $decoder->decode($message, $requestId);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Message::class, $response);
|
||||||
|
$this->assertEquals(MessageTypes::RESPONSE, $response->getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideValidJsonPayloads()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'{
|
||||||
|
"Status": 0,
|
||||||
|
"TC": false,
|
||||||
|
"RD": true,
|
||||||
|
"RA": true,
|
||||||
|
"AD": false,
|
||||||
|
"CD": false,
|
||||||
|
"Question":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Answer":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.178.96.59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.172.224.47"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.142.160.59"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Additional": [ ],
|
||||||
|
"edns_client_subnet": "12.34.56.78/0"
|
||||||
|
}',
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": true,"CD": false,"Question":[{"name": "example.com.", "type": 28}],"Answer":[{"name": "example.com.", "type": 28, "TTL": 7092, "data": "2606:2800:220:1:248:1893:25c8:1946"}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": false,"CD": false,"Question":[{"name": "daniil.it.", "type": 1}],"Answer":[{"name": "daniil.it.", "type": 1, "TTL": 300, "data": "104.27.146.166"},{"name": "daniil.it.", "type": 1, "TTL": 300, "data": "104.27.147.166"}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": false,"CD": false,"Question":[{"name": "amphp.org.", "type": 15}],"Answer":[{"name": "amphp.org.", "type": 15, "TTL": 86400, "data": "0 mail.negativeion.net."}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test decoding of invalid JSON DNS payloads
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
* @param int $requestId
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @dataProvider provideInvalidJsonPayloads
|
||||||
|
*/
|
||||||
|
public function testDecodesInvalidJsonPayloads($message, $requestId)
|
||||||
|
{
|
||||||
|
$decoder = (new JsonDecoderFactory)->create();
|
||||||
|
$this->expectException(DnsException::class);
|
||||||
|
$decoder->decode($message, $requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideInvalidJsonPayloads()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'{lmfao
|
||||||
|
"Status": 0,
|
||||||
|
"TC": false,
|
||||||
|
"RD": true,
|
||||||
|
"RA": true,
|
||||||
|
"AD": false,
|
||||||
|
"CD": false,
|
||||||
|
"Question":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Answer":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.178.96.59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.172.224.47"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.142.160.59"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Additional": [ ],
|
||||||
|
"edns_client_subnet": "12.34.56.78/0"
|
||||||
|
}',
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'xd{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": true,"CD": false,"Question":[{"name": "example.com.", "type": 28}],"Answer":[{"name": "example.com.", "type": 28, "TTL": 7092, "data": "2606:2800:220:1:248:1893:25c8:1946"}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'whaaa{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": false,"CD": false,"Question":[{"name": "daniil.it.", "type": 1}],"Answer":[{"name": "daniil.it.", "type": 1, "TTL": 300, "data": "104.27.146.166"},{"name": "daniil.it.", "type": 1, "TTL": 300, "data": "104.27.147.166"}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'xdxdxxxxx{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": false,"CD": false,"Question":[{"name": "amphp.org.", "type": 15}],"Answer":[{"name": "amphp.org.", "type": 15, "TTL": 86400, "data": "0 mail.negativeion.net."}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"TC": false,"RD": true, "RA": true, "AD": false,"CD": false,"Question":[{"name": "amphp.org.", "type": 15}],"Answer":[{"name": "amphp.org.", "type": 15, "TTL": 86400, "data": "0 mail.negativeion.net."}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"RD": true, "RA": true, "AD": false,"CD": false,"Question":[{"name": "amphp.org.", "type": 15}],"Answer":[{"name": "amphp.org.", "type": 15, "TTL": 86400, "data": "0 mail.negativeion.net."}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"TC": false,"RA": true, "AD": false,"CD": false,"Question":[{"name": "amphp.org.", "type": 15}],"Answer":[{"name": "amphp.org.", "type": 15, "TTL": 86400, "data": "0 mail.negativeion.net."}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"TC": false,"RD": true, "AD": false,"CD": false,"Question":[{"name": "amphp.org.", "type": 15}],"Answer":[{"name": "amphp.org.", "type": 15, "TTL": 86400, "data": "0 mail.negativeion.net."}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'xd',
|
||||||
|
0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[],
|
||||||
|
0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
new class {},
|
||||||
|
0
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
86
test/NameserverTest.php
Normal file
86
test/NameserverTest.php
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Amp\DoH\Test;
|
||||||
|
|
||||||
|
use Amp\PHPUnit\TestCase;
|
||||||
|
use Amp\DoH\Nameserver;
|
||||||
|
|
||||||
|
class NameserverTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string[] $nameservers Valid server array.
|
||||||
|
*
|
||||||
|
* @dataProvider provideValidServers
|
||||||
|
*/
|
||||||
|
public function testAcceptsValidServers($nameserver, $type = Nameserver::RFC8484_POST, $headers = [])
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf(Nameserver::class, new Nameserver($nameserver, $type, $headers));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideValidServers()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query'],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_POST],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON],
|
||||||
|
['https://google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $nameservers Invalid server array.
|
||||||
|
*
|
||||||
|
* @dataProvider provideInvalidServers
|
||||||
|
*/
|
||||||
|
public function testRejectsInvalidServers($nameserver, $type = Nameserver::RFC8484_POST, $headers = [])
|
||||||
|
{
|
||||||
|
$this->expectException(ConfigException::class);
|
||||||
|
new Nameserver($nameserver, $type, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideInvalidServers()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[''],
|
||||||
|
[42],
|
||||||
|
[null],
|
||||||
|
[true],
|
||||||
|
["foobar"],
|
||||||
|
["foobar.com"],
|
||||||
|
["127.1.1"],
|
||||||
|
["127.1.1.1.1"],
|
||||||
|
["126.0.0.5"],
|
||||||
|
["42"],
|
||||||
|
["::1"],
|
||||||
|
["::1:53"],
|
||||||
|
["[::1]:"],
|
||||||
|
["[::1]:76235"],
|
||||||
|
["[::1]:0"],
|
||||||
|
["[::1]:-1"],
|
||||||
|
["[::1:51"],
|
||||||
|
["[::1]:abc"],
|
||||||
|
['http://mozilla.cloudflare-dns.com/dns-query'],
|
||||||
|
['http://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_POST],
|
||||||
|
['http://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET],
|
||||||
|
['http://mozilla.cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON],
|
||||||
|
['http://google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"]],
|
||||||
|
|
||||||
|
['mozilla.cloudflare-dns.com/dns-query'],
|
||||||
|
['mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_POST],
|
||||||
|
['mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET],
|
||||||
|
['mozilla.cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON],
|
||||||
|
['google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"]],
|
||||||
|
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query'],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', 100],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', "2"],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', -1],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', null],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', "hi"],
|
||||||
|
['https://mozilla.cloudflare-dns.com/dns-query', "foobar"],
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
test/QueryEncoderFactoryTest.php
Normal file
15
test/QueryEncoderFactoryTest.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Amp\Dns\Test;
|
||||||
|
|
||||||
|
use Amp\PHPUnit\TestCase;
|
||||||
|
use Amp\DoH\QueryEncoderFactory;
|
||||||
|
use Amp\DoH\QueryEncoder;
|
||||||
|
|
||||||
|
class QueryEncoderFactoryTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testQueryEncoderFactoryWorks()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf(QueryEncoder::class, (new QueryEncoderFactory)->create());
|
||||||
|
}
|
||||||
|
}
|
208
test/QueryEncoderTest.php
Normal file
208
test/QueryEncoderTest.php
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Amp\Dns\Test;
|
||||||
|
|
||||||
|
use Amp\Dns\DnsException;
|
||||||
|
use Amp\DoH\JsonDecoderFactory;
|
||||||
|
use Amp\DoH\QueryEncoderFactory;
|
||||||
|
use Amp\PHPUnit\TestCase;
|
||||||
|
use LibDNS\Messages\Message;
|
||||||
|
use LibDNS\Messages\MessageTypes;
|
||||||
|
|
||||||
|
class QueryEncoderTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Test encoding of valid DNS message payloads
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @dataProvider provideValidQueryPayloads
|
||||||
|
*/
|
||||||
|
public function testEncodesValidQueryPayloads(string $message)
|
||||||
|
{
|
||||||
|
$decoder = (new JsonDecoderFactory)->create();
|
||||||
|
$response = $decoder->decode($message, 0);
|
||||||
|
$response->setType(MessageTypes::QUERY);
|
||||||
|
|
||||||
|
$encoder = (new QueryEncoderFactory)->create();
|
||||||
|
$request = $encoder->encode($response);
|
||||||
|
|
||||||
|
$this->assertInternalType('string', $request, "Got a ".gettype($request)." instead of a string");
|
||||||
|
parse_str($request, $output);
|
||||||
|
$this->assertNotEmpty($output);
|
||||||
|
$this->assertArrayHasKey('cd', $output);
|
||||||
|
$this->assertArrayHasKey('do', $output);
|
||||||
|
$this->assertArrayHasKey('ct', $output);
|
||||||
|
$this->assertArrayHasKey('type', $output);
|
||||||
|
$this->assertArrayHasKey('name', $output);
|
||||||
|
$this->assertEquals($output['cd'], 0);
|
||||||
|
$this->assertEquals($output['do'], 0);
|
||||||
|
$this->assertEquals($output['ct'], 'application/dns-json');
|
||||||
|
$this->assertEquals($output['type'], $response->getQuestionRecords()->getRecordByIndex(0)->getType());
|
||||||
|
$this->assertEquals($output['name'], implode('.', $message->getQuestionRecords()->getRecordByIndex(0)->getName()->getLabels()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideValidJsonPayloads()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'{
|
||||||
|
"Status": 0,
|
||||||
|
"TC": false,
|
||||||
|
"RD": true,
|
||||||
|
"RA": true,
|
||||||
|
"AD": false,
|
||||||
|
"CD": false,
|
||||||
|
"Question":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Answer":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.178.96.59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.172.224.47"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.142.160.59"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Additional": [ ],
|
||||||
|
"edns_client_subnet": "12.34.56.78/0"
|
||||||
|
}',
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": true,"CD": false,"Question":[{"name": "example.com.", "type": 28}],"Answer":[{"name": "example.com.", "type": 28, "TTL": 7092, "data": "2606:2800:220:1:248:1893:25c8:1946"}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": false,"CD": false,"Question":[{"name": "daniil.it.", "type": 1}],"Answer":[{"name": "daniil.it.", "type": 1, "TTL": 300, "data": "104.27.146.166"},{"name": "daniil.it.", "type": 1, "TTL": 300, "data": "104.27.147.166"}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": false,"CD": false,"Question":[{"name": "amphp.org.", "type": 15}],"Answer":[{"name": "amphp.org.", "type": 15, "TTL": 86400, "data": "0 mail.negativeion.net."}]}',
|
||||||
|
3,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test query encoding of invalid DNS payloads
|
||||||
|
*
|
||||||
|
* @param $request
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @dataProvider provideInvalidQueryPayloads
|
||||||
|
*/
|
||||||
|
public function testEncodesInvalidQueryPayloads($request)
|
||||||
|
{
|
||||||
|
$encoder = (new QueryEncoderFactory)->create();
|
||||||
|
$this->expectException(DnsException::class);
|
||||||
|
$encoder->encode($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideInvalidQueryPayloads()
|
||||||
|
{
|
||||||
|
$decoder = (new JsonDecoderFactory)->create();
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
$decoder->decode(
|
||||||
|
'{
|
||||||
|
"Status": 0,
|
||||||
|
"TC": false,
|
||||||
|
"RD": true,
|
||||||
|
"RA": true,
|
||||||
|
"AD": false,
|
||||||
|
"CD": false,
|
||||||
|
"Question":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Answer":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.178.96.59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.172.224.47"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.142.160.59"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Additional": [ ],
|
||||||
|
"edns_client_subnet": "12.34.56.78/0"
|
||||||
|
}',
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
$decoder->decode(
|
||||||
|
'{
|
||||||
|
"Status": 0,
|
||||||
|
"TC": false,
|
||||||
|
"RD": true,
|
||||||
|
"RA": true,
|
||||||
|
"AD": false,
|
||||||
|
"CD": false,
|
||||||
|
"Question":
|
||||||
|
[
|
||||||
|
],
|
||||||
|
"Answer":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.178.96.59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.172.224.47"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apple.com.",
|
||||||
|
"type": 1,
|
||||||
|
"TTL": 3599,
|
||||||
|
"data": "17.142.160.59"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Additional": [ ],
|
||||||
|
"edns_client_subnet": "12.34.56.78/0"
|
||||||
|
}',
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Amp\Dns\Test;
|
|
||||||
|
|
||||||
use Amp\Dns\Record;
|
|
||||||
use Amp\PHPUnit\TestCase;
|
|
||||||
|
|
||||||
class RecordTest extends TestCase
|
|
||||||
{
|
|
||||||
public function testGetName()
|
|
||||||
{
|
|
||||||
$this->assertSame("A", Record::getName(Record::A));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetNameOnInvalidRecordType()
|
|
||||||
{
|
|
||||||
$this->expectException(\Error::class);
|
|
||||||
$this->expectExceptionMessage("65536 does not correspond to a valid record type (must be between 0 and 65535).");
|
|
||||||
|
|
||||||
Record::getName(65536);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetNameOnUnknownRecordType()
|
|
||||||
{
|
|
||||||
$this->assertSame("unknown (1000)", Record::getName(1000));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Amp\Dns\Test;
|
|
||||||
|
|
||||||
use Amp\Dns\Config;
|
|
||||||
use Amp\Dns\ConfigException;
|
|
||||||
use Amp\Dns\UnixConfigLoader;
|
|
||||||
use Amp\PHPUnit\TestCase;
|
|
||||||
use function Amp\Promise\wait;
|
|
||||||
|
|
||||||
class UnixConfigLoaderTest extends TestCase
|
|
||||||
{
|
|
||||||
public function test()
|
|
||||||
{
|
|
||||||
$loader = new UnixConfigLoader(__DIR__ . "/data/resolv.conf");
|
|
||||||
|
|
||||||
/** @var Config $result */
|
|
||||||
$result = wait($loader->loadConfig());
|
|
||||||
|
|
||||||
$this->assertSame([
|
|
||||||
"127.0.0.1:53",
|
|
||||||
"[2001:4860:4860::8888]:53",
|
|
||||||
], $result->getNameservers());
|
|
||||||
|
|
||||||
$this->assertSame(5000, $result->getTimeout());
|
|
||||||
$this->assertSame(3, $result->getAttempts());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNoDefaultsOnConfNotFound()
|
|
||||||
{
|
|
||||||
$this->expectException(ConfigException::class);
|
|
||||||
wait((new UnixConfigLoader(__DIR__ . "/data/non-existent.conf"))->loadConfig());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user