[PYTHON-CRYPTO] M2Crypto.httpslib.HTTPSConnection only works once?
Ng Pheng Siong
ngps at NETMEMETIC.COM
Mon Jan 31 16:17:56 CET 2005
On Fri, Jan 28, 2005 at 01:42:36PM -0800, Heikki Toivonen wrote:
> M2Crypto.SSL.SSLError: bad write retry
> Has anyone else seen this?
I suppose your code uses non-blocking sockets. I've just blogged about this
very topic here:
http://sandbox.rulemaker.net/ngps/199
In essence, "bad write retry" arises from the way OpenSSL behaves in
non-blocking mode; specifically, if a write cannot complete (because of
SSL-layer protocol happenings) then the operation should be attempted again
with the same data.
The fix alluded to in my blog post is as follows:
- Changed the 'send' method in class https_channel in ZServerSSL's
https_server.py to this:
def send(self, data):
try:
if self._wbuf is not None:
if len(data) > len(self._wbuf):
result = self._send_buffered(self._wbuf)
if result > 0:
data = data[len(self._wbuf):]
self._wbuf = None
return self.send(data)
else:
return 0
else:
self._wbuf = None
return self.send(data)
else:
result = self.socket._write_nbio(data)
if result <= 0:
if result == -1:
self._wbuf = data
return 0
else:
self.server.bytes_out.increment(result)
return result
except SSL.SSL_ReadWrite_Retry_Error, which:
if which[0] == SSL.SSL_ERROR_WANT_READ:
self._ssl_writable = None
self._ssl_readable = 1
return 0
except SSL.SSLError, why:
self.close()
self.log_info('send: closing channel %s %s' % (repr(self), why))
return 0
- Added a new method '_send_buffered':
def _send_buffered(self, data):
try:
result = self.socket._write_nbio(data)
if result <= 0:
return 0
else:
self.server.bytes_out.increment(result)
return result
except SSL.SSL_ReadWrite_Retry_Error, which:
if which[0] == SSL.SSL_ERROR_WANT_READ:
self._ssl_writable = None
self._ssl_readable = 1
return -1
except SSL.SSLError, why:
self.close()
self.log_info('send: closing channel %s %s' % (repr(self), why))
return -1
- Add the necessary assignment 'self._wbuf = None' in the class's __init__
method.
(BTW, Heikki, are you the one who added the
"except SSL.SSL_ReadWrite_Retry_Error" stuff?)
Now, if you are using blocking sockets, then this will be a very curious
situation, because, for the longest time, in SWIG/_ssl.i's bio_set_ssl():
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
which supposedly means that OpenSSL will retry automatically without
bothering the application.
Cheers.
--
Ng Pheng Siong <ngps at netmemetic.com>
http://sandbox.rulemaker.net/ngps -+- M2Crypto, ZServerSSL for Zope, Blog
http://www.sqlcrypt.com -+- Database Engine with Transparent AES Encryption
More information about the python-crypto
mailing list