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' % namespaces.ns_soap_env: raise Fault('Client.SoapError', 'No {%s}Envelope element was found!' % namespaces.ns_soap_env) header_envelope = in_envelope_xml.xpath('e:Header', namespaces={'e': namespaces.ns_soap_env}) body_envelope = in_envelope_xml.xpath('e:Body', namespaces={'e': namespaces.ns_soap_env}) if len(header_envelope) == 0 and len(body_envelope) == 0: raise Fault('Client.SoapError', 'Soap envelope is empty!' % namespaces.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
def handle_request(self): if self.is_wsdl(): return self.get_wsdl() try: resp_comp = self.parse_soap_request() self.request.response.setStatus(resp_comp.resp_code) self.request.response['Content-Type'] = "text/xml; charset=utf-8" return resp_comp.xml_response except TypeError as te: te_fault = Fault(faultcode="Client", faultstring=te.message, faultactor="Client")
def deserialize_soap(self, ctx, wrapper, envelope_xml, xmlids=None): """Takes a MethodContext instance and a string containing ONE soap message. Returns the corresponding native python object Not meant to be overridden. """ assert wrapper in (Application.IN_WRAPPER, Application.OUT_WRAPPER), wrapper # this sets the ctx.in_body_xml and ctx.in_header_xml properties self.decompose_incoming_envelope(ctx, envelope_xml, xmlids) if ctx.in_body_xml.tag == "{%s}Fault" % namespaces.ns_soap_env: in_body = Fault.from_xml(ctx.in_body_xml) 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 wrapper is Application.IN_WRAPPER: header_class = descriptor.in_header body_class = descriptor.in_message elif wrapper is Application.OUT_WRAPPER: header_class = descriptor.out_header body_class = descriptor.out_message # decode header object if (ctx.in_header_xml is not None and len(ctx.in_header_xml) > 0 and header_class is not None): ctx.service.in_header = header_class.from_xml( ctx.in_header_xml) # decode method arguments if ctx.in_body_xml is not None and len(ctx.in_body_xml) > 0: in_body = body_class.from_xml(ctx.in_body_xml) else: in_body = [None] * len(body_class._type_info) return in_body
def deserialize_soap(self, ctx, wrapper, envelope_xml, xmlids=None): """Takes a MethodContext instance and a string containing ONE soap message. Returns the corresponding native python object Not meant to be overridden. """ assert wrapper in (Application.IN_WRAPPER, Application.OUT_WRAPPER),wrapper # this sets the ctx.in_body_xml and ctx.in_header_xml properties self.decompose_incoming_envelope(ctx, envelope_xml, xmlids) if ctx.in_body_xml.tag == "{%s}Fault" % namespaces.ns_soap_env: in_body = Fault.from_xml(ctx.in_body_xml) 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 wrapper is Application.IN_WRAPPER: header_class = descriptor.in_header body_class = descriptor.in_message elif wrapper is Application.OUT_WRAPPER: header_class = descriptor.out_header body_class = descriptor.out_message # decode header object if (ctx.in_header_xml is not None and len(ctx.in_header_xml) > 0 and header_class is not None): ctx.service.in_header = header_class.from_xml(ctx.in_header_xml) # decode method arguments if ctx.in_body_xml is not None and len(ctx.in_body_xml) > 0: in_body = body_class.from_xml(ctx.in_body_xml) else: in_body = [None] * len(body_class._type_info) return in_body
def GetSitesXml(self, site, authToken): try: siteArg = ','.join(str(s) for s in site) siteResponse = self.wof_inst.create_get_site_response(siteArg) outStream = StringIO.StringIO() siteResponse.export(outStream, 0, name_="sitesResponse", namespacedef_=NSDEF) return (outStream.getvalue()).replace('\n', '') except Exception as inst: if type(inst) == Fault: raise inst else: raise Fault(faultstring=str(inst))
def GetValuesObject(self, location, variable, startDate, endDate): try: timeSeriesResponse = self.wof_inst.create_get_values_response( location, variable, startDate, endDate) outStream = StringIO.StringIO() timeSeriesResponse.export(outStream, 0, name_="timeSeriesResponse", namespacedef_=NSDEF) return outStream.getvalue() except Exception as inst: if type(inst) == Fault: raise inst else: raise Fault(faultstring=str(inst))
def GetVariableInfoObject(self, variable, authToken): try: variableInfoResponse = \ self.wof_inst.create_get_variable_info_response(variable) outStream = StringIO.StringIO() variableInfoResponse.export(outStream, 0, name_="variablesResponse", namespacedef_=NSDEF) return outStream.getvalue() except Exception as inst: if type(inst) == Fault: raise inst else: raise Fault(faultstring=str(inst))
def index_html(self, REQUEST, RESPONSE): """Handle an incoming SOAP request or a non-SOAP WSDL query.""" if REQUEST.get('SOAPXML', None) == None: # Not a SOAP Request, return WSDL return self.service_description(REQUEST, RESPONSE) try: # Deserialize the Body of the SOAP Request from soaplib.core._base import _from_soap header, payload = _from_soap(REQUEST.SOAPXML) # TODO: At this point I need dispatch method calls to the soaplib.Application # somehow....... :) ctx = MethodContext() content_type = cgi.parse_header(REQUEST.get("Content-Type")) charset = content_type[1].get('charset', None) length = REQUEST.get("Content-Length") http_payload = REQUEST.read(int(length)) if not charset: charset = "ascii" in_string = collapse_swa(content_type, http_payload) in_obj = self.soap_handler.get_in_object(ctx, in_string, charset) out_obj = self.soap_handler.get_out_object(ctx, in_obj) out_string = self.soap_handler.get_out_string(ctx, out_obj) return out_string except Exception, e: fault = Fault(faultstring=str(e)) resp = etree.tostring(fault, encoding=string_encoding) RESPONSE.setStatus('InternalServerError', reason=faultstring) RESPONSE.setHeader('Content-Type', 'text/xml') return resp
def decompose_incoming_envelope(self, ctx, envelope_xml, xmlids=None): header, body = _from_soap(envelope_xml, xmlids) # FIXME: find a way to include soap env schema with soaplib package and # properly validate the whole request. if len(body) > 0 and body.tag == '{%s}Fault' % namespaces.ns_soap_env: ctx.in_body_xml = body elif not (body is None): try: self.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.get_service_class(ctx.method_name) except Exception, e: logger.debug(traceback.format_exc()) raise ValidationError('Client', 'Method not found: %r' % ctx.method_name)
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)) # implementation hook if isinstance(retval, Fault): ctx.service.on_method_exception_object(retval) self.on_exception_object(retval) else: ctx.service.on_method_return_object(retval) return retval def serialize_soap(self, ctx, wrapper, out_object): """Takes a MethodContext instance and the object to be serialied. Returns the corresponding xml structure as an lxml.etree._Element instance.
def soap_exception(self): raise Fault("Plausible", "A plausible fault", 'Fault actor', detail=etree.Element('something'))