friendship ended with social-app. php is my new best friend
1<?php
2
3namespace React\Socket;
4
5use React\Dns\Resolver\ResolverInterface;
6use React\EventLoop\Loop;
7use React\EventLoop\LoopInterface;
8use React\Promise;
9
10final class HappyEyeBallsConnector implements ConnectorInterface
11{
12 private $loop;
13 private $connector;
14 private $resolver;
15
16 /**
17 * @param ?LoopInterface $loop
18 * @param ConnectorInterface $connector
19 * @param ResolverInterface $resolver
20 */
21 public function __construct($loop = null, $connector = null, $resolver = null)
22 {
23 // $connector and $resolver arguments are actually required, marked
24 // optional for technical reasons only. Nullable $loop without default
25 // requires PHP 7.1, null default is also supported in legacy PHP
26 // versions, but required parameters are not allowed after arguments
27 // with null default. Mark all parameters optional and check accordingly.
28 if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
29 throw new \InvalidArgumentException('Argument #1 ($loop) expected null|React\EventLoop\LoopInterface');
30 }
31 if (!$connector instanceof ConnectorInterface) { // manual type check to support legacy PHP < 7.1
32 throw new \InvalidArgumentException('Argument #2 ($connector) expected React\Socket\ConnectorInterface');
33 }
34 if (!$resolver instanceof ResolverInterface) { // manual type check to support legacy PHP < 7.1
35 throw new \InvalidArgumentException('Argument #3 ($resolver) expected React\Dns\Resolver\ResolverInterface');
36 }
37
38 $this->loop = $loop ?: Loop::get();
39 $this->connector = $connector;
40 $this->resolver = $resolver;
41 }
42
43 public function connect($uri)
44 {
45 $original = $uri;
46 if (\strpos($uri, '://') === false) {
47 $uri = 'tcp://' . $uri;
48 $parts = \parse_url($uri);
49 if (isset($parts['scheme'])) {
50 unset($parts['scheme']);
51 }
52 } else {
53 $parts = \parse_url($uri);
54 }
55
56 if (!$parts || !isset($parts['host'])) {
57 return Promise\reject(new \InvalidArgumentException(
58 'Given URI "' . $original . '" is invalid (EINVAL)',
59 \defined('SOCKET_EINVAL') ? \SOCKET_EINVAL : (\defined('PCNTL_EINVAL') ? \PCNTL_EINVAL : 22)
60 ));
61 }
62
63 $host = \trim($parts['host'], '[]');
64
65 // skip DNS lookup / URI manipulation if this URI already contains an IP
66 if (@\inet_pton($host) !== false) {
67 return $this->connector->connect($original);
68 }
69
70 $builder = new HappyEyeBallsConnectionBuilder(
71 $this->loop,
72 $this->connector,
73 $this->resolver,
74 $uri,
75 $host,
76 $parts
77 );
78 return $builder->connect();
79 }
80}