[Python-Dev] blocking a non-blocking socket

Audun Ostrem Nordal Audun.Ostrem.Nordal at cern.ch
Mon Dec 3 14:01:04 CET 2007


> An interesting question has come up in the development of the 
> SSL module.
> 
> The function ssl.wrap_socket() takes a flag, 
> do_handshake_on_connect, which tells it whether to do the SSL 
> handshake before returning an SSLSocket object to the caller. 
>  If the socket being wrapped is non-blocking, the code in 
> wrap_socket() must invoke do_handshake() multiple times, and 
> effectively block until the handshake is done.
> 
> Right now, I'm doing it with this loop:
> 
>             if do_handshake_on_connect:
>                 # have to loop to support non-blocking sockets
>                 while True:
>                     try:
>                         self.do_handshake()
>                         break
>                     except SSLError, err:
>                         if err.args[0] == SSL_ERROR_WANT_READ:
>                             select.select([self], [], [])
>                         elif err.args[0] == SSL_ERROR_WANT_WRITE:
>                             select.select([], [self], [])
>                         else:
>                             raise

Hello Bill,

Another way of doing it could be to expose a connect() method on the ssl
objects.  It changes the socket.ssl api, but I'd say it is in the same
spirit as the do_handshake_on_connect parameter since no existing code
will break.  The caller then calls connect() until it does not return
SSL_ERROR_WANT_[WRITE|READ].  This only applies when the underlying
socket is non-blocking and the do_handshake_on_connect parameter is
false.

Arguably, this is similar to how normal sockets are treated in asyncore,
only that he caller must be prepared to respond to (multiple?) readable
and writable events for the connection to be established.


Cheers

Audun


More information about the Python-Dev mailing list