Пример #1
0
def _from_soap(in_envelope_xml, xmlids=None):
    '''
    Parses the xml string into the header and payload
    '''

    if xmlids:
        resolve_hrefs(in_envelope_xml, xmlids)

    if in_envelope_xml.tag != '{%s}Envelope' % rpclib.ns_soap_env:
        raise Fault('Client.SoapError',
                    'No {%s}Envelope element was found!' % rpclib.ns_soap_env)

    header_envelope = in_envelope_xml.xpath(
        'e:Header', namespaces={'e': rpclib.ns_soap_env})
    body_envelope = in_envelope_xml.xpath('e:Body',
                                          namespaces={'e': rpclib.ns_soap_env})

    if len(header_envelope) == 0 and len(body_envelope) == 0:
        raise Fault('Client.SoapError',
                    'Soap envelope is empty!' % rpclib.ns_soap_env)

    header = None
    if len(header_envelope) > 0 and len(header_envelope[0]) > 0:
        header = header_envelope[0].getchildren()[0]

    body = None
    if len(body_envelope) > 0 and len(body_envelope[0]) > 0:
        body = body_envelope[0].getchildren()[0]

    return header, body
Пример #2
0
    def deserialize(self, ctx):
        """Takes a MethodContext instance and a string containing ONE soap
        message.
        Returns the corresponding native python object

        Not meant to be overridden.
        """

        if ctx.in_body_doc.tag == "{%s}Fault" % ns.soap_env:
            ctx.in_object = None
            ctx.in_error = Fault.from_xml(ctx.in_body_doc)

        else:
            # retrieve the method descriptor
            if ctx.method_name is None:
                raise Exception("Could not extract method name from the request!")
            if ctx.descriptor is None:
                ctx.descriptor = ctx.service_class.get_method(ctx.method_name)

            if self.in_wrapper is self.IN_WRAPPER:
                header_class = ctx.descriptor.in_header
                body_class = ctx.descriptor.in_message

            elif self.in_wrapper is self.OUT_WRAPPER:
                header_class = ctx.descriptor.out_header
                body_class = ctx.descriptor.out_message

            # decode header objects
            if (ctx.in_header_doc is not None and header_class is not None):
                if isinstance(header_class, (list, tuple)):
                    headers = [None] * len(header_class)
                    for i, (header_doc, head_class) in enumerate(zip(ctx.in_header_doc, header_class)):
                        if len(header_doc) > 0:
                            headers[i] = head_class.from_xml(header_doc)
                    ctx.in_header = tuple(headers)
                else:
                    header_doc = ctx.in_header_doc[0]
                    if len(header_doc) > 0:
                        ctx.in_header = header_class.from_xml(header_doc)

            # decode method arguments
            if ctx.in_body_doc is not None and len(ctx.in_body_doc) > 0:
                ctx.in_object = body_class.from_xml(ctx.in_body_doc)
            else:
                ctx.in_object = [None] * len(body_class._type_info)

        self.event_manager.fire_event('deserialize', ctx)
Пример #3
0
    def deserialize(self, ctx, doc_struct):
        """Takes a MethodContext instance and a string containing ONE soap
        message.
        Returns the corresponding native python object

        Not meant to be overridden.
        """

        # this sets the ctx.in_body_doc and ctx.in_header_doc properties
        self.decompose_incoming_envelope(ctx, doc_struct)

        if ctx.in_body_doc.tag == "{%s}Fault" % rpclib.ns_soap_env:
            in_body = Fault.from_xml(ctx.in_body_doc)

        else:
            # retrieve the method descriptor
            if ctx.method_name is None:
                raise Exception(
                    "Could not extract method name from the request!")
            else:
                if ctx.descriptor is None:
                    descriptor = ctx.descriptor = ctx.service.get_method(
                        ctx.method_name)
                else:
                    descriptor = ctx.descriptor

            if self.in_wrapper is self.IN_WRAPPER:
                header_class = descriptor.in_header
                body_class = descriptor.in_message

            elif self.in_wrapper is self.OUT_WRAPPER:
                header_class = descriptor.out_header
                body_class = descriptor.out_message

            # decode header object
            if ctx.in_header_doc is not None and len(ctx.in_header_doc) > 0:
                ctx.service.in_header = header_class.from_xml(
                    ctx.in_header_doc)

            # decode method arguments
            if ctx.in_body_doc is not None and len(ctx.in_body_doc) > 0:
                in_body = body_class.from_xml(ctx.in_body_doc)
            else:
                in_body = [None] * len(body_class._type_info)

        return in_body
Пример #4
0
    def deserialize(self, ctx, doc_struct):
        """Takes a MethodContext instance and a string containing ONE soap
        message.
        Returns the corresponding native python object

        Not meant to be overridden.
        """

        # this sets the ctx.in_body_doc and ctx.in_header_doc properties
        self.decompose_incoming_envelope(ctx, doc_struct)

        if ctx.in_body_doc.tag == "{%s}Fault" % rpclib.ns_soap_env:
            in_body = Fault.from_xml(ctx.in_body_doc)

        else:
            # retrieve the method descriptor
            if ctx.method_name is None:
                raise Exception("Could not extract method name from the request!")
            else:
                if ctx.descriptor is None:
                    descriptor = ctx.descriptor = ctx.service.get_method(
                                                                ctx.method_name)
                else:
                    descriptor = ctx.descriptor

            if self.in_wrapper is self.IN_WRAPPER:
                header_class = descriptor.in_header
                body_class = descriptor.in_message

            elif self.in_wrapper is self.OUT_WRAPPER:
                header_class = descriptor.out_header
                body_class = descriptor.out_message

            # decode header object
            if ctx.in_header_doc is not None and len(ctx.in_header_doc) > 0:
                ctx.service.in_header = header_class.from_xml(ctx.in_header_doc)

            # decode method arguments
            if ctx.in_body_doc is not None and len(ctx.in_body_doc) > 0:
                in_body = body_class.from_xml(ctx.in_body_doc)
            else:
                in_body = [None] * len(body_class._type_info)

        return in_body
Пример #5
0
    def decompose_incoming_envelope(self, ctx, envelope_doc):
        envelope_xml, xmlids = envelope_doc
        header, body = _from_soap(envelope_xml, xmlids)

        # FIXME: find a way to include soap env schema with rpclib package and
        # properly validate the whole request.

        if len(body) > 0 and body.tag == '{%s}Fault' % rpclib.ns_soap_env:
            ctx.in_body_doc = body

        elif not (body is None):
            try:
                self.parent.interface.validate(body)
                if (not (body is None)) and (ctx.method_name is None):
                    ctx.method_name = body.tag
                    logger.debug("\033[92mMethod name: %r\033[0m" %
                                 ctx.method_name)

            finally:
                # for performance reasons, we don't want the following to run
                # in production even though we won't see the results.
                if logger.level == logging.DEBUG:
                    try:
                        logger.debug(
                            etree.tostring(envelope_xml, pretty_print=True))
                    except etree.XMLSyntaxError, e:
                        logger.debug(body)
                        raise Fault(
                            'Client.Xml', 'Error at line: %d, '
                            'col: %d' % e.position)
            try:
                if ctx.service_class is None:  # i.e. if it's a server
                    ctx.service_class = self.parent.get_service_class(
                        ctx.method_name)

            except Exception, e:
                logger.debug(traceback.format_exc())
                raise ValidationError('Client',
                                      'Method not found: %r' % ctx.method_name)
Пример #6
0
 def soap_exception(self):
     raise Fault("Plausible",
                 "A plausible fault",
                 'Fault actor',
                 detail=etree.Element('something'))
Пример #7
0
class Application(object):
    transport = None

    def __init__(self,
                 services,
                 interface_class,
                 in_protocol_class,
                 out_protocol_class=None,
                 *args,
                 **kwargs):
        '''Constructor.

        @param An iterable of ServiceBase subclasses that define the exposed
               services.
        @param The targetNamespace attribute of the exposed service.
        @param The name attribute of the exposed service.
        '''

        if out_protocol_class is None:
            out_protocol_class = in_protocol_class

        self.interface = interface_class(self, services, *args, **kwargs)
        self.in_protocol = in_protocol_class(self)
        self.out_protocol = out_protocol_class(self)
        self.services = services

        self.__public_methods = {}
        self.__classes = {}

    def get_class(self, key):
        return self.interface.get_class(key)

    def get_class_instance(self, key):
        return self.interface.get_class_instance(key)

    def process_request(self, ctx, req_obj):
        """Takes a MethodContext instance and the native request object.
        Returns the response to the request as a native python object.

        Not meant to be overridden.
        """

        try:
            # implementation hook
            ctx.service.on_method_call(ctx.method_name, req_obj,
                                       ctx.in_body_doc)

            # retrieve the method
            func = getattr(ctx.service, ctx.descriptor.name)

            # call the method
            retval = ctx.service.call_wrapper(func, req_obj)

        except Fault, e:
            stacktrace = traceback.format_exc()
            logger.error(stacktrace)

            retval = e

        except Exception, e:
            stacktrace = traceback.format_exc()
            logger.error(stacktrace)

            retval = Fault('Server', str(e))