[Python-Dev] ssl module integration with asyncore (original) (raw)

Bill Janssen janssen at parc.com
Thu Nov 29 03:27:33 CET 2007


It does raise the same exception.

Hmmm, not in my version.

Are there plans for fixing this?

Yes, it's fixed in my CVS, and I'll upload a new version to PyPI when I get a chance.

Using that kind of workaround is not acceptable in any case (select module shouldn't even get imported when using asyncore).

Well, that's what the fix in the SSL module will do under the covers, so if there's a reason not to do it, or a better way of doing it, speak now. It really has nothing to do with asyncore; it's just a way of safely handling a socket which may or may not be non-blocking.

A more extended example, more true to the asyncore way of doing things, would in fact keep track of the connection state in a local variable, and would consult that in "handle_read_event" and "handle_write_event", calling do_handshake again if it's still not completed. That way you could get rid of the select.

Here's my (working) version of your code. Note that I inherit from dispatcher_with_send to make sure I have a working "handle_write" method.

Bill

--- snippet --- import asyncore, asynchat, socket, ssl, select

class Handler(asyncore.dispatcher_with_send):

def __init__(self, conn):
    asyncore.dispatcher_with_send.__init__(self, conn)
    self.socket = ssl.wrap_socket(conn, server_side=True,
                                  certfile='keycert.pem',
                                  do_handshake_on_connect=False)
    while True:
        try:
            self.socket.do_handshake()
            break
        except ssl.SSLError, err:
            if err.args[0] == ssl.SSL_ERROR_WANT_READ:
                select.select([self.socket], [], [])
            elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
                select.select([], [self.socket], [])
            else:
                raise
    self.send("hello there!")        

def readable(self):
    if isinstance(self.socket, ssl.SSLSocket):
        while self.socket.pending() > 0:
            self.handle_read_event()
    return True

def handle_read(self):
    data = self.recv(1024)
    print data

def handle_error(self):
    raise

class Server(asyncore.dispatcher):

def __init__(self):
    asyncore.dispatcher.__init__(self)
    self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
    self.bind(('', 54321))
    self.listen(5)

def handle_accept(self):
    sock_obj, addr = self.accept()
    print "[]%s:%s Connected." %addr
    Handler(sock_obj)

def handle_error(self):
    raise

Server() asyncore.loop(timeout=1) --- /snippet ---



More information about the Python-Dev mailing list