diff options
author | Tim Laszlo <tim.laszlo@gmail.com> | 2010-07-26 15:30:46 +0000 |
---|---|---|
committer | Sol Jerome <sol.jerome@gmail.com> | 2010-07-30 11:53:15 -0500 |
commit | bf3fe01ce7c139e1afe8b6addc8cd4c6c819c4a9 (patch) | |
tree | 6e0148e90c47336f5017807afd9c7536c156675a | |
parent | d74aa12c9d3d92c405aaacb5a3bfd265b017879f (diff) | |
download | bcfg2-bf3fe01ce7c139e1afe8b6addc8cd4c6c819c4a9.tar.gz bcfg2-bf3fe01ce7c139e1afe8b6addc8cd4c6c819c4a9.tar.bz2 bcfg2-bf3fe01ce7c139e1afe8b6addc8cd4c6c819c4a9.zip |
SSLServer: Retry failed writes
Fixes an issue where a client can no longer connect to the server
after dropping a connection without properly terminating the ssl
connection.
git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@5991 ce84e21b-d406-0410-9b95-82705330c041
-rw-r--r-- | src/lib/SSLServer.py | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/src/lib/SSLServer.py b/src/lib/SSLServer.py index fe28203d3..ed8e5e405 100644 --- a/src/lib/SSLServer.py +++ b/src/lib/SSLServer.py @@ -221,16 +221,45 @@ class XMLRPCRequestHandler (SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): data = ''.join(L) response = self.server._marshaled_dispatch(self.client_address, data) except: - raise - self.send_response(500) - self.end_headers() + try: + self.send_response(500) + self.end_headers() + except: + (type, msg) = sys.exc_info()[:2] + self.logger.error("Error sending 500 response (%s): %s" % \ + (type, msg)) + raise else: # got a valid XML RPC response - self.send_response(200) - self.send_header("Content-type", "text/xml") - self.send_header("Content-length", str(len(response))) - self.end_headers() - self.wfile.write(response) + try: + self.send_response(200) + self.send_header("Content-type", "text/xml") + self.send_header("Content-length", str(len(response))) + self.end_headers() + failcount = 0 + while True: + try: + # If we hit SSL3_WRITE_PENDING here try to resend. + self.wfile.write(response) + break + except ssl.SSLError, e: + if str(e).find("SSL3_WRITE_PENDING") < 0: + raise + self.logger.error("SSL3_WRITE_PENDING") + failcount += 1 + if failcount < 5: + continue + raise + except: + (type, msg) = sys.exc_info()[:2] + if str(type) == 'socket.error' and msg[0] == 32: + self.logger.warning("Connection dropped from %s" % self.client_address[0]) + elif str(type) == 'socket.error' and msg[0] == 104: + self.logger.warning("Connection reset by peer: %s" % self.client_address[0]) + else: + self.logger.error("Error sending response (%s): %s" % \ + (type, msg)) + raise def finish(self): # shut down the connection |