4
4
5
5
use Clue \React \Block ;
6
6
use React \EventLoop \Factory ;
7
+ use React \Socket \ConnectionInterface ;
7
8
use React \Socket \Connector ;
9
+ use React \Socket \ConnectorInterface ;
8
10
use React \Socket \TcpServer ;
9
11
10
12
class FunctionalConnectorTest extends TestCase
11
13
{
12
- const TIMEOUT = 1.0 ;
14
+ const TIMEOUT = 30.0 ;
15
+
16
+ private $ ipv4 ;
17
+ private $ ipv6 ;
13
18
14
19
/** @test */
15
20
public function connectionToTcpServerShouldSucceedWithLocalhost ()
@@ -29,4 +34,174 @@ public function connectionToTcpServerShouldSucceedWithLocalhost()
29
34
$ connection ->close ();
30
35
$ server ->close ();
31
36
}
37
+
38
+ /**
39
+ * @test
40
+ * @group internet
41
+ */
42
+ public function connectionToRemoteTCP4n6ServerShouldResultInOurIP ()
43
+ {
44
+ $ loop = Factory::create ();
45
+
46
+ $ connector = new Connector ($ loop , array ('happy_eyeballs ' => true ));
47
+
48
+ $ ip = Block \await ($ this ->request ('dual.tlund.se ' , $ connector ), $ loop , self ::TIMEOUT );
49
+
50
+ $ this ->assertSame ($ ip , filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 ), $ ip );
51
+ }
52
+
53
+ /**
54
+ * @test
55
+ * @group internet
56
+ */
57
+ public function connectionToRemoteTCP4ServerShouldResultInOurIP ()
58
+ {
59
+ if ($ this ->ipv4 () === false ) {
60
+ $ this ->markTestSkipped ('IPv4 not supported on this system ' );
61
+ }
62
+
63
+ $ loop = Factory::create ();
64
+
65
+ $ connector = new Connector ($ loop , array ('happy_eyeballs ' => true ));
66
+
67
+ $ ip = Block \await ($ this ->request ('ipv4.tlund.se ' , $ connector ), $ loop , self ::TIMEOUT );
68
+
69
+ $ this ->assertSame ($ ip , filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 ), $ ip );
70
+ $ this ->assertFalse (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 ), $ ip );
71
+ }
72
+
73
+ /**
74
+ * @test
75
+ * @group internet
76
+ */
77
+ public function connectionToRemoteTCP6ServerShouldResultInOurIP ()
78
+ {
79
+ if ($ this ->ipv6 () === false ) {
80
+ $ this ->markTestSkipped ('IPv6 not supported on this system ' );
81
+ }
82
+
83
+ $ loop = Factory::create ();
84
+
85
+ $ connector = new Connector ($ loop , array ('happy_eyeballs ' => true ));
86
+
87
+ $ ip = Block \await ($ this ->request ('ipv6.tlund.se ' , $ connector ), $ loop , self ::TIMEOUT );
88
+
89
+ $ this ->assertFalse (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 ), $ ip );
90
+ $ this ->assertSame ($ ip , filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 ), $ ip );
91
+ }
92
+
93
+ /**
94
+ * @test
95
+ * @group internet
96
+ *
97
+ * @expectedException \RuntimeException
98
+ * @expectedExceptionMessageRegExp /Connection to ipv6.tlund.se:80 failed/
99
+ */
100
+ public function tryingToConnectToAnIPv6OnlyHostWithOutHappyEyeBallsShouldResultInFailure ()
101
+ {
102
+ $ loop = Factory::create ();
103
+
104
+ $ connector = new Connector ($ loop , array ('happy_eyeballs ' => false ));
105
+
106
+ $ ip = Block \await ($ this ->request ('ipv6.tlund.se ' , $ connector ), $ loop , self ::TIMEOUT );
107
+
108
+ $ this ->assertFalse (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 ), $ ip );
109
+ $ this ->assertSame ($ ip , filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 ), $ ip );
110
+ }
111
+
112
+ /**
113
+ * @test
114
+ * @group internet
115
+ *
116
+ * @expectedException \RuntimeException
117
+ * @expectedExceptionMessageRegExp /Connection to tcp:\/\/193.15.228.195:80 failed:/
118
+ */
119
+ public function connectingDirectlyToAnIPv4AddressShouldFailWhenIPv4IsntAvailable ()
120
+ {
121
+ if ($ this ->ipv4 () === true ) {
122
+ $ this ->markTestSkipped ('IPv4 supported on this system ' );
123
+ }
124
+
125
+ $ loop = Factory::create ();
126
+
127
+ $ connector = new Connector ($ loop );
128
+
129
+ $ host = current (dns_get_record ('ipv4.tlund.se ' , DNS_A ));
130
+ $ host = $ host ['ip ' ];
131
+ $ ip = Block \await ($ this ->request ($ host , $ connector ), $ loop , self ::TIMEOUT );
132
+
133
+ $ this ->assertSame ($ ip , filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 ), $ ip );
134
+ $ this ->assertFalse (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 ), $ ip );
135
+ }
136
+
137
+ /**
138
+ * @test
139
+ * @group internet
140
+ *
141
+ * @expectedException \RuntimeException
142
+ * @expectedExceptionMessageRegExp /Connection to tcp:\/\/\[2a00:801:f::195\]:80 failed:/
143
+ */
144
+ public function connectingDirectlyToAnIPv6AddressShouldFailWhenIPv6IsntAvailable ()
145
+ {
146
+ if ($ this ->ipv6 () === true ) {
147
+ $ this ->markTestSkipped ('IPv6 supported on this system ' );
148
+ }
149
+
150
+ $ loop = Factory::create ();
151
+
152
+ $ connector = new Connector ($ loop );
153
+
154
+ $ host = current (dns_get_record ('ipv6.tlund.se ' , DNS_AAAA ));
155
+ $ host = $ host ['ipv6 ' ];
156
+ $ host = '[ ' . $ host . '] ' ;
157
+ $ ip = Block \await ($ this ->request ($ host , $ connector ), $ loop , self ::TIMEOUT );
158
+
159
+ $ this ->assertFalse (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 ), $ ip );
160
+ $ this ->assertSame ($ ip , filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 ), $ ip );
161
+ }
162
+
163
+ /**
164
+ * @internal
165
+ */
166
+ public function parseIpFromPage ($ body )
167
+ {
168
+ $ ex = explode ('title="Look up on bgp.he.net"> ' , $ body );
169
+ $ ex = explode ('< ' , $ ex [1 ]);
170
+
171
+ return $ ex [0 ];
172
+ }
173
+
174
+ private function request ($ host , ConnectorInterface $ connector )
175
+ {
176
+ $ that = $ this ;
177
+ return $ connector ->connect ($ host . ':80 ' )->then (function (ConnectionInterface $ connection ) use ($ host ) {
178
+ $ connection ->write ("GET / HTTP/1.1 \r\nHost: " . $ host . "\r\n\r\n" );
179
+
180
+ return \React \Promise \Stream \buffer ($ connection );
181
+ })->then (function ($ response ) use ($ that ) {
182
+ return $ that ->parseIpFromPage ($ response );
183
+ });
184
+ }
185
+
186
+ private function ipv4 ()
187
+ {
188
+ if ($ this ->ipv4 !== null ) {
189
+ return $ this ->ipv4 ;
190
+ }
191
+
192
+ $ this ->ipv4 = !!@file_get_contents ('http://ipv4.tlund.se/ ' );
193
+
194
+ return $ this ->ipv4 ;
195
+ }
196
+
197
+ private function ipv6 ()
198
+ {
199
+ if ($ this ->ipv6 !== null ) {
200
+ return $ this ->ipv6 ;
201
+ }
202
+
203
+ $ this ->ipv6 = !!@file_get_contents ('http://ipv6.tlund.se/ ' );
204
+
205
+ return $ this ->ipv6 ;
206
+ }
32
207
}
0 commit comments