fix https timeout bug
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Thu, 4 Aug 2011 19:49:12 +0000 (15:49 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Thu, 4 Aug 2011 19:49:12 +0000 (15:49 -0400)
sfa/util/httpsProtocol.py [new file with mode: 0644]
sfa/util/xmlrpcprotocol.py

diff --git a/sfa/util/httpsProtocol.py b/sfa/util/httpsProtocol.py
new file mode 100644 (file)
index 0000000..a9d86ad
--- /dev/null
@@ -0,0 +1,32 @@
+import httplib
+import socket
+
+# wrapper around standartd https modules. Properly supports timeouts.  
+
+class HTTPSConnection(httplib.HTTPSConnection):
+    def __init__(self, host, port=None, key_file=None, cert_file=None,
+                 strict=None, timeout = None):
+        httplib.HTTPSConnection.__init__(self, host, port, key_file, cert_file, strict)
+        self.timeout = float(timeout)
+
+    def connect(self):
+        """Connect to a host on a given (SSL) port."""
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.settimeout(self.timeout)
+        sock.connect((self.host, self.port))
+        ssl = socket.ssl(sock, self.key_file, self.cert_file)
+        self.sock = httplib.FakeSocket(sock, ssl)
+
+class HTTPS(httplib.HTTPS):
+   def __init__(self, host='', port=None, key_file=None, cert_file=None,
+                     strict=None, timeout = None):
+        # urf. compensate for bad input.
+        if port == 0:
+            port = None
+        self._setup(HTTPSConnection(host, port, key_file, cert_file, strict, timeout))
+
+        # we never actually use these for anything, but we keep them
+        # here for compatibility with post-1.5.2 CVS.
+        self.key_file = key_file
+        self.cert_file = cert_file
+
index b5e9c01..c321406 100644 (file)
@@ -1,7 +1,7 @@
 # XMLRPC-specific code for SFA Client
 
-import httplib
 import xmlrpclib
+from sfa.util.httpsProtocol import HTTPS, HTTPSConnection
 
 from sfa.util.sfalogging import logger
 ##
@@ -34,16 +34,21 @@ class ExceptionUnmarshaller(xmlrpclib.Unmarshaller):
 need_HTTPSConnection=hasattr(xmlrpclib.Transport().make_connection('localhost'),'getresponse')
 
 class XMLRPCTransport(xmlrpclib.Transport):
-    key_file = None
-    cert_file = None
+    
+    def __init__(self, key_file=None, cert_file=None, timeout=None):
+        xmlrpclib.Transport.__init__(self)
+        self.timeout=timeout
+        self.key_file = key_file
+        self.cert_file = cert_file
+        
     def make_connection(self, host):
         # create a HTTPS connection object from a host descriptor
         # host may be a string, or a (host, x509-dict) tuple
         host, extra_headers, x509 = self.get_host_info(host)
         if need_HTTPSConnection:
-            return httplib.HTTPSConnection(host, None, key_file=self.key_file, cert_file=self.cert_file) #**(x509 or {}))
+            return HTTPSConnection(host, None, key_file=self.key_file, cert_file=self.cert_file, timeout=self.timeout) #**(x509 or {}))
         else:
-            return httplib.HTTPS(host, None, key_file=self.key_file, cert_file=self.cert_file) #**(x509 or {}))
+            return HTTPS(host, None, key_file=self.key_file, cert_file=self.cert_file, timeout=self.timeout) #**(x509 or {}))
 
     def getparser(self):
         unmarshaller = ExceptionUnmarshaller()
@@ -51,23 +56,16 @@ class XMLRPCTransport(xmlrpclib.Transport):
         return parser, unmarshaller
 
 class XMLRPCServerProxy(xmlrpclib.ServerProxy):
-    def __init__(self, url, transport, allow_none=True, options=None):
+    def __init__(self, url, transport, allow_none=True, verbose=False):
         # remember url for GetVersion
         self.url=url
-        verbose = False
-        if options and options.debug:
-            verbose = True
         xmlrpclib.ServerProxy.__init__(self, url, transport, allow_none=allow_none, verbose=verbose)
 
     def __getattr__(self, attr):
         logger.debug ("xml-rpc %s method:%s"%(self.url,attr))
         return xmlrpclib.ServerProxy.__getattr__(self, attr)
 
-
-def get_server(url, key_file, cert_file, options=None):
-    transport = XMLRPCTransport()
-    transport.key_file = key_file
-    transport.cert_file = cert_file
-
-    return XMLRPCServerProxy(url, transport, allow_none=True, options=options)
+def get_server(url, key_file, cert_file, timeout=None, verbose=False):
+    transport = XMLRPCTransport(key_file, cert_file, timeout)
+    return XMLRPCServerProxy(url, transport, allow_none=True, verbose=verbose)