diff options
author | Kenneth Anthony Giusti <kgiusti@apache.org> | 2013-05-22 18:46:56 +0000 |
---|---|---|
committer | Kenneth Anthony Giusti <kgiusti@apache.org> | 2013-05-22 18:46:56 +0000 |
commit | 7f8dc70b43e82d68ef93219b8a98f928161baf43 (patch) | |
tree | 481d9242acbb08fb1ba604b189dcd764ecf4c1c0 | |
parent | 9287d0deaf8cc05c323c6c06415352c75f27528c (diff) | |
download | qpid-python-7f8dc70b43e82d68ef93219b8a98f928161baf43.tar.gz |
QPID-4872: when retrying ssl reads or writes, use previous arguments
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1485331 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | python/qpid/messaging/transports.py | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/python/qpid/messaging/transports.py b/python/qpid/messaging/transports.py index c76db1f395..3751aa1d77 100644 --- a/python/qpid/messaging/transports.py +++ b/python/qpid/messaging/transports.py @@ -139,6 +139,11 @@ else: self.socket.setblocking(0) self.state = None + # See qpid-4872: need to store the parameters last passed to + # tls.recv_into() and tls.write() in case the calls fail with an + # SSL_ERROR_WANT_* error and we have to retry the call. + self.write_retry = None # buffer passed to last call of tls.write() + self.read_retry = None # buffer passed to last call of tls.recv_into() def reading(self, reading): if self.state is None: @@ -153,24 +158,41 @@ else: return self.state == SSL_ERROR_WANT_WRITE def send(self, bytes): + if self.write_retry is None: + self.write_retry = bytes self._clear_state() try: - return self.tls.write(bytes) + n = self.tls.write( self.write_retry ) + self.write_retry = None + return n except SSLError, e: if self._update_state(e.args[0]): + # will retry on next invokation return 0 - else: - raise + self.write_retry = None + raise + except: + self.write_retry = None + raise def recv(self, n): + if self.read_retry == None: + self.read_retry = bytearray( n ) self._clear_state() try: - return self.tls.read(n) + n = self.tls.recv_into( self.read_retry ) + r = str(self.read_retry[:n]) + self.read_retry = None + return r except SSLError, e: if self._update_state(e.args[0]): + # will retry on next invokation return None - else: - raise + self.read_retry = None + raise + except: + self.read_retry = None + raise def _clear_state(self): self.state = None |