@@ -207,10 +207,11 @@ def write(self, data, callback=None):
207
207
else :
208
208
self ._write_buffer .append (data )
209
209
self ._write_callback = stack_context .wrap (callback )
210
- self ._handle_write ()
211
- if self ._write_buffer :
212
- self ._add_io_state (self .io_loop .WRITE )
213
- self ._maybe_add_error_listener ()
210
+ if not self ._connecting :
211
+ self ._handle_write ()
212
+ if self ._write_buffer :
213
+ self ._add_io_state (self .io_loop .WRITE )
214
+ self ._maybe_add_error_listener ()
214
215
215
216
def set_close_callback (self , callback ):
216
217
"""Call the given callback when the stream is closed."""
@@ -626,6 +627,7 @@ def __init__(self, *args, **kwargs):
626
627
self ._ssl_accepting = True
627
628
self ._handshake_reading = False
628
629
self ._handshake_writing = False
630
+ self ._ssl_connect_callback = None
629
631
630
632
def reading (self ):
631
633
return self ._handshake_reading or super (SSLIOStream , self ).reading ()
@@ -663,7 +665,11 @@ def _do_ssl_handshake(self):
663
665
return self .close ()
664
666
else :
665
667
self ._ssl_accepting = False
666
- super (SSLIOStream , self )._handle_connect ()
668
+ if self ._ssl_connect_callback is not None :
669
+ callback = self ._ssl_connect_callback
670
+ self ._ssl_connect_callback = None
671
+ self ._run_callback (callback )
672
+
667
673
668
674
def _handle_read (self ):
669
675
if self ._ssl_accepting :
@@ -677,14 +683,23 @@ def _handle_write(self):
677
683
return
678
684
super (SSLIOStream , self )._handle_write ()
679
685
686
+ def connect (self , address , callback = None ):
687
+ # Save the user's callback and run it after the ssl handshake
688
+ # has completed.
689
+ self ._ssl_connect_callback = callback
690
+ super (SSLIOStream , self ).connect (address , callback = None )
691
+
680
692
def _handle_connect (self ):
693
+ # When the connection is complete, wrap the socket for SSL
694
+ # traffic. Note that we do this by overriding _handle_connect
695
+ # instead of by passing a callback to super().connect because
696
+ # user callbacks are enqueued asynchronously on the IOLoop,
697
+ # but since _handle_events calls _handle_connect immediately
698
+ # followed by _handle_write we need this to be synchronous.
681
699
self .socket = ssl .wrap_socket (self .socket ,
682
700
do_handshake_on_connect = False ,
683
701
** self ._ssl_options )
684
- # Don't call the superclass's _handle_connect (which is responsible
685
- # for telling the application that the connection is complete)
686
- # until we've completed the SSL handshake (so certificates are
687
- # available, etc).
702
+ super (SSLIOStream , self )._handle_connect ()
688
703
689
704
def _read_from_socket (self ):
690
705
if self ._ssl_accepting :
0 commit comments