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",
"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": "*"

View File

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

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;
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

View File

@ -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:

View File

@ -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

View File

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

View File

@ -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()],
];
}
/**

View File

@ -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()

View File

@ -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++) {

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_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],