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 ->createPromiseForServerError ( $ 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 ->createPromiseForServerError ( $ 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 ->createPromiseForServerError ($ 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 ' , $ 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 ->createPromiseForServerError ($ 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 ' , $ error ->getMessage ());
450
+ $ this ->assertEquals (defined ('SOCKET_ECONNRESET ' ) ? SOCKET_ECONNRESET : 0 , $
10000
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 ->createPromiseForServerError ( $ server );
428
481
429
482
$ connector = new TcpConnector ($ loop );
430
483
$ promise = $ connector ->connect (str_replace ('tls:// ' , '' , $ server ->getAddress ()));
@@ -433,6 +486,59 @@ 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
+
493
+ // OpenSSL error messages are version/platform specific
494
+ // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:SSL3_GET_RECORD:http request
495
+ // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:ssl3_get_record:wrong version number
496
+ // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:func(143):reason(267)
497
+ // Unable to complete TLS handshake: Failed setting RSA key
498
+ }
499
+
500
+ public function testEmitsErrorIfConnectionIsUnknownProtocolInsteadOfSecureHandshake ()
501
+ {
502
+ $ loop = Factory::create ();
503
+
504
+ $ server = new TcpServer (0 , $ loop );
505
+ $ server = new SecureServer ($ server , $ loop , array (
506
+ 'local_cert ' => __DIR__ . '/../examples/localhost.pem '
507
+ ));
508
+ $ server ->on ('connection ' , $ this ->expectCallableNever ());
509
+ $ errorEvent = $ this ->createPromiseForServerError ($ server );
510
+
511
+ $ connector = new TcpConnector ($ loop );
512
+ $ promise = $ connector ->connect (str_replace ('tls:// ' , '' , $ server ->getAddress ()));
513
+
514
+ $ promise ->then (function (ConnectionInterface $ stream ) {
515
+ $ stream ->write ("Hello world! \n" );
516
+ });
517
+
518
+ $ error = Block \await ($ errorEvent , $ loop , self ::TIMEOUT );
519
+
520
+ $ this ->assertTrue ($ error instanceof \RuntimeException);
521
+
522
+ // OpenSSL error messages are version/platform specific
523
+ // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:SSL3_GET_RECORD:unknown protocol
524
+ // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:ssl3_get_record:wrong version number
525
+ // Unable to complete TLS handshake: SSL operation failed with code 1. OpenSSL Error messages: error:1408F10B:SSL routines:func(143):reason(267)
526
+ // Unable to complete TLS handshake: Failed setting RSA key
527
+ }
528
+
529
+ private function createPromiseForServerError (ServerInterface $ server )
530
+ {
531
+ return $ this ->createPromiseForEvent ($ server , 'error ' , function ($ error ) {
532
+ return $ error ;
533
+ });
534
+ }
535
+
536
+ private function createPromiseForEvent (EventEmitterInterface $ emitter , $ event , $ fn )
537
+ {
538
+ return new Promise (function ($ resolve ) use ($ emitter , $ event , $ fn ) {
539
+ $ emitter ->on ($ event , function () use ($ resolve , $ fn ) {
540
+ $ resolve (call_user_func_array ($ fn , func_get_args ()));
541
+ });
542
+ });
437
543
}
438
544
}
0 commit comments