mirror of
https://github.com/danog/dns-over-https.git
synced 2024-11-26 20:04:47 +01:00
Upgrade to http-client
This commit is contained in:
parent
dfe1445418
commit
0444e06dc2
@ -47,7 +47,7 @@
|
||||
"danog/libdns-json": "^0.1",
|
||||
"daverandom/libdns": "^2.0.1",
|
||||
"amphp/amp": "^2",
|
||||
"amphp/artax": "dev-master",
|
||||
"amphp/http-client": "4.0-rc10",
|
||||
"amphp/dns": "dev-master as v0.9.x-dev",
|
||||
"ext-filter": "*",
|
||||
"ext-json": "*"
|
||||
|
@ -8,7 +8,7 @@ use Amp\Loop;
|
||||
|
||||
print "Downloading top 500 domains..." . PHP_EOL;
|
||||
|
||||
$domains = \file_get_contents("https://moz.com/top-500/download?table=top500Domains");
|
||||
$domains = \file_get_contents("https://moz.com/top-500/download/?table=top500Domains");
|
||||
$domains = \array_map(function ($line) {
|
||||
return \trim(\explode(",", $line)[1], '"/');
|
||||
}, \array_filter(\explode("\n", $domains)));
|
||||
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/_bootstrap.php";
|
||||
|
||||
use Amp\Dns;
|
||||
use Amp\DoH;
|
||||
use Amp\DoH\Nameserver;
|
||||
use Amp\Loop;
|
||||
|
||||
// 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);
|
||||
}
|
||||
});
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace Amp\DoH;
|
||||
|
||||
use Amp\Artax\Client;
|
||||
use Amp\Artax\DefaultClient;
|
||||
use Amp\Cache\ArrayCache;
|
||||
use Amp\Cache\Cache;
|
||||
use Amp\Dns\ConfigException;
|
||||
@ -12,16 +10,18 @@ use Amp\Dns\Resolver;
|
||||
use Amp\Dns\Rfc1035StubResolver;
|
||||
use Amp\Dns\UnixConfigLoader;
|
||||
use Amp\Dns\WindowsConfigLoader;
|
||||
use Amp\Http\Client\DelegateHttpClient;
|
||||
use Amp\Http\Client\HttpClientBuilder;
|
||||
|
||||
final class DoHConfig
|
||||
{
|
||||
private $nameservers;
|
||||
private $artax;
|
||||
private $httpClient;
|
||||
private $subResolver;
|
||||
private $configLoader;
|
||||
private $cache;
|
||||
|
||||
public function __construct(array $nameservers, Client $artax = null, Resolver $resolver = null, ConfigLoader $configLoader = null, Cache $cache = null)
|
||||
public function __construct(array $nameservers, DelegateHttpClient $httpClient = null, Resolver $resolver = null, ConfigLoader $configLoader = null, Cache $cache = null)
|
||||
{
|
||||
if (\count($nameservers) < 1) {
|
||||
throw new ConfigException("At least one nameserver is required for a valid config");
|
||||
@ -32,7 +32,7 @@ final class DoHConfig
|
||||
}
|
||||
|
||||
$this->nameservers = $nameservers;
|
||||
$this->artax = $artax ?? new DefaultClient();
|
||||
$this->httpClient = $httpClient ?? HttpClientBuilder::buildDefault();
|
||||
$this->cache = $cache ?? new ArrayCache(5000/* default gc interval */, 256/* size */);
|
||||
$this->configLoader = $configLoader ?? (\stripos(PHP_OS, "win") === 0
|
||||
? new WindowsConfigLoader
|
||||
@ -61,9 +61,9 @@ final class DoHConfig
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getArtax(): Client
|
||||
public function getHttpClient(): DelegateHttpClient
|
||||
{
|
||||
return $this->artax;
|
||||
return $this->httpClient;
|
||||
}
|
||||
|
||||
public function getCache(): Cache
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
namespace Amp\DoH\Internal;
|
||||
|
||||
use Amp\Artax\Client;
|
||||
use Amp\Artax\Request;
|
||||
use Amp\DoH\DoHException;
|
||||
use Amp\DoH\Nameserver;
|
||||
use Amp\Http\Client\DelegateHttpClient;
|
||||
use Amp\Http\Client\Request;
|
||||
use Amp\Promise;
|
||||
use danog\LibDNSJson\JsonDecoderFactory;
|
||||
use danog\LibDNSJson\QueryEncoderFactory;
|
||||
@ -17,7 +17,7 @@ use function Amp\call;
|
||||
/** @internal */
|
||||
final class HttpsSocket extends Socket
|
||||
{
|
||||
/** @var \Amp\Artax\Client */
|
||||
/** @var \Amp\Http\HttpClient */
|
||||
private $httpClient;
|
||||
|
||||
/** @var \Amp\DoH\Nameserver */
|
||||
@ -32,14 +32,14 @@ final class HttpsSocket extends Socket
|
||||
/** @var \Amp\Deferred */
|
||||
private $responseDeferred;
|
||||
|
||||
public static function connect(Client $artax, Nameserver $nameserver): Socket
|
||||
public static function connect(DelegateHttpClient $httpClient, Nameserver $nameserver): Socket
|
||||
{
|
||||
return new self($artax, $nameserver);
|
||||
return new self($httpClient, $nameserver);
|
||||
}
|
||||
|
||||
protected function __construct(Client $artax, Nameserver $nameserver)
|
||||
protected function __construct(DelegateHttpClient $httpClient, Nameserver $nameserver)
|
||||
{
|
||||
$this->httpClient = $artax;
|
||||
$this->httpClient = $httpClient;
|
||||
$this->nameserver = $nameserver;
|
||||
|
||||
if ($nameserver->getType() !== Nameserver::GOOGLE_JSON) {
|
||||
@ -60,23 +60,24 @@ final class HttpsSocket extends Socket
|
||||
switch ($this->nameserver->getType()) {
|
||||
case Nameserver::RFC8484_GET:
|
||||
$data = $this->encoder->encode($message);
|
||||
$request = (new Request($this->nameserver->getUri().'?'.\http_build_query(['dns' => \base64_encode($data), 'ct' => 'application/dns-message']), "GET"))
|
||||
->withHeader('accept', 'application/dns-message')
|
||||
->withHeaders($this->nameserver->getHeaders());
|
||||
$request = new Request($this->nameserver->getUri().'?'.\http_build_query(['dns' => \base64_encode($data), 'ct' => 'application/dns-message']), "GET");
|
||||
$request->setHeader('accept', 'application/dns-message');
|
||||
$request->setHeaders($this->nameserver->getHeaders());
|
||||
break;
|
||||
case Nameserver::RFC8484_POST:
|
||||
$data = $this->encoder->encode($message);
|
||||
$request = (new Request($this->nameserver->getUri(), "POST"))
|
||||
->withBody($data)
|
||||
->withHeader('content-type', 'application/dns-message')
|
||||
->withHeader('accept', 'application/dns-message')
|
||||
->withHeaders($this->nameserver->getHeaders());
|
||||
$request = new Request($this->nameserver->getUri(), "POST");
|
||||
$request->setBody($data);
|
||||
$request->setHeader('content-type', 'application/dns-message');
|
||||
$request->setHeader('accept', 'application/dns-message');
|
||||
$request->setHeader('content-length', strlen($data));
|
||||
$request->setHeaders($this->nameserver->getHeaders());
|
||||
break;
|
||||
case Nameserver::GOOGLE_JSON:
|
||||
$data = $this->encoder->encode($message);
|
||||
$request = (new Request($this->nameserver->getUri().'?'.$data, "GET"))
|
||||
->withHeader('accept', 'application/dns-json')
|
||||
->withHeaders($this->nameserver->getHeaders());
|
||||
$request = new Request($this->nameserver->getUri().'?'.$data, "GET");
|
||||
$request->setHeader('accept', 'application/dns-json');
|
||||
$request->setHeaders($this->nameserver->getHeaders());
|
||||
break;
|
||||
}
|
||||
$response = $this->httpClient->request($request);
|
||||
@ -85,8 +86,7 @@ final class HttpsSocket extends Socket
|
||||
if ($response->getStatus() !== 200) {
|
||||
throw new DoHException("HTTP result !== 200: ".$response->getStatus()." ".$response->getReason(), $response->getStatus());
|
||||
}
|
||||
$response = yield $response->getBody();
|
||||
|
||||
$response = yield $response->getBody()->buffer();
|
||||
|
||||
switch ($this->nameserver->getType()) {
|
||||
case Nameserver::RFC8484_GET:
|
||||
|
@ -3,14 +3,13 @@
|
||||
namespace Amp\DoH\Internal;
|
||||
|
||||
use Amp;
|
||||
use Amp\Artax\Client;
|
||||
use Amp\Artax\Response;
|
||||
use Amp\ByteStream\StreamException;
|
||||
use Amp\Deferred;
|
||||
use Amp\Dns\DnsException;
|
||||
use Amp\Dns\TimeoutException;
|
||||
use Amp\DoH\DoHException;
|
||||
use Amp\DoH\Nameserver;
|
||||
use Amp\Http\Client\DelegateHttpClient;
|
||||
use Amp\Promise;
|
||||
use LibDNS\Messages\Message;
|
||||
use LibDNS\Messages\MessageFactory;
|
||||
@ -41,7 +40,7 @@ abstract class Socket
|
||||
* @return Promise<self>
|
||||
*/
|
||||
|
||||
abstract public static function connect(Client $artax, Nameserver $nameserver): self;
|
||||
abstract public static function connect(DelegateHttpClient $httpClient, Nameserver $nameserver): self;
|
||||
|
||||
/**
|
||||
* @param Message $message
|
||||
|
@ -147,7 +147,15 @@ final class Rfc8484StubResolver implements Resolver
|
||||
if ($reason instanceof NoRecordException) {
|
||||
throw $reason;
|
||||
}
|
||||
$errors[] = $reason->getMessage();
|
||||
$error = $reason->getMessage();
|
||||
if ($reason instanceof MultiReasonException) {
|
||||
$reasons = [];
|
||||
foreach ($reason->getReasons() as $reason) {
|
||||
$reasons []= $reason->getMessage();
|
||||
}
|
||||
$error .= " (".implode(", ", $reasons).")";
|
||||
}
|
||||
$errors[] = $error;
|
||||
}
|
||||
|
||||
throw new DnsException("All query attempts failed for {$name}: ".\implode(", ", $errors), 0, $e);
|
||||
@ -254,6 +262,8 @@ final class Rfc8484StubResolver implements Resolver
|
||||
|
||||
$attemptDescription = [];
|
||||
|
||||
$exceptions = [];
|
||||
|
||||
while ($attempt < $attempts) {
|
||||
try {
|
||||
$attemptDescription[] = $nameserver;
|
||||
@ -263,6 +273,7 @@ final class Rfc8484StubResolver implements Resolver
|
||||
$response = yield $socket->ask($question, $this->config->getTimeout());
|
||||
} catch (DoHException $e) {
|
||||
// Defer call, because it might interfere with the unreference() call in Internal\Socket otherwise
|
||||
$exceptions []= $e;
|
||||
|
||||
$i = ++$attempt % \count($nameservers);
|
||||
$nameserver = $nameservers[$i];
|
||||
@ -319,13 +330,17 @@ final class Rfc8484StubResolver implements Resolver
|
||||
}
|
||||
}
|
||||
|
||||
throw new TimeoutException(\sprintf(
|
||||
$timeout = new TimeoutException(\sprintf(
|
||||
"No response for '%s' (%s) from any nameserver after %d attempts, tried %s",
|
||||
$name,
|
||||
Record::getName($type),
|
||||
$attempts,
|
||||
\implode(", ", $attemptDescription)
|
||||
));
|
||||
if (!$exceptions) {
|
||||
throw $timeout;
|
||||
}
|
||||
throw new MultiReasonException($exceptions, $timeout->getMessage());
|
||||
});
|
||||
|
||||
$this->pendingQueries[$type." ".$name] = $promise;
|
||||
@ -401,7 +416,7 @@ final class Rfc8484StubResolver implements Resolver
|
||||
return $this->sockets[$uri];
|
||||
}
|
||||
|
||||
$this->sockets[$uri] = HttpsSocket::connect($this->dohConfig->getArtax(), $nameserver);
|
||||
$this->sockets[$uri] = HttpsSocket::connect($this->dohConfig->getHttpClient(), $nameserver);
|
||||
|
||||
return $this->sockets[$uri];
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace Amp\DoH\Test;
|
||||
|
||||
use Amp\Artax\DefaultClient;
|
||||
use Amp\Cache\ArrayCache;
|
||||
use Amp\Dns\ConfigException;
|
||||
use Amp\Dns\Rfc1035StubResolver;
|
||||
@ -10,6 +9,7 @@ use Amp\Dns\UnixConfigLoader;
|
||||
use Amp\Dns\WindowsConfigLoader;
|
||||
use Amp\DoH\DoHConfig;
|
||||
use Amp\DoH\Nameserver;
|
||||
use Amp\Http\Client\HttpClientBuilder;
|
||||
use Amp\PHPUnit\TestCase;
|
||||
|
||||
class DoHConfigTest extends TestCase
|
||||
@ -31,8 +31,8 @@ class DoHConfigTest extends TestCase
|
||||
[[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"])]],
|
||||
[[new Nameserver('https://dns.google/resolve', Nameserver::GOOGLE_JSON)]],
|
||||
[[new Nameserver('https://cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON), new Nameserver('dns.google/resolve', Nameserver::GOOGLE_JSON)]],
|
||||
];
|
||||
}
|
||||
|
||||
@ -74,19 +74,19 @@ class DoHConfigTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Amp\Artax\Client $client Valid artax instance
|
||||
* @param \Amp\Http\Client\DelegateHttpClient $client Valid HttpClient instance
|
||||
*
|
||||
* @dataProvider provideValidArtax
|
||||
* @dataProvider provideValidHttpClient
|
||||
*/
|
||||
public function testAcceptsValidArtax($client)
|
||||
public function testAcceptsValidHttpClient($client)
|
||||
{
|
||||
$this->assertInstanceOf(DoHConfig::class, new DoHConfig([new Nameserver('https://cloudflare-dns.com/dns-query')], $client));
|
||||
}
|
||||
|
||||
public function provideValidArtax()
|
||||
public function provideValidHttpClient()
|
||||
{
|
||||
return [
|
||||
[new DefaultClient()],
|
||||
[HttpClientBuilder::buildDefault()],
|
||||
];
|
||||
}
|
||||
/**
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
namespace Amp\DoH\Test;
|
||||
|
||||
use Amp\Artax\DefaultClient;
|
||||
use Amp\Dns;
|
||||
use Amp\DoH;
|
||||
use Amp\DoH\Internal\Socket;
|
||||
use Amp\DoH\Nameserver;
|
||||
use Amp\Http\Client\HttpClientBuilder;
|
||||
use LibDNS\Records\QuestionFactory;
|
||||
use function Amp\Promise\wait;
|
||||
|
||||
@ -14,7 +14,7 @@ class HttpsSocketTest extends SocketTest
|
||||
{
|
||||
protected function connect(Nameserver $nameserver): Socket
|
||||
{
|
||||
return DoH\Internal\HttpsSocket::connect(new DefaultClient(), $nameserver);
|
||||
return DoH\Internal\HttpsSocket::connect(HttpClientBuilder::buildDefault(), $nameserver);
|
||||
}
|
||||
|
||||
public function testTimeout()
|
||||
|
@ -133,7 +133,7 @@ class IntegrationTest extends TestCase
|
||||
|
||||
/** @var Record $record */
|
||||
$record = $result[0];
|
||||
$this->assertSame("google-public-dns-b.google.com", $record->getValue());
|
||||
$this->assertSame("dns.google", $record->getValue());
|
||||
$this->assertNotNull($record->getTtl());
|
||||
$this->assertSame(Record::PTR, $record->getType());
|
||||
});
|
||||
@ -194,7 +194,7 @@ class IntegrationTest extends TestCase
|
||||
['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"]],
|
||||
['https://dns.google/resolve', Nameserver::GOOGLE_JSON],
|
||||
];
|
||||
$result = [];
|
||||
for ($start = 0; $start < \count($nameservers); $start++) {
|
||||
|
@ -25,7 +25,7 @@ class NameserverTest extends TestCase
|
||||
['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"]],
|
||||
['https://dns.google/resolve', Nameserver::GOOGLE_JSON],
|
||||
];
|
||||
}
|
||||
|
||||
@ -62,13 +62,13 @@ class NameserverTest extends TestCase
|
||||
['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"]],
|
||||
['http://dns.google/resolve', Nameserver::GOOGLE_JSON],
|
||||
|
||||
['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"]],
|
||||
['dns.google/resolve', Nameserver::GOOGLE_JSON],
|
||||
|
||||
['https://mozilla.cloudflare-dns.com/dns-query', 100],
|
||||
['https://mozilla.cloudflare-dns.com/dns-query', -1],
|
||||
|
Loading…
Reference in New Issue
Block a user