| 3 |
liveuser |
1 |
<?php
|
|
|
2 |
|
|
|
3 |
namespace React\Dns\Resolver;
|
|
|
4 |
|
|
|
5 |
use React\Cache\ArrayCache;
|
|
|
6 |
use React\Cache\CacheInterface;
|
|
|
7 |
use React\Dns\Config\HostsFile;
|
|
|
8 |
use React\Dns\Query\CachingExecutor;
|
|
|
9 |
use React\Dns\Query\CoopExecutor;
|
|
|
10 |
use React\Dns\Query\ExecutorInterface;
|
|
|
11 |
use React\Dns\Query\HostsFileExecutor;
|
|
|
12 |
use React\Dns\Query\RetryExecutor;
|
|
|
13 |
use React\Dns\Query\SelectiveTransportExecutor;
|
|
|
14 |
use React\Dns\Query\TcpTransportExecutor;
|
|
|
15 |
use React\Dns\Query\TimeoutExecutor;
|
|
|
16 |
use React\Dns\Query\UdpTransportExecutor;
|
|
|
17 |
use React\EventLoop\LoopInterface;
|
|
|
18 |
|
|
|
19 |
final class Factory
|
|
|
20 |
{
|
|
|
21 |
/**
|
|
|
22 |
* @param string $nameserver
|
|
|
23 |
* @param LoopInterface $loop
|
|
|
24 |
* @return \React\Dns\Resolver\ResolverInterface
|
|
|
25 |
*/
|
|
|
26 |
public function create($nameserver, LoopInterface $loop)
|
|
|
27 |
{
|
|
|
28 |
$executor = $this->decorateHostsFileExecutor($this->createExecutor($nameserver, $loop));
|
|
|
29 |
|
|
|
30 |
return new Resolver($executor);
|
|
|
31 |
}
|
|
|
32 |
|
|
|
33 |
/**
|
|
|
34 |
* @param string $nameserver
|
|
|
35 |
* @param LoopInterface $loop
|
|
|
36 |
* @param ?CacheInterface $cache
|
|
|
37 |
* @return \React\Dns\Resolver\ResolverInterface
|
|
|
38 |
*/
|
|
|
39 |
public function createCached($nameserver, LoopInterface $loop, CacheInterface $cache = null)
|
|
|
40 |
{
|
|
|
41 |
// default to keeping maximum of 256 responses in cache unless explicitly given
|
|
|
42 |
if (!($cache instanceof CacheInterface)) {
|
|
|
43 |
$cache = new ArrayCache(256);
|
|
|
44 |
}
|
|
|
45 |
|
|
|
46 |
$executor = $this->createExecutor($nameserver, $loop);
|
|
|
47 |
$executor = new CachingExecutor($executor, $cache);
|
|
|
48 |
$executor = $this->decorateHostsFileExecutor($executor);
|
|
|
49 |
|
|
|
50 |
return new Resolver($executor);
|
|
|
51 |
}
|
|
|
52 |
|
|
|
53 |
/**
|
|
|
54 |
* Tries to load the hosts file and decorates the given executor on success
|
|
|
55 |
*
|
|
|
56 |
* @param ExecutorInterface $executor
|
|
|
57 |
* @return ExecutorInterface
|
|
|
58 |
* @codeCoverageIgnore
|
|
|
59 |
*/
|
|
|
60 |
private function decorateHostsFileExecutor(ExecutorInterface $executor)
|
|
|
61 |
{
|
|
|
62 |
try {
|
|
|
63 |
$executor = new HostsFileExecutor(
|
|
|
64 |
HostsFile::loadFromPathBlocking(),
|
|
|
65 |
$executor
|
|
|
66 |
);
|
|
|
67 |
} catch (\RuntimeException $e) {
|
|
|
68 |
// ignore this file if it can not be loaded
|
|
|
69 |
}
|
|
|
70 |
|
|
|
71 |
// Windows does not store localhost in hosts file by default but handles this internally
|
|
|
72 |
// To compensate for this, we explicitly use hard-coded defaults for localhost
|
|
|
73 |
if (DIRECTORY_SEPARATOR === '\\') {
|
|
|
74 |
$executor = new HostsFileExecutor(
|
|
|
75 |
new HostsFile("127.0.0.1 localhost\n::1 localhost"),
|
|
|
76 |
$executor
|
|
|
77 |
);
|
|
|
78 |
}
|
|
|
79 |
|
|
|
80 |
return $executor;
|
|
|
81 |
}
|
|
|
82 |
|
|
|
83 |
private function createExecutor($nameserver, LoopInterface $loop)
|
|
|
84 |
{
|
|
|
85 |
$parts = \parse_url($nameserver);
|
|
|
86 |
|
|
|
87 |
if (isset($parts['scheme']) && $parts['scheme'] === 'tcp') {
|
|
|
88 |
$executor = $this->createTcpExecutor($nameserver, $loop);
|
|
|
89 |
} elseif (isset($parts['scheme']) && $parts['scheme'] === 'udp') {
|
|
|
90 |
$executor = $this->createUdpExecutor($nameserver, $loop);
|
|
|
91 |
} else {
|
|
|
92 |
$executor = new SelectiveTransportExecutor(
|
|
|
93 |
$this->createUdpExecutor($nameserver, $loop),
|
|
|
94 |
$this->createTcpExecutor($nameserver, $loop)
|
|
|
95 |
);
|
|
|
96 |
}
|
|
|
97 |
|
|
|
98 |
return new CoopExecutor($executor);
|
|
|
99 |
}
|
|
|
100 |
|
|
|
101 |
private function createTcpExecutor($nameserver, LoopInterface $loop)
|
|
|
102 |
{
|
|
|
103 |
return new TimeoutExecutor(
|
|
|
104 |
new TcpTransportExecutor($nameserver, $loop),
|
|
|
105 |
5.0,
|
|
|
106 |
$loop
|
|
|
107 |
);
|
|
|
108 |
}
|
|
|
109 |
|
|
|
110 |
private function createUdpExecutor($nameserver, LoopInterface $loop)
|
|
|
111 |
{
|
|
|
112 |
return new RetryExecutor(
|
|
|
113 |
new TimeoutExecutor(
|
|
|
114 |
new UdpTransportExecutor(
|
|
|
115 |
$nameserver,
|
|
|
116 |
$loop
|
|
|
117 |
),
|
|
|
118 |
5.0,
|
|
|
119 |
$loop
|
|
|
120 |
)
|
|
|
121 |
);
|
|
|
122 |
}
|
|
|
123 |
}
|