[Python-Dev] ssl module, non-blocking sockets and asyncore integration

Bill Janssen janssen at parc.com
Mon Sep 15 04:50:15 CEST 2008

Hi, Giampaolo.

If you look a bit further in Lib/test/test_ssl.py, you'll see a
non-blocking use of the "do_handshake" method.  Basically, the flag
"do_handshake_on_connect" says whether you want this to happen
automatically and blockingly (True), or whether you want to do it
yourself (False).  In the test suite, the function
"testNonBlockingHandshake" does the async client-side handshake; the
server side logic is just the same, only it would happen in the server's
"handle new connection" code -- you'd have to add a state variable, and
bind handlers for "read_event" and "write_event", which would consult
the state variable to see whether they had finished the handshake yet.

I just made the server do it automatically to make life easier.

The hard part isn't really doing the non-blocking, it's trying to figure
out how to use asyncore correctly, IMO.

Giampaolo Rodola' <gnewsg at gmail.com> wrote:

> I'm interested in using the ssl module with asyncore but since there's
> no real documentation about how using ssl module with non-blocking

If you'd like to contribute a doc patch, that would be great.

Here's what it current says for do_handshake_on_connect:

  The parameter do_handshake_on_connect specifies whether to do the SSL
  handshake automatically after doing a socket.connect(), or whether the
  application program will call it explicitly, by invoking the
  SSLSocket.do_handshake() method. Calling SSLSocket.do_handshake()
  explicitly gives the program control over the blocking behavior of the
  socket I/O involved in the handshake.

and here's what the docs for do_handshake() says:

  SSLSocket.do_handshake()¦ Perform a TLS/SSL handshake. If this is used
  with a non-blocking socket, it may raise SSLError with an arg[0] of
  SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, in which case it must be
  called again until it completes successfully. For example, to simulate
  the behavior of a blocking socket, one might write:

    while True:
        except ssl.SSLError, err:
            if err.args[0] == ssl.SSL_ERROR_WANT_READ:
                select.select([s], [], [])
            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
                select.select([], [s], [])


More information about the Python-Dev mailing list