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\Socket;
4
 
5
use React\Dns\Config\Config as DnsConfig;
6
use React\Dns\Resolver\Factory as DnsFactory;
7
use React\Dns\Resolver\ResolverInterface;
8
use React\EventLoop\LoopInterface;
9
 
10
/**
11
 * The `Connector` class is the main class in this package that implements the
12
 * `ConnectorInterface` and allows you to create streaming connections.
13
 *
14
 * You can use this connector to create any kind of streaming connections, such
15
 * as plaintext TCP/IP, secure TLS or local Unix connection streams.
16
 *
17
 * Under the hood, the `Connector` is implemented as a *higher-level facade*
18
 * or the lower-level connectors implemented in this package. This means it
19
 * also shares all of their features and implementation details.
20
 * If you want to typehint in your higher-level protocol implementation, you SHOULD
21
 * use the generic [`ConnectorInterface`](#connectorinterface) instead.
22
 *
23
 * @see ConnectorInterface for the base interface
24
 */
25
final class Connector implements ConnectorInterface
26
{
27
    private $connectors = array();
28
 
29
    public function __construct(LoopInterface $loop, array $options = array())
30
    {
31
        // apply default options if not explicitly given
32
        $options += array(
33
            'tcp' => true,
34
            'tls' => true,
35
            'unix' => true,
36
 
37
            'dns' => true,
38
            'timeout' => true,
39
            'happy_eyeballs' => true,
40
        );
41
 
42
        if ($options['timeout'] === true) {
43
            $options['timeout'] = (float)\ini_get("default_socket_timeout");
44
        }
45
 
46
        if ($options['tcp'] instanceof ConnectorInterface) {
47
            $tcp = $options['tcp'];
48
        } else {
49
            $tcp = new TcpConnector(
50
                $loop,
51
                \is_array($options['tcp']) ? $options['tcp'] : array()
52
            );
53
        }
54
 
55
        if ($options['dns'] !== false) {
56
            if ($options['dns'] instanceof ResolverInterface) {
57
                $resolver = $options['dns'];
58
            } else {
59
                if ($options['dns'] !== true) {
60
                    $server = $options['dns'];
61
                } else {
62
                    // try to load nameservers from system config or default to Google's public DNS
63
                    $config = DnsConfig::loadSystemConfigBlocking();
64
                    $server = $config->nameservers ? \reset($config->nameservers) : '8.8.8.8';
65
                }
66
 
67
                $factory = new DnsFactory();
68
                $resolver = $factory->createCached(
69
                    $server,
70
                    $loop
71
                );
72
            }
73
 
74
            if ($options['happy_eyeballs'] === true) {
75
                $tcp = new HappyEyeBallsConnector($loop, $tcp, $resolver);
76
            } else {
77
                $tcp = new DnsConnector($tcp, $resolver);
78
            }
79
        }
80
 
81
        if ($options['tcp'] !== false) {
82
            $options['tcp'] = $tcp;
83
 
84
            if ($options['timeout'] !== false) {
85
                $options['tcp'] = new TimeoutConnector(
86
                    $options['tcp'],
87
                    $options['timeout'],
88
                    $loop
89
                );
90
            }
91
 
92
            $this->connectors['tcp'] = $options['tcp'];
93
        }
94
 
95
        if ($options['tls'] !== false) {
96
            if (!$options['tls'] instanceof ConnectorInterface) {
97
                $options['tls'] = new SecureConnector(
98
                    $tcp,
99
                    $loop,
100
                    \is_array($options['tls']) ? $options['tls'] : array()
101
                );
102
            }
103
 
104
            if ($options['timeout'] !== false) {
105
                $options['tls'] = new TimeoutConnector(
106
                    $options['tls'],
107
                    $options['timeout'],
108
                    $loop
109
                );
110
            }
111
 
112
            $this->connectors['tls'] = $options['tls'];
113
        }
114
 
115
        if ($options['unix'] !== false) {
116
            if (!$options['unix'] instanceof ConnectorInterface) {
117
                $options['unix'] = new UnixConnector($loop);
118
            }
119
            $this->connectors['unix'] = $options['unix'];
120
        }
121
    }
122
 
123
    public function connect($uri)
124
    {
125
        $scheme = 'tcp';
126
        if (\strpos($uri, '://') !== false) {
127
            $scheme = (string)\substr($uri, 0, \strpos($uri, '://'));
128
        }
129
 
130
        if (!isset($this->connectors[$scheme])) {
131
            return \React\Promise\reject(new \RuntimeException(
132
                'No connector available for URI scheme "' . $scheme . '"'
133
            ));
134
        }
135
 
136
        return $this->connectors[$scheme]->connect($uri);
137
    }
138
}
139