Upgrade to http-client

This commit is contained in:
Daniil Gentili 2019-12-12 22:27:22 +01:00
parent dfe1445418
commit 0444e06dc2
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
11 changed files with 65 additions and 73 deletions

View File

@ -47,7 +47,7 @@
"danog/libdns-json": "^0.1", "danog/libdns-json": "^0.1",
"daverandom/libdns": "^2.0.1", "daverandom/libdns": "^2.0.1",
"amphp/amp": "^2", "amphp/amp": "^2",
"amphp/artax": "dev-master", "amphp/http-client": "4.0-rc10",
"amphp/dns": "dev-master as v0.9.x-dev", "amphp/dns": "dev-master as v0.9.x-dev",
"ext-filter": "*", "ext-filter": "*",
"ext-json": "*" "ext-json": "*"

View File

@ -8,7 +8,7 @@ use Amp\Loop;
print "Downloading top 500 domains..." . PHP_EOL; 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) { $domains = \array_map(function ($line) {
return \trim(\explode(",", $line)[1], '"/'); return \trim(\explode(",", $line)[1], '"/');
}, \array_filter(\explode("\n", $domains))); }, \array_filter(\explode("\n", $domains)));

View File

@ -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);
}
});

View File

@ -2,8 +2,6 @@
namespace Amp\DoH; namespace Amp\DoH;
use Amp\Artax\Client;
use Amp\Artax\DefaultClient;
use Amp\Cache\ArrayCache; use Amp\Cache\ArrayCache;
use Amp\Cache\Cache; use Amp\Cache\Cache;
use Amp\Dns\ConfigException; use Amp\Dns\ConfigException;
@ -12,16 +10,18 @@ use Amp\Dns\Resolver;
use Amp\Dns\Rfc1035StubResolver; use Amp\Dns\Rfc1035StubResolver;
use Amp\Dns\UnixConfigLoader; use Amp\Dns\UnixConfigLoader;
use Amp\Dns\WindowsConfigLoader; use Amp\Dns\WindowsConfigLoader;
use Amp\Http\Client\DelegateHttpClient;
use Amp\Http\Client\HttpClientBuilder;
final class DoHConfig final class DoHConfig
{ {
private $nameservers; private $nameservers;
private $artax; private $httpClient;
private $subResolver; private $subResolver;
private $configLoader; private $configLoader;
private $cache; 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) { if (\count($nameservers) < 1) {
throw new ConfigException("At least one nameserver is required for a valid config"); throw new ConfigException("At least one nameserver is required for a valid config");
@ -32,7 +32,7 @@ final class DoHConfig
} }
$this->nameservers = $nameservers; $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->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
@ -61,9 +61,9 @@ final class DoHConfig
return false; return false;
} }
public function getArtax(): Client public function getHttpClient(): DelegateHttpClient
{ {
return $this->artax; return $this->httpClient;
} }
public function getCache(): Cache public function getCache(): Cache

View File

@ -2,10 +2,10 @@
namespace Amp\DoH\Internal; namespace Amp\DoH\Internal;
use Amp\Artax\Client;
use Amp\Artax\Request;
use Amp\DoH\DoHException; use Amp\DoH\DoHException;
use Amp\DoH\Nameserver; use Amp\DoH\Nameserver;
use Amp\Http\Client\DelegateHttpClient;
use Amp\Http\Client\Request;
use Amp\Promise; use Amp\Promise;
use danog\LibDNSJson\JsonDecoderFactory; use danog\LibDNSJson\JsonDecoderFactory;
use danog\LibDNSJson\QueryEncoderFactory; use danog\LibDNSJson\QueryEncoderFactory;
@ -17,7 +17,7 @@ use function Amp\call;
/** @internal */ /** @internal */
final class HttpsSocket extends Socket final class HttpsSocket extends Socket
{ {
/** @var \Amp\Artax\Client */ /** @var \Amp\Http\HttpClient */
private $httpClient; private $httpClient;
/** @var \Amp\DoH\Nameserver */ /** @var \Amp\DoH\Nameserver */
@ -32,14 +32,14 @@ final class HttpsSocket extends Socket
/** @var \Amp\Deferred */ /** @var \Amp\Deferred */
private $responseDeferred; 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; $this->nameserver = $nameserver;
if ($nameserver->getType() !== Nameserver::GOOGLE_JSON) { if ($nameserver->getType() !== Nameserver::GOOGLE_JSON) {
@ -60,23 +60,24 @@ 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') $request->setHeader('accept', 'application/dns-message');
->withHeaders($this->nameserver->getHeaders()); $request->setHeaders($this->nameserver->getHeaders());
break; break;
case Nameserver::RFC8484_POST: case Nameserver::RFC8484_POST:
$data = $this->encoder->encode($message); $data = $this->encoder->encode($message);
$request = (new Request($this->nameserver->getUri(), "POST")) $request = new Request($this->nameserver->getUri(), "POST");
->withBody($data) $request->setBody($data);
->withHeader('content-type', 'application/dns-message') $request->setHeader('content-type', 'application/dns-message');
->withHeader('accept', 'application/dns-message') $request->setHeader('accept', 'application/dns-message');
->withHeaders($this->nameserver->getHeaders()); $request->setHeader('content-length', strlen($data));
$request->setHeaders($this->nameserver->getHeaders());
break; break;
case Nameserver::GOOGLE_JSON: case Nameserver::GOOGLE_JSON:
$data = $this->encoder->encode($message); $data = $this->encoder->encode($message);
$request = (new Request($this->nameserver->getUri().'?'.$data, "GET")) $request = new Request($this->nameserver->getUri().'?'.$data, "GET");
->withHeader('accept', 'application/dns-json') $request->setHeader('accept', 'application/dns-json');
->withHeaders($this->nameserver->getHeaders()); $request->setHeaders($this->nameserver->getHeaders());
break; break;
} }
$response = $this->httpClient->request($request); $response = $this->httpClient->request($request);
@ -85,8 +86,7 @@ final class HttpsSocket extends Socket
if ($response->getStatus() !== 200) { if ($response->getStatus() !== 200) {
throw new DoHException("HTTP result !== 200: ".$response->getStatus()." ".$response->getReason(), $response->getStatus()); 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()) { switch ($this->nameserver->getType()) {
case Nameserver::RFC8484_GET: case Nameserver::RFC8484_GET:

View File

@ -3,14 +3,13 @@
namespace Amp\DoH\Internal; namespace Amp\DoH\Internal;
use Amp; use Amp;
use Amp\Artax\Client;
use Amp\Artax\Response;
use Amp\ByteStream\StreamException; use Amp\ByteStream\StreamException;
use Amp\Deferred; use Amp\Deferred;
use Amp\Dns\DnsException; use Amp\Dns\DnsException;
use Amp\Dns\TimeoutException; use Amp\Dns\TimeoutException;
use Amp\DoH\DoHException; use Amp\DoH\DoHException;
use Amp\DoH\Nameserver; use Amp\DoH\Nameserver;
use Amp\Http\Client\DelegateHttpClient;
use Amp\Promise; use Amp\Promise;
use LibDNS\Messages\Message; use LibDNS\Messages\Message;
use LibDNS\Messages\MessageFactory; use LibDNS\Messages\MessageFactory;
@ -41,7 +40,7 @@ abstract class Socket
* @return Promise<self> * @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 * @param Message $message

View File

@ -147,7 +147,15 @@ final class Rfc8484StubResolver implements Resolver
if ($reason instanceof NoRecordException) { if ($reason instanceof NoRecordException) {
throw $reason; 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); throw new DnsException("All query attempts failed for {$name}: ".\implode(", ", $errors), 0, $e);
@ -254,6 +262,8 @@ final class Rfc8484StubResolver implements Resolver
$attemptDescription = []; $attemptDescription = [];
$exceptions = [];
while ($attempt < $attempts) { while ($attempt < $attempts) {
try { try {
$attemptDescription[] = $nameserver; $attemptDescription[] = $nameserver;
@ -263,6 +273,7 @@ final class Rfc8484StubResolver implements Resolver
$response = yield $socket->ask($question, $this->config->getTimeout()); $response = yield $socket->ask($question, $this->config->getTimeout());
} catch (DoHException $e) { } catch (DoHException $e) {
// Defer call, because it might interfere with the unreference() call in Internal\Socket otherwise // Defer call, because it might interfere with the unreference() call in Internal\Socket otherwise
$exceptions []= $e;
$i = ++$attempt % \count($nameservers); $i = ++$attempt % \count($nameservers);
$nameserver = $nameservers[$i]; $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", "No response for '%s' (%s) from any nameserver after %d attempts, tried %s",
$name, $name,
Record::getName($type), Record::getName($type),
$attempts, $attempts,
\implode(", ", $attemptDescription) \implode(", ", $attemptDescription)
)); ));
if (!$exceptions) {
throw $timeout;
}
throw new MultiReasonException($exceptions, $timeout->getMessage());
}); });
$this->pendingQueries[$type." ".$name] = $promise; $this->pendingQueries[$type." ".$name] = $promise;
@ -401,7 +416,7 @@ final class Rfc8484StubResolver implements Resolver
return $this->sockets[$uri]; 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]; return $this->sockets[$uri];
} }

View File

@ -2,7 +2,6 @@
namespace Amp\DoH\Test; namespace Amp\DoH\Test;
use Amp\Artax\DefaultClient;
use Amp\Cache\ArrayCache; use Amp\Cache\ArrayCache;
use Amp\Dns\ConfigException; use Amp\Dns\ConfigException;
use Amp\Dns\Rfc1035StubResolver; use Amp\Dns\Rfc1035StubResolver;
@ -10,6 +9,7 @@ use Amp\Dns\UnixConfigLoader;
use Amp\Dns\WindowsConfigLoader; use Amp\Dns\WindowsConfigLoader;
use Amp\DoH\DoHConfig; use Amp\DoH\DoHConfig;
use Amp\DoH\Nameserver; use Amp\DoH\Nameserver;
use Amp\Http\Client\HttpClientBuilder;
use Amp\PHPUnit\TestCase; use Amp\PHPUnit\TestCase;
class DoHConfigTest extends 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_POST)]],
[[new Nameserver('https://cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET)]], [[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://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('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["host" => "dns.google.com"])]], [[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)); $this->assertInstanceOf(DoHConfig::class, new DoHConfig([new Nameserver('https://cloudflare-dns.com/dns-query')], $client));
} }
public function provideValidArtax() public function provideValidHttpClient()
{ {
return [ return [
[new DefaultClient()], [HttpClientBuilder::buildDefault()],
]; ];
} }
/** /**

View File

@ -2,11 +2,11 @@
namespace Amp\DoH\Test; namespace Amp\DoH\Test;
use Amp\Artax\DefaultClient;
use Amp\Dns; use Amp\Dns;
use Amp\DoH; use Amp\DoH;
use Amp\DoH\Internal\Socket; use Amp\DoH\Internal\Socket;
use Amp\DoH\Nameserver; use Amp\DoH\Nameserver;
use Amp\Http\Client\HttpClientBuilder;
use LibDNS\Records\QuestionFactory; use LibDNS\Records\QuestionFactory;
use function Amp\Promise\wait; use function Amp\Promise\wait;
@ -14,7 +14,7 @@ class HttpsSocketTest extends SocketTest
{ {
protected function connect(Nameserver $nameserver): Socket 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() public function testTimeout()

View File

@ -133,7 +133,7 @@ class IntegrationTest extends TestCase
/** @var Record $record */ /** @var Record $record */
$record = $result[0]; $record = $result[0];
$this->assertSame("google-public-dns-b.google.com", $record->getValue()); $this->assertSame("dns.google", $record->getValue());
$this->assertNotNull($record->getTtl()); $this->assertNotNull($record->getTtl());
$this->assertSame(Record::PTR, $record->getType()); $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_POST],
['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET], ['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET],
['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON], ['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 = []; $result = [];
for ($start = 0; $start < \count($nameservers); $start++) { for ($start = 0; $start < \count($nameservers); $start++) {

View File

@ -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_POST],
['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET], ['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET],
['https://mozilla.cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON], ['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_POST],
['http://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET], ['http://mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_GET],
['http://mozilla.cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON], ['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'],
['mozilla.cloudflare-dns.com/dns-query', Nameserver::RFC8484_POST], ['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::RFC8484_GET],
['mozilla.cloudflare-dns.com/dns-query', Nameserver::GOOGLE_JSON], ['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', 100],
['https://mozilla.cloudflare-dns.com/dns-query', -1], ['https://mozilla.cloudflare-dns.com/dns-query', -1],