def __handle_wsdl_request(self, req_env, start_response, url): http_resp_headers = {'Content-Type': 'text/xml'} try: self.get_wsdl(url) self.on_wsdl(req_env, self.__wsdl) # implementation hook http_resp_headers['Content-Length'] = str(len(self.__wsdl)) start_response(HTTP_200, http_resp_headers.items()) return [self.__wsdl] except Exception, e: # implementation hook logger.error(traceback.format_exc()) tns = self.get_tns() fault_xml = Fault.to_xml(Fault(str(e)), tns) fault_str = etree.tostring(fault_xml, xml_declaration=True, encoding=string_encoding) if logger.level == logging.DEBUG: logger.debug(etree.tostring(etree.fromstring(fault_str),pretty_print=True)) self.on_wsdl_exception(req_env, e, fault_xml) http_resp_headers['Content-length'] = str(len(fault_str)) start_response(HTTP_500, http_resp_headers.items()) return [fault_str]
def test_soap_fault(self): ns_test = "test_namespace" fault = Fault("code", 'something happened', 'detail') fault_str = etree.tostring(make_soap_envelope(Fault.to_xml(fault,ns_test)), pretty_print=True) print fault_str fault = etree.fromstring(fault_str) self.assertTrue(fault.getchildren()[0].tag.endswith, 'Body') self.assertTrue( fault.getchildren()[0].getchildren()[0].tag.endswith('Fault')) f = fault.getchildren()[0].getchildren()[0] print etree.tostring(f,pretty_print=True) self.assertEquals(f.find('{%s}faultstring' % ns_test).text, 'something happened') self.assertEquals(f.find('{%s}faultcode' % ns_test).text, 'code') self.assertEquals(f.find('{%s}detail' % ns_test).text, 'detail')
def __handle_soap_request(self, req_env, start_response, url): """ This function is too big. """ http_resp_headers = { 'Content-Type': 'text/xml', 'Content-Length': '0', } method_name = None try: # implementation hook self.on_call(req_env) if req_env['REQUEST_METHOD'].lower() != 'post': http_resp_headers['Allow'] = 'POST' start_response(HTTP_405, http_resp_headers.items()) return [''] input = req_env.get('wsgi.input') length = req_env.get("CONTENT_LENGTH") body = input.read(int(length)) try: service = None soap_req_header, soap_req_payload = self.__decode_soap_request( req_env, body) if not (soap_req_payload is None): self.validate_request(soap_req_payload) method_name = self.__get_method_name(req_env, soap_req_payload) if method_name is None: resp = "Could not extract method name from the request!" http_resp_headers['Content-Length'] = str(len(resp)) start_response(HTTP_500, http_resp_headers.items()) return [resp] service_class = self.get_service_class(method_name) service = self.get_service(service_class, req_env) 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(etree.fromstring(body), pretty_print=True)) except etree.XMLSyntaxError,e: logger.debug(body) raise Fault('Client.XMLSyntax', 'Error at line: %d, col: %d' % e.position) # retrieve the method descriptor descriptor = service.get_method(method_name) func = getattr(service, descriptor.name) # decode header object if soap_req_header is not None and len(soap_req_header) > 0: in_header = descriptor.in_header service.soap_in_header = in_header.from_xml(soap_req_header) # decode method arguments if soap_req_payload is not None and len(soap_req_payload) > 0: params = descriptor.in_message.from_xml(soap_req_payload) else: params = [None] * len(descriptor.in_message._type_info) # implementation hook service.on_method_call(req_env, method_name, params, soap_req_payload) # call the method result_raw = service.call_wrapper(func, params) # construct the soap response, and serialize it envelope = etree.Element('{%s}Envelope' % soaplib.ns_soap_env, nsmap=soaplib.nsmap) # # header # soap_header_elt = etree.SubElement(envelope, '{%s}Header' % soaplib.ns_soap_env) if service.soap_out_header != None: if descriptor.out_header is None: logger.warning("Skipping soap response header as %r method " "is not published to have a soap response " "header" % method_name) else: descriptor.out_header.to_xml( service.soap_out_header, self.get_tns(), soap_header_elt, descriptor.out_header.get_type_name() ) if len(soap_header_elt) > 0: envelope.append(soap_header_elt) # # body # soap_body = etree.SubElement(envelope, '{%s}Body' % soaplib.ns_soap_env) # instantiate the result message result_message = descriptor.out_message() # assign raw result to its wrapper, result_message out_type = descriptor.out_message._type_info if len(out_type) > 0: if len(out_type) == 1: attr_name = descriptor.out_message._type_info.keys()[0] setattr(result_message, attr_name, result_raw) else: for i in range(len(out_type)): attr_name = descriptor.out_message._type_info.keys()[i] setattr(result_message, attr_name, result_raw[i]) # transform the results into an element descriptor.out_message.to_xml(result_message, self.get_tns(), soap_body) # implementation hook service.on_method_return(req_env, result_raw, soap_body, http_resp_headers) # # misc # results_str = etree.tostring(envelope, xml_declaration=True, encoding=string_encoding) if descriptor.mtom: http_resp_headers, results_str = apply_mtom(http_resp_headers, results_str, descriptor.out_message._type_info,[result_raw]) # implementation hook self.on_return(req_env, http_resp_headers, results_str) # initiate the response http_resp_headers['Content-Length'] = str(len(results_str)) start_response(HTTP_200, http_resp_headers.items()) if logger.level == logging.DEBUG: logger.debug('\033[91m'+ "Response" + '\033[0m') logger.debug(etree.tostring(envelope, xml_declaration=True, pretty_print=True)) # return the serialized results return [results_str]
if logger.level == logging.DEBUG: logger.debug('\033[91m'+ "Response" + '\033[0m') logger.debug(etree.tostring(envelope, xml_declaration=True, pretty_print=True)) # return the serialized results return [results_str] # The user issued a Fault, so handle it just like an exception! except Fault, e: return self.__handle_fault(req_env, start_response, http_resp_headers, service, e) except Exception, e: fault = Fault('Server', str(e)) return self.__handle_fault(req_env, start_response, http_resp_headers, service, fault) def __handle_fault(self, req_env, start_response, http_resp_headers, service, exc): stacktrace=traceback.format_exc() logger.error(stacktrace) # implementation hook if not (service is None): service.on_method_exception_object(req_env, exc) self.on_exception_object(req_env, exc) # FIXME: There's no way to alter soap response headers for the user.
def __handle_soap_request(self, req_env, start_response, url): http_resp_headers = { 'Content-Type': 'text/xml', 'Content-Length': '0', } method_name = None try: # implementation hook self.on_call(req_env) if req_env['REQUEST_METHOD'].lower() != 'post': http_resp_headers['Allow'] = 'POST' start_response(HTTP_405, http_resp_headers.items()) return [''] input = req_env.get('wsgi.input') length = req_env.get("CONTENT_LENGTH") body = input.read(int(length)) try: service = None soap_req_header, soap_req_payload = self.__decode_soap_request( req_env, body) self.validate_request(soap_req_payload) method_name = self.__get_method_name(req_env, soap_req_payload) if method_name is None: resp = "Could not get method name!" http_resp_headers['Content-Length'] = str(len(resp)) start_response(HTTP_500, http_resp_headers.items()) return [resp] service_class = self.get_service_class(method_name) service = self.get_service(service_class, req_env) finally: # for performance reasons, we don't want the following to run # in production even if we don't see the results. if logger.level == logging.DEBUG: try: logger.debug(etree.tostring(etree.fromstring(body), pretty_print=True)) except: logger.debug(body) raise # retrieve the method descriptor descriptor = service.get_method(method_name) func = getattr(service, descriptor.name) # decode header object if soap_req_header is not None and len(soap_req_header) > 0: service.soap_in_header = descriptor.in_header.from_xml(soap_req_header) # decode method arguments if soap_req_payload is not None and len(soap_req_payload) > 0: params = descriptor.in_message.from_xml(soap_req_payload) else: params = [None] * len(descriptor.in_message._type_info) # implementation hook service.on_method_call(req_env, method_name, params, soap_req_payload) # call the method result_raw = service.call_wrapper(func, params) # create result message result_message = descriptor.out_message() # assign raw result to its wrapper, result_message out_type = descriptor.out_message._type_info if len(out_type) > 0: assert len(out_type) == 1 attr_name = descriptor.out_message._type_info.keys()[0] setattr(result_message, attr_name, result_raw) # transform the results into an element # only expect a single element soap_resp_body = None if not (descriptor.is_async or descriptor.is_callback): soap_resp_body = descriptor.out_message.to_xml(result_message, self.get_tns()) soap_resp_header = None if not (descriptor.out_header is None or service.soap_out_header is None): soap_resp_header = descriptor.out_header.to_xml( service.soap_out_header, self.get_tns(), descriptor.out_header.get_type_name()) # implementation hook service.on_method_return(req_env, result_raw, soap_resp_body, http_resp_headers) # construct the soap response, and serialize it envelope = make_soap_envelope(soap_resp_header, soap_resp_body) results_str = etree.tostring(envelope, xml_declaration=True, encoding=string_encoding) if descriptor.mtom: http_resp_headers, results_str = apply_mtom(http_resp_headers, results_str,descriptor.out_message._type_info,[result_raw]) # implementation hook self.on_return(req_env, http_resp_headers, results_str) # initiate the response http_resp_headers['Content-Length'] = str(len(results_str)) start_response(HTTP_200, http_resp_headers.items()) if logger.level == logging.DEBUG: logger.debug('\033[91m'+ "Response" + '\033[0m') logger.debug(etree.tostring(envelope, xml_declaration=True, pretty_print=True)) # return the serialized results return [results_str] # The user issued a Fault, so handle it just like an exception! except Fault, e: stacktrace=traceback.format_exc() logger.error(stacktrace) # FIXME: There's no way to alter soap response headers for the user. soap_resp_header = None soap_resp_body = Fault.to_xml(e, self.get_tns()) fault_xml = make_soap_envelope(soap_resp_header, soap_resp_body) fault_str = etree.tostring(fault_xml, xml_declaration=True, encoding=string_encoding) if logger.level == logging.DEBUG: logger.debug(etree.tostring(etree.fromstring(fault_str), pretty_print=True)) # implementation hook if not (service is None): service.on_method_exception(req_env, e, fault_xml, fault_str) self.on_exception(req_env,e,fault_str) # initiate the response http_resp_headers['Content-Length'] = str(len(fault_str)) start_response(HTTP_500, http_resp_headers.items()) return [fault_str]
e.params={} faultstring = str(e) if method_name: faultcode = '%sFault' % method_name else: faultcode = 'Server' detail = ' ' logger.error(stacktrace) fault = Fault(faultcode, faultstring, detail) soap_resp_header = None soap_resp_body = Fault.to_xml(fault, self.get_tns()) fault_xml = make_soap_envelope(soap_resp_header, soap_resp_body) fault_str = etree.tostring(fault_xml, xml_declaration=True, encoding=string_encoding) if logger.level == logging.DEBUG: logger.debug(etree.tostring(etree.fromstring(fault_str), pretty_print=True)) # implementation hook if not (service is None): service.on_method_exception(req_env, e, fault_xml, fault_str) self.on_exception(req_env,e,fault_str) # initiate the response http_resp_headers['Content-Length'] = str(len(fault_str))