SSL support in asynchat.async_chat
A while back I needed to be able to use SSL connections in async_chat, but I found it to be horribly incompatible. After quite a bit of investigation I found a suitable solution.
import asynchat import socket import ssl import errno class async_chat_ssl(asynchat.async_chat): """ Asynchronous connection with SSL support. """ def connect(self, host, use_ssl=False): self.use_ssl = use_ssl if use_ssl: self.send = self._ssl_send self.recv = self._ssl_recv asynchat.async_chat.connect(self, host) def handle_connect(self): """ Initializes SSL support after the connection has been made. """ if self.use_ssl: self.ssl = ssl.wrap_socket(self.socket) self.set_socket(self.ssl) def _ssl_send(self, data): """ Replacement for self.send() during SSL connections. """ try: result = self.write(data) return result except ssl.SSLError, why: if why[0] in (asyncore.EWOULDBLOCK, errno.ESRCH): return 0 else: raise ssl.SSLError, why return 0 def _ssl_recv(self, buffer_size): """ Replacement for self.recv() during SSL connections. """ try: data = self.read(buffer_size) if not data: self.handle_close() return '' return data except ssl.SSLError, why: if why[0] in (asyncore.ECONNRESET, asyncore.ENOTCONN, asyncore.ESHUTDOWN): self.handle_close() return '' elif why[0] == errno.ENOENT: # Required in order to keep it non-blocking return '' else: raise
It should fit in place of typical use of asynchat.async_chat. In order to specify that you’re wanting to use SSL, just set the flag in:
connect(host, use_ssl=True)
It would be nice if SSL support with asynchat.async_chat worked by default. Hopefully I’m not the only one who finds the above solution useful.
And as always, if you see any errors above, I encourage you to post a comment explaining the it!
