Changeset 0a47d52


Ignore:
Timestamp:
Jul 1, 2008 10:39:43 AM (16 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
Children:
bb3769a
Parents:
329f61d
Message:

XMLRPC proxy from SOAP and XML

Location:
fedd
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd.py

    r329f61d r0a47d52  
    4343    def send_fault(self, f, code=500):
    4444        """Send a SOAP encoded fault as reply"""
    45         self.send_xml(f.AsSOAP(), code)
     45        self.send_xml(f.AsSOAP(processContents="lax"), code)
    4646
    4747    def check_headers(self, ps):
     
    7272            ps = ParsedSoap(data)
    7373        except ParseException, e:
    74             self.send_fault(FaultFromZSIException(e))
     74            self.send_fault(Fault(Fault.Client, str(e)))
    7575            return
    7676        except Exception, e:
     
    108108        resp = None
    109109        data = None
     110        method = None
    110111        cl = int(self.headers['content-length'])
    111112        data = self.rfile.read(cl)
    112         params, method = xmlrpclib.loads(data)
    113113
    114114        try:
    115             resp = self.server.impl.xmlrpc_dispatch(method, params,
    116                         fedid(cert=self.request.get_peer_cert()))
    117             data = xmlrpclib.dumps((resp,), methodresponse=True)
    118         except Fault, f:
    119             xf = xmlrpclib.Fault(f.code, f.string)
    120             data = xmlrpclib.dumps(xf, methodresponse=True)
    121             resp = None
    122         except xmlrpclib.Fault, f:
    123             data = xmlrpclib.dumps(f, methodresponse=True)
    124             resp = None
    125 
     115            params, method = xmlrpclib.loads(data)
     116        except xmlrpclib.ResponseError:
     117            data = xmlrpclib.dumps(xmlrpclib.Fault("Client",
     118                "Malformed request"), methodresponse=True)
     119       
     120        if method != None:
     121            try:
     122                resp = self.server.impl.xmlrpc_dispatch(method, params,
     123                            fedid(cert=self.request.get_peer_cert()))
     124                data = xmlrpclib.dumps((resp,), methodresponse=True)
     125            except Fault, f:
     126                xf = xmlrpclib.Fault(f.code, f.string)
     127                data = xmlrpclib.dumps(xf, methodresponse=True)
     128                resp = None
     129            except xmlrpclib.Fault, f:
     130                data = xmlrpclib.dumps(f, methodresponse=True)
     131                resp = None
    126132        self.send_xml(data)
    127133
  • fedd/fedd_client.py

    r329f61d r0a47d52  
    289289    try:
    290290        resp = port.RequestAccess(req)
     291    except ZSI.ParseException, e:
     292        sys.exit("Malformed response (XMLPRC?): %s" % e)
    291293    except ZSI.FaultException, e:
    292294        sys.exit("Fault: %s" % e)
  • fedd/fedd_proj.py

    r329f61d r0a47d52  
    66from ZSI import *
    77from M2Crypto import SSL
     8from M2Crypto.m2xmlrpclib import SSL_Transport
    89from M2Crypto.SSL.SSLServer import SSLServer
    910import M2Crypto.httpslib
     
    1516import subprocess
    1617import tempfile
     18import copy
    1719
    1820from fedd_services import *
     
    228230        os.unlink(projfile)
    229231
    230     def proxy_request(self, dt, req):
    231         """
    232         Send req on to the real destination in dt and return the response
    233 
    234         Req is just the requestType object.  This function re-wraps it.  It
    235         also rethrows any faults.
    236         """
     232   
     233    def strip_unicode(self, obj):
     234        """Loosly de-unicode an object"""
     235        if isinstance(obj, dict):
     236            for k in obj.keys():
     237                obj[k] = self.strip_unicode(obj[k])
     238            return obj
     239        elif isinstance(obj, basestring):
     240            return str(obj)
     241        elif getattr(obj, "__iter__", None):
     242            return [ self.strip_unicode(x) for x in obj]
     243        else:
     244            return obj
     245
     246    def proxy_xmlrpc_request(self, dt, req):
     247        """Send an XMLRPC proxy request.  Called if the SOAP RPC fails"""
    237248        tc = self.proxy_trusted_certs or self.trusted_certs
    238249
     
    244255            raise Fault(Fault.Server, "Server certificates misconfigured")
    245256
     257        # Of all the dumbass things.  The XMLRPC library in use here won't
     258        # properly encode unicode strings, so we make a copy of req with the
     259        # unicode objects converted.  We also convert the destination testbed
     260        # to a basic string if it isn't one already.
     261        if isinstance(dt, str): url = dt
     262        else: url = str(dt)
     263
     264        r = copy.deepcopy(req)
     265        self.strip_unicode(r)
     266       
     267        transport = SSL_Transport(ctx)
     268        port = xmlrpclib.ServerProxy(url, transport=transport)
     269
     270        # Reconstruct the full request message
     271        try:
     272            resp = port.RequestAccess(
     273                    { "RequestAccessRequestBody": r})
     274            resp, method = xmlrpclib.loads(resp)
     275        except xmlrpclib.Error, e:
     276            raise Fault(Fault.Server, "Remote XMLRPC Fault: %s" % e)
     277       
     278        if resp[0].has_key('RequestAccessResponseBody'):
     279            return resp[0]['RequestAccessResponseBody']
     280        else:
     281            raise Fault(Fault.Server, "Bad proxy response")
     282
     283    def proxy_request(self, dt, req):
     284        """
     285        Send req on to the real destination in dt and return the response
     286
     287        Req is just the requestType object.  This function re-wraps it.  It
     288        also rethrows any faults.
     289        """
     290        tc = self.proxy_trusted_certs or self.trusted_certs
     291
     292        # No retry loop here.  Proxy servers must correctly authenticate
     293        # themselves without help
     294        try:
     295            ctx = fedd_ssl_context(self.cert_file, tc, password=self.cert_pwd)
     296        except SSL.SSLError:
     297            raise Fault(Fault.Server, "Server certificates misconfigured")
     298
    246299        loc = feddServiceLocator();
    247300        port = loc.getfeddPortType(dt,
     
    255308        try:
    256309            resp = port.RequestAccess(msg)
     310        except ZSI.ParseException, e:
     311            raise Fault(Fault.Server, "Bad format message (XMLRPC??): %s" %
     312                    str(e))
    257313        except ZSI.FaultException, e:
    258314            raise e.fault
     
    423479            dt = unpack_id(req['destinationTestbed'])
    424480       
    425         print dt
    426 
    427481        if dt == None or dt == self.testbed:
    428482            # Request for this fedd
     
    454508            return resp
    455509        else:
    456             # Proxy the request
    457             return self.proxy_request(dt, req)
     510            p_fault = None      # Any SOAP failure (sent unless XMLRPC works)
     511            try:
     512                # Proxy the request using SOAP
     513                return self.proxy_request(dt, req)
     514            except Fault, f:
     515                p_fault = f
     516         
     517           
     518            # This runs if SOAP failed
     519            try:
     520                return self.proxy_xmlrpc_request(dt, req)
     521            except Fault:
     522                # Both failed, return the SOAP error.  If somehow that
     523                # exception is gone, return the XMLRPC one
     524                if p_fault != None: raise p_fault
     525                else: raise
    458526
    459527    def soap_RequestAccess(self, ps, fid):
  • fedd/fedd_util.py

    r329f61d r0a47d52  
    211211            sub = getattr(element, m)()
    212212            if sub != None:
    213                 rv[n] = unpack_soap(sub)
     213                if isinstance(sub, basestring):
     214                    rv[n] = sub
     215                elif getattr(sub, "__iter__", None) != None:
     216                    if len(sub) > 0: rv[n] = [unpack_soap(e) for e in sub]
     217                else:
     218                    rv[n] = unpack_soap(sub)
    214219        return rv
    215     elif getattr(element, "__iter__", None) != None:
    216         return [unpack_soap(e) for e in element]
    217220    else:
    218         return element;
     221        return element
Note: See TracChangeset for help on using the changeset viewer.