X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Futil%2Fxmlrpcprotocol.py;h=25e7b76d7e2ca7c90e6d23d7aef87d72ade30ed1;hb=0f57e9a45ec399ae3157f48aa7db7921706315f3;hp=afba6f3b34d63bea6bd258404f8bcc91fd50c3fb;hpb=d72c0aac21d66f4cec8f51c8a41f0abd77e905a7;p=sfa.git diff --git a/sfa/util/xmlrpcprotocol.py b/sfa/util/xmlrpcprotocol.py index afba6f3b..25e7b76d 100644 --- a/sfa/util/xmlrpcprotocol.py +++ b/sfa/util/xmlrpcprotocol.py @@ -1,7 +1,9 @@ # XMLRPC-specific code for SFA Client import xmlrpclib - +#from sfa.util.httpsProtocol import HTTPS, HTTPSConnection +from httplib import HTTPS, HTTPSConnection +from sfa.util.sfalogging import logger ## # ServerException, ExceptionUnmarshaller # @@ -23,22 +25,51 @@ class ExceptionUnmarshaller(xmlrpclib.Unmarshaller): # # A transport for XMLRPC that works on top of HTTPS +# python 2.7 xmlrpclib has changed its internal code +# it now calls 'getresponse' on the obj returned by make_connection +# while it used to call 'getreply' +# regardless of the version, httplib.HTTPS does implement getreply, +# while httplib.HTTPSConnection has getresponse +# so we create a dummy instance to check what's expected +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 - import httplib host, extra_headers, x509 = self.get_host_info(host) - try: - HTTPS = httplib.HTTPS() - except AttributeError: - raise NotImplementedError( - "your version of httplib doesn't support HTTPS" - ) + if need_HTTPSConnection: + #conn = HTTPSConnection(host, None, key_file=self.key_file, cert_file=self.cert_file, timeout=self.timeout) #**(x509 or {})) + conn = HTTPSConnection(host, None, key_file=self.key_file, cert_file=self.cert_file) #**(x509 or {})) else: - return httplib.HTTPS(host, None, key_file=self.key_file, cert_file=self.cert_file) #**(x509 or {})) + #conn = HTTPS(host, None, key_file=self.key_file, cert_file=self.cert_file, timeout=self.timeout) #**(x509 or {})) + conn = HTTPS(host, None, key_file=self.key_file, cert_file=self.cert_file) #**(x509 or {})) + + if hasattr(conn, 'set_timeout'): + conn.set_timeout(self.timeout) + + # Some logic to deal with timeouts. It appears that some (or all) versions + # of python don't set the timeout after the socket is created. We'll do it + # ourselves by forcing the connection to connect, finding the socket, and + # calling settimeout() on it. (tested with python 2.6) + if self.timeout: + if hasattr(conn, "_conn"): + # HTTPS is a wrapper around HTTPSConnection + real_conn = conn._conn + else: + real_conn = conn + conn.connect() + if hasattr(real_conn, "sock") and hasattr(real_conn.sock, "settimeout"): + real_conn.sock.settimeout(float(self.timeout)) + + return conn def getparser(self): unmarshaller = ExceptionUnmarshaller() @@ -46,23 +77,16 @@ class XMLRPCTransport(xmlrpclib.Transport): return parser, unmarshaller class XMLRPCServerProxy(xmlrpclib.ServerProxy): - def __init__(self, url, transport, allow_none=True, options=None): - self.options = options - verbose = False - if self.options and self.options.debug: - verbose = True + def __init__(self, url, transport, allow_none=True, verbose=False): + # remember url for GetVersion + self.url=url xmlrpclib.ServerProxy.__init__(self, url, transport, allow_none=allow_none, verbose=verbose) def __getattr__(self, attr): - if self.options and self.options.verbose: - print "Calling xml-rpc method:", 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)