Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
}