1 # XMLRPC-specific code for SFA Client
3 # starting with 2.7.9 we need to turn off server verification
5 try: turn_off_server_verify = { 'context' : ssl._create_unverified_context() }
6 except: turn_off_server_verify = {}
9 from httplib import HTTPS, HTTPSConnection
12 from sfa.util.sfalogging import logger
15 logger = logging.getLogger('sfaserverproxy')
18 # ServerException, ExceptionUnmarshaller
20 # Used to convert server exception strings back to an exception.
21 # from usenet, Raghuram Devarakonda
23 class ServerException(Exception):
26 class ExceptionUnmarshaller(xmlrpclib.Unmarshaller):
29 return xmlrpclib.Unmarshaller.close(self)
30 except xmlrpclib.Fault, e:
31 raise ServerException(e.faultString)
36 # A transport for XMLRPC that works on top of HTTPS
38 # targetting only python-2.7 we can get rid of some older code
40 class XMLRPCTransport(xmlrpclib.Transport):
42 def __init__(self, key_file = None, cert_file = None, timeout = None):
43 xmlrpclib.Transport.__init__(self)
45 self.key_file = key_file
46 self.cert_file = cert_file
48 def make_connection(self, host):
49 # create a HTTPS connection object from a host descriptor
50 # host may be a string, or a (host, x509-dict) tuple
51 host, extra_headers, x509 = self.get_host_info(host)
52 conn = HTTPSConnection(host, None, key_file = self.key_file,
53 cert_file = self.cert_file,
54 **turn_off_server_verify)
56 # Some logic to deal with timeouts. It appears that some (or all) versions
57 # of python don't set the timeout after the socket is created. We'll do it
58 # ourselves by forcing the connection to connect, finding the socket, and
59 # calling settimeout() on it. (tested with python 2.6)
61 if hasattr(conn, 'set_timeout'):
62 conn.set_timeout(self.timeout)
64 if hasattr(conn, "_conn"):
65 # HTTPS is a wrapper around HTTPSConnection
66 real_conn = conn._conn
70 if hasattr(real_conn, "sock") and hasattr(real_conn.sock, "settimeout"):
71 real_conn.sock.settimeout(float(self.timeout))
76 unmarshaller = ExceptionUnmarshaller()
77 parser = xmlrpclib.ExpatParser(unmarshaller)
78 return parser, unmarshaller
80 class XMLRPCServerProxy(xmlrpclib.ServerProxy):
81 def __init__(self, url, transport, allow_none=True, verbose=False):
82 # remember url for GetVersion
83 # xxx not sure this is still needed as SfaServerProxy has this too
85 xmlrpclib.ServerProxy.__init__(self, url, transport, allow_none=allow_none,
87 **turn_off_server_verify)
89 def __getattr__(self, attr):
90 logger.debug ("xml-rpc %s method:%s" % (self.url, attr))
91 return xmlrpclib.ServerProxy.__getattr__(self, attr)
93 ########## the object on which we can send methods that get sent over xmlrpc
96 def __init__ (self, url, keyfile, certfile, verbose=False, timeout=None):
98 self.keyfile = keyfile
99 self.certfile = certfile
100 self.verbose = verbose
101 self.timeout = timeout
102 # an instance of xmlrpclib.ServerProxy
103 transport = XMLRPCTransport(keyfile, certfile, timeout)
104 self.serverproxy = XMLRPCServerProxy(url, transport, allow_none=True, verbose=verbose)
106 # this is python magic to return the code to run when
107 # SfaServerProxy receives a method call
108 # so essentially we send the same method with identical arguments
109 # to the server_proxy object
110 def __getattr__(self, name):
111 def func(*args, **kwds):
112 return getattr(self.serverproxy, name)(*args, **kwds)