#! /usr/bin/env python # $Header$ '''Simple CGI dispatching. ''' from pysphere.ZSI import TC import base64, os from pysphere.ZSI import ZSI_SCHEMA_URI _b64_decode = base64.decodestring # Typecode to parse a ZSI BasicAuth header. _auth_tc = TC.Struct(None, [ TC.String('Name'), TC.String('Password') ], extras=1) class AUTH: '''Constants for authentication mechanisms. ''' none = 0 httpbasic = 1 zsibasic = 2 httpdigest = 4 class ClientBinding: '''Information about the client that is connected to us. ''' def __init__(self, ps): self.ps, self.auth = \
def call_closure(*args, **kwargs): """Call the named remote web service method.""" if len(args) and len(kwargs): raise TypeError('Use positional or keyword argument only.') if len(args) > 0: raise TypeError('Not supporting SOAPENC:Arrays or XSD:List') if len(kwargs): args = kwargs callinfo = getattr(self, name).callinfo # go through the list of defined methods, and look for the one with # the same number of arguments as what was passed. this is a weak # check that should probably be improved in the future to check the # types of the arguments to allow for polymorphism for method in self._methods[name]: if len(method.callinfo.inparams) == len(kwargs): callinfo = method.callinfo binding = _Binding(url=self._url or callinfo.location, soapaction=callinfo.soapAction, **self._kw) kw = dict(unique=True) if callinfo.use == 'encoded': kw['unique'] = False if callinfo.style == 'rpc': request = TC.Struct(None, ofwhat=[], pname=(callinfo.namespace, name), **kw) response = TC.Struct(None, ofwhat=[], pname=(callinfo.namespace, name+"Response"), **kw) if len(callinfo.getInParameters()) != len(args): raise RuntimeError('expecting "%s" parts, got %s' %( str(callinfo.getInParameters(), str(args)))) for msg,pms in ((request,callinfo.getInParameters()), (response,callinfo.getOutParameters())): msg.ofwhat = [] for part in pms: klass = GTD(*part.type) if klass is None: if part.type: klass = [gt for gt in TC.TYPES if part.type==gt.type] if len(klass) == 0: klass = [gt for gt in TC.TYPES if part.type[1]==gt.type[1]] if not len(klass):klass = [TC.Any] if len(klass) > 1: #Enumerations, XMLString, etc klass = [i for i in klass if 'type' in i.__dict__] klass = klass[0] else: klass = TC.Any msg.ofwhat.append(klass(part.name)) msg.ofwhat = tuple(msg.ofwhat) if not args: args = {} else: # Grab <part element> attribute ipart,opart = callinfo.getInParameters(),callinfo.getOutParameters() if ( len(ipart) != 1 or not ipart[0].element_type or ipart[0].type is None ): raise RuntimeError('Bad Input Message "%s"' %callinfo.name) if ( len(opart) not in (0,1) or not opart[0].element_type or opart[0].type is None ): raise RuntimeError('Bad Output Message "%s"' %callinfo.name) # if ( len(args) > 1 ): # raise RuntimeError, 'Message has only one part: %s' %str(args) ipart = ipart[0] request,response = GED(*ipart.type),None if opart: response = GED(*opart[0].type) msg = args if self._asdict: if not msg: msg = dict() self._nullpyclass(request) elif request.pyclass is not None: if type(args) is dict: msg = request.pyclass() msg.__dict__.update(args) elif type(args) is list and len(args) == 1: msg = request.pyclass(args[0]) else: msg = request.pyclass() binding.Send(None, None, msg, requesttypecode=request, soapheaders=soapheaders, encodingStyle=callinfo.encodingStyle) if response is None: return None if self._asdict: self._nullpyclass(response) return binding.Receive(replytype=response, encodingStyle=callinfo.encodingStyle)