2
2
3
3
namespace React \Tests \Socket ;
4
4
5
+ use Clue \React \Block ;
6
+ use Evenement \EventEmitterInterface ;
5
7
use React \EventLoop \Factory ;
6
- use React \Socket \ SecureServer ;
8
+ use React \Promise \ Promise ;
7
9
use React \Socket \ConnectionInterface ;
10
+ use React \Socket \SecureConnector ;
11
+ use React \Socket \SecureServer ;
8
12
use React \Socket \TcpServer ;
9
13
use React \Socket \TcpConnector ;
10
- use React \Socket \SecureConnector ;
11
- use Clue \React \Block ;
14
+ use React \Socket \ServerInterface ;
12
15
13
16
class FunctionalSecureServerTest extends TestCase
14
17
{
@@ -86,7 +89,7 @@ public function testWritesDataInMultipleChunksToConnection()
86
89
$ promise = $ connector ->connect ($ server ->getAddress ());
87
90
88
91
$ local = Block \await ($ promise , $ loop , self ::TIMEOUT );
89
- /* @var $local React\Stream\Stream */
92
+ /* @var $local ConnectionInterface */
90
93
91
94
$ received = 0 ;
92
95
$ local ->on ('data ' , function ($ chunk ) use (&$ received ) {
@@ -118,7 +121,7 @@ public function testWritesMoreDataInMultipleChunksToConnection()
118
121
$ promise = $ connector ->connect ($ server ->getAddress ());
119
122
120
123
$ local = Block \await ($ promise , $ loop , self ::TIMEOUT );
121
- /* @var $local React\Stream\Stream */
124
+ /* @var $local ConnectionInterface */
122
125
123
126
$ received = 0 ;
124
127
$ local ->on ('data ' , function ($ chunk ) use (&$ received ) {
@@ -151,7 +154,7 @@ public function testEmitsDataFromConnection()
151
154
$ promise = $ connector ->connect ($ server ->getAddress ());
152
155
153
156
$ local = Block \await ($ promise , $ loop , self ::TIMEOUT );
154
- /* @var $local React\Stream\Stream */
157
+ /* @var $local ConnectionInterface */
155
158
156
159
$ local ->write ("foo " );
157
160
@@ -181,7 +184,7 @@ public function testEmitsDataInMultipleChunksFromConnection()
181
184
$ promise = $ connector ->connect ($ server ->getAddress ());
182
185
183
186
$ local = Block \await ($ promise , $ loop , self ::TIMEOUT );
184
- /* @var $local React\Stream\Stream */
187
+ /* @var $local ConnectionInterface */
185
188
186
189
$ local ->write (str_repeat ('* ' , 400000 ));
187
190
@@ -210,7 +213,7 @@ public function testPipesDataBackInMultipleChunksFromConnection()
210
213
$ promise = $ connector ->connect ($ server ->getAddress ());
211
214
212
215
$ local = Block \await ($ promise , $ loop , self ::TIMEOUT );
213
- /* @var $local React\Stream\Stream */
216
+ /* @var $local ConnectionInterface */
214
217
215
218
$ received = 0 ;
216
219
$ local ->on ('data ' , function ($ chunk ) use (&$ received ) {
@@ -361,15 +364,15 @@ public function testEmitsErrorForConnectionWithPeerVerification()
361
364
'local_cert ' => __DIR__ . '/../examples/localhost.pem '
362
365
));
363
366
$ server ->on ('connection ' , $ this ->expectCallableNever ());
364
- $ server -> on ( ' error ' , $ this ->expectCallableOnce () );
367
+ $ errorEvent = $ this ->createPromieForServerError ( $ server );
365
368
366
369
$ connector = new SecureConnector (new TcpConnector ($ loop ), $ loop , array (
367
370
'verify_peer ' => true
368
371
));
369
372
$ promise = $ connector ->connect ($ server ->getAddress ());
370
-
371
373
$ promise ->then (null , $ this ->expectCallableOnce ());
372
- Block \sleep (self ::TIMEOUT , $ loop );
374
+
375
+ Block \await ($ errorEvent , $ loop , self ::TIMEOUT );
373
376
}
374
377
375
378
public function testEmitsErrorIfConnectionIsCancelled ()
@@ -385,16 +388,66 @@ public function testEmitsErrorIfConnectionIsCancelled()
385
388
'local_cert ' => __DIR__ . '/../examples/localhost.pem '
386
389
));
387
390
$ server ->on ('connection ' , $ this ->expectCallableNever ());
388
- $ server -> on ( ' error ' , $ this ->expectCallableOnce () );
391
+ $ errorEvent = $ this ->createPromieForServerError ( $ server );
389
392
390
393
$ connector = new SecureConnector (new TcpConnector ($ loop ), $ loop , array (
391
394
'verify_peer ' => false
392
395
));
393
396
$ promise = $ connector ->connect ($ server ->getAddress ());
394
397
$ promise ->cancel ();
395
-
396
398
$ promise ->then (null , $ this ->expectCallableOnce ());
397
- Block \sleep (self ::TIMEOUT , $ loop );
399
+
400
+ Block \await ($ errorEvent , $ loop , self ::TIMEOUT );
401
+ }
402
+
403
+ public function testEmitsErrorIfConnectionIsClosedBeforeHandshake ()
404
+ {
405
+ $ loop = Factory::create ();
406
+
407
+ $ server = new TcpServer (0 , $ loop );
408
+ $ server = new SecureServer ($ server , $ loop , array (
409
+ 'local_cert ' => __DIR__ . '/../examples/localhost.pem '
410
+ ));
411
+ $ server ->on ('connection ' , $ this ->expectCallableNever ());
412
+ $ errorEvent = $ this ->createPromieForServerError ($ server );
413
+
414
+ $ connector = new TcpConnector ($ loop );
415
+ $ promise = $ connector ->connect (str_replace ('tls:// ' , '' , $ server ->getAddress ()));
416
+
417
+ $ promise ->then (function (ConnectionInterface $ stream ) {
418
+ $ stream ->close ();
419
+ });
420
+
421
+ $ error = Block \await ($ errorEvent , $ loop , self ::TIMEOUT );
422
+
423
+ $ this ->assertTrue ($ error instanceof \RuntimeException);
424
+ $ this ->assertEquals ('Connection lost during TLS handshake (ECONNRESET) ' , $ error ->getMessage ());
425
+ $ this ->assertEquals (defined ('SOCKET_ECONNRESET ' ) ? SOCKET_ECONNRESET : 0 , $ error ->getCode ());
426
+ }
427
+
428
+ public function testEmitsErrorIfConnectionIsClosedWithIncompleteHandshake ()
429
+ {
430
+ $ loop = Factory::create ();
431
+
432
+ $ server = new TcpServer (0 , $ loop );
433
+ $ server = new SecureServer ($ server , $ loop , array (
434
+ 'local_cert ' => __DIR__ . '/../examples/localhost.pem '
435
+ ));
436
+ $ server ->on ('connection ' , $ this ->expectCallableNever ());
437
+ $ errorEvent = $ this ->createPromieForServerError ($ server );
438
+
439
+ $ connector = new TcpConnector ($ loop );
440
+ $ promise = $ connector ->connect (str_replace ('tls:// ' , '' , $ server ->getAddress ()));
441
+
442
+ $ promise ->then (function (ConnectionInterface $ stream ) {
443
+ $ stream ->end ("\x1e" );
444
+ });
445
+
446
+ $ error = Block \await ($ errorEvent , $ loop , self ::TIMEOUT );
447
+
448
+ $ this ->assertTrue ($ error instanceof \RuntimeException);
449
+ $ this ->assertEquals ('Connection lost during TLS handshake (ECONNRESET) ' , $ error ->getMessage ());
450
+ $ this ->assertEquals (defined ('SOCKET_ECONNRESET ' ) ? SOCKET_ECONNRESET : 0 , $ error ->getCode ());
398
451
}
399
452
400
453
public function testEmitsNothingIfConnectionIsIdle ()
@@ -415,7 +468,7 @@ public function testEmitsNothingIfConnectionIsIdle()
415
468
Block \sleep (self ::TIMEOUT , $ loop );
416
469
}
417
470
418
- public function testEmitsErrorIfConnectionIsNotSecureHandshake ()
471
+ public function testEmitsErrorIfConnectionIsHttpInsteadOfSecureHandshake ()
419
472
{
420
473
$ loop = Factory::create ();
421
474
@@ -424,7 +477,7 @@ public function testEmitsErrorIfConnectionIsNotSecureHandshake()
424
477
'local_cert ' => __DIR__ . '/../examples/localhost.pem '
425
478
));
426
479
$ server ->on ('connection ' , $ this ->expectCallableNever ());
427
- $ server -> on ( ' error ' , $ this ->expectCallableOnce () );
480
+ $ errorEvent = $ this ->createPromieForServerError ( $ server );
428
481
429
482
$ connector = new TcpConnector ($ loop );
430
483
$ promise = $ connector ->connect (str_replace ('tls:// ' , '' , $ server ->getAddress ()));
@@ -433,6 +486,49 @@ public function testEmitsErrorIfConnectionIsNotSecureHandshake()
433
486
$ stream ->write ("GET / HTTP/1.0 \r\n\r\n" );
434
487
});
435
488
436
- Block \sleep (self ::TIMEOUT , $ loop );
489
+ $ error = Block \await ($ errorEvent , $ loop , self ::TIMEOUT );
490
+
491
+ $ this ->assertTrue ($ error instanceof \RuntimeException);
492
+ $ this ->assertStringEndsWith (':http request ' , $ error ->getMessage ());
493
+ }
494
+
495
+ public function testEmitsErrorIfConnectionIsUnknownProtocolInsteadOfSecureHandshake ()
496
+ {
497
+ $ loop = Factory::create ();
498
+
499
+ $ server = new TcpServer (0 , $ loop );
500
+ $ server = new SecureServer ($ server , $ loop , array (
501
+ 'local_cert ' => __DIR__ . '/../examples/localhost.pem '
502
+ ));
503
+ $ server ->on ('connection ' , $ this ->expectCallableNever ());
504
+ $ errorEvent = $ this ->createPromieForServerError ($ server );
505
+
506
+ $ connector = new TcpConnector ($ loop );
507
+ $ promise = $ connector ->connect (str_replace ('tls:// ' , '' , $ server ->getAddress ()));
508
+
509
+ $ promise ->then (function (ConnectionInterface $ stream ) {
510
+ $ stream ->write ("Hello world! \n" );
511
+ });
512
+
513
+ $ error = Block \await ($ errorEvent , $ loop , self ::TIMEOUT );
514
+
515
+ $ this ->assertTrue ($ error instanceof \RuntimeException);
516
+ $ this ->assertStringEndsWith (':unknown protocol ' , $ error ->getMessage ());
517
+ }
518
+
519
+ private function createPromieForServerError (ServerInterface $ server )
520
+ {
521
+ return $ this ->createPromiseForEvent ($ server , 'error ' , function ($ error ) {
522
+ return $ error ;
523
+ });
524
+ }
525
+
526
+ private function createPromiseForEvent (EventEmitterInterface $ emitter , $ event , $ fn )
527
+ {
528
+ return new Promise (function ($ resolve ) use ($ emitter , $ event , $ fn ) {
529
+ $ emitter ->on ($ event , function () use ($ resolve , $ fn ) {
530
+ $ resolve (call_user_func_array ($ fn , func_get_args ()));
531
+ });
532
+ });
437
533
}
438
534
}
0 commit comments