@@ -744,6 +744,85 @@ def test_create_connection_local_addr_in_use(self):
744744 self .assertEqual (cm .exception .errno , errno .EADDRINUSE )
745745 self .assertIn (str (httpd .address ), cm .exception .strerror )
746746
747+ def test_connect_accepted_socket (self , server_ssl = None , client_ssl = None ):
748+ loop = self .loop
749+
750+ class MyProto (MyBaseProto ):
751+
752+ def connection_lost (self , exc ):
753+ super ().connection_lost (exc )
754+ loop .call_soon (loop .stop )
755+
756+ def data_received (self , data ):
757+ super ().data_received (data )
758+ self .transport .write (expected_response )
759+
760+ lsock = socket .socket ()
761+ lsock .bind (('127.0.0.1' , 0 ))
762+ lsock .listen (1 )
763+ addr = lsock .getsockname ()
764+
765+ message = b'test data'
766+ reponse = None
767+ expected_response = b'roger'
768+
769+ def client ():
770+ global response
771+ try :
772+ csock = socket .socket ()
773+ if client_ssl is not None :
774+ csock = client_ssl .wrap_socket (csock )
775+ csock .connect (addr )
776+ csock .sendall (message )
777+ response = csock .recv (99 )
778+ csock .close ()
779+ except Exception as exc :
780+ print (
781+ "Failure in client thread in test_connect_accepted_socket" ,
782+ exc )
783+
784+ thread = threading .Thread (target = client , daemon = True )
785+ thread .start ()
786+
787+ conn , _ = lsock .accept ()
788+ proto = MyProto (loop = loop )
789+ proto .loop = loop
790+ f = loop .create_task (
791+ loop .connect_accepted_socket (
792+ (lambda : proto ), conn , ssl = server_ssl ))
793+ loop .run_forever ()
794+ conn .close ()
795+ lsock .close ()
796+
797+ thread .join (1 )
798+ self .assertFalse (thread .is_alive ())
799+ self .assertEqual (proto .state , 'CLOSED' )
800+ self .assertEqual (proto .nbytes , len (message ))
801+ self .assertEqual (response , expected_response )
802+
803+ @unittest .skipIf (ssl is None , 'No ssl module' )
804+ def test_ssl_connect_accepted_socket (self ):
805+ if (sys .platform == 'win32' and
806+ sys .version_info < (3 , 5 ) and
807+ isinstance (self .loop , proactor_events .BaseProactorEventLoop )
808+ ):
809+ raise unittest .SkipTest (
810+ 'SSL not supported with proactor event loops before Python 3.5'
811+ )
812+
813+ server_context = ssl .SSLContext (ssl .PROTOCOL_SSLv23 )
814+ server_context .load_cert_chain (ONLYCERT , ONLYKEY )
815+ if hasattr (server_context , 'check_hostname' ):
816+ server_context .check_hostname = False
817+ server_context .verify_mode = ssl .CERT_NONE
818+
819+ client_context = ssl .SSLContext (ssl .PROTOCOL_SSLv23 )
820+ if hasattr (server_context , 'check_hostname' ):
821+ client_context .check_hostname = False
822+ client_context .verify_mode = ssl .CERT_NONE
823+
824+ self .test_connect_accepted_socket (server_context , client_context )
825+
747826 @mock .patch ('asyncio.base_events.socket' )
748827 def create_server_multiple_hosts (self , family , hosts , mock_sock ):
749828 @asyncio .coroutine
0 commit comments