[Python-Dev] ssl module integration with asyncore
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