def test_xml_dumps(): """ Test the `ipalib.rpc.xml_dumps` function. """ f = rpc.xml_dumps params = (binary_bytes, utf8_bytes, unicode_str, None) # Test serializing an RPC request: data = f(params, API_VERSION, 'the_method') (p, m) = loads(data) assert_equal(m, u'the_method') assert type(p) is tuple assert rpc.xml_unwrap(p) == params # Test serializing an RPC response: data = f((params, ), API_VERSION, methodresponse=True) (tup, m) = loads(data) assert m is None assert len(tup) == 1 assert type(tup) is tuple assert rpc.xml_unwrap(tup[0]) == params # Test serializing an RPC response containing a Fault: fault = Fault(69, unicode_str) data = f(fault, API_VERSION, methodresponse=True) e = raises(Fault, loads, data) assert e.faultCode == 69 assert_equal(e.faultString, unicode_str)
def render_POST(self, request): request.content.seek(0, 0) request.setHeader("content-type", "text/xml") try: if self.useDateTime: args, functionPath = xmlrpclib.loads(request.content.read(), use_datetime=True) else: # Maintain backwards compatibility with Python < 2.5 args, functionPath = xmlrpclib.loads(request.content.read()) except Exception as e: f = Fault(self.FAILURE, "Can't deserialize input: %s" % (e,)) self._cbRender(f, request) else: try: function = self.lookupProcedure(functionPath) except Fault as f: self._cbRender(f, request) else: # Use this list to track whether the response has failed or not. # This will be used later on to decide if the result of the # Deferred should be written out and Request.finish called. responseFailed = [] request.notifyFinish().addErrback(responseFailed.append) if getattr(function, 'withRequest', False): d = defer.maybeDeferred(function, request, *args) else: d = defer.maybeDeferred(function, *args) d.addErrback(self._ebRender) d.addCallback(self._cbRender, request, responseFailed) return server.NOT_DONE_YET
def test_xml_dumps(): """ Test the `ipalib.rpc.xml_dumps` function. """ f = rpc.xml_dumps params = (binary_bytes, utf8_bytes, unicode_str, None) # Test serializing an RPC request: data = f(params, API_VERSION, 'the_method') (p, m) = loads(data) assert_equal(m, u'the_method') assert type(p) is tuple assert rpc.xml_unwrap(p) == params # Test serializing an RPC response: data = f((params,), API_VERSION, methodresponse=True) (tup, m) = loads(data) assert m is None assert len(tup) == 1 assert type(tup) is tuple assert rpc.xml_unwrap(tup[0]) == params # Test serializing an RPC response containing a Fault: fault = Fault(69, unicode_str) data = f(fault, API_VERSION, methodresponse=True) e = raises(Fault, loads, data) assert e.faultCode == 69 assert_equal(e.faultString, unicode_str)
def test_dump_bare_datetime(self): # This checks that an unwrapped datetime.date object can be handled # by the marshalling code. This can't be done via test_dump_load() # since with use_builtin_types set to 1 the unmarshaller would create # datetime objects for the 'datetime[123]' keys as well dt = datetime.datetime(2005, 2, 10, 11, 41, 23) self.assertEqual(dt, xmlrpclib.DateTime('20050210T11:41:23')) s = xmlrpclib.dumps((dt, )) result, m = xmlrpclib.loads(s, use_builtin_types=True) (newdt, ) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), datetime.datetime) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_builtin_types=False) (newdt, ) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), xmlrpclib.DateTime) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_datetime=True) (newdt, ) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), datetime.datetime) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_datetime=False) (newdt, ) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), xmlrpclib.DateTime) self.assertIsNone(m)
def test_dump_bare_datetime(self): # This checks that an unwrapped datetime.date object can be handled # by the marshalling code. This can't be done via test_dump_load() # since with use_builtin_types set to 1 the unmarshaller would create # datetime objects for the 'datetime[123]' keys as well dt = datetime.datetime(2005, 2, 10, 11, 41, 23) self.assertEqual(dt, xmlrpclib.DateTime('20050210T11:41:23')) s = xmlrpclib.dumps((dt,)) result, m = xmlrpclib.loads(s, use_builtin_types=True) (newdt,) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), datetime.datetime) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_builtin_types=False) (newdt,) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), xmlrpclib.DateTime) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_datetime=True) (newdt,) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), datetime.datetime) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_datetime=False) (newdt,) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), xmlrpclib.DateTime) self.assertIsNone(m)
def render_POST(self, request): request.content.seek(0, 0) request.setHeader("content-type", "text/xml") try: if self.useDateTime: args, functionPath = xmlrpclib.loads(request.content.read(), use_datetime=True) else: # Maintain backwards compatibility with Python < 2.5 args, functionPath = xmlrpclib.loads(request.content.read()) except Exception as e: f = Fault(self.FAILURE, "Can't deserialize input: %s" % (e, )) self._cbRender(f, request) else: try: function = self.lookupProcedure(functionPath) except Fault as f: self._cbRender(f, request) else: # Use this list to track whether the response has failed or not. # This will be used later on to decide if the result of the # Deferred should be written out and Request.finish called. responseFailed = [] request.notifyFinish().addErrback(responseFailed.append) if getattr(function, 'withRequest', False): d = defer.maybeDeferred(function, request, *args) else: d = defer.maybeDeferred(function, *args) d.addErrback(self._ebRender) d.addCallback(self._cbRender, request, responseFailed) return server.NOT_DONE_YET
def test_datetime_before_1900(self): # same as before but with a date before 1900 dt = datetime.datetime(1, 2, 10, 11, 41, 23) s = xmlrpclib.dumps((dt,)) (newdt,), m = xmlrpclib.loads(s, use_datetime=1) self.assertEqual(newdt, dt) self.assertEqual(m, None) (newdt,), m = xmlrpclib.loads(s, use_datetime=0) self.assertEqual(newdt, xmlrpclib.DateTime('00010210T11:41:23'))
def test_datetime_before_1900(self): # same as before but with a date before 1900 dt = datetime.datetime(1, 2, 10, 11, 41, 23) s = xmlrpclib.dumps((dt, )) (newdt, ), m = xmlrpclib.loads(s, use_datetime=1) self.assertEqual(newdt, dt) self.assertEqual(m, None) (newdt, ), m = xmlrpclib.loads(s, use_datetime=0) self.assertEqual(newdt, xmlrpclib.DateTime('00010210T11:41:23'))
def test_dump_bare_datetime(self): # This checks that an unwrapped datetime.date object can be handled # by the marshalling code. This can't be done via test_dump_load() # since with use_datetime set to 1 the unmarshaller would create # datetime objects for the 'datetime[123]' keys as well dt = datetime.datetime(2005, 2, 10, 11, 41, 23) s = xmlrpclib.dumps((dt, )) (newdt, ), m = xmlrpclib.loads(s, use_datetime=1) self.assertEqual(newdt, dt) self.assertEqual(m, None) (newdt, ), m = xmlrpclib.loads(s, use_datetime=0) self.assertEqual(newdt, xmlrpclib.DateTime('20050210T11:41:23'))
def test_dump_encoding(self): value = '\u20ac' strg = xmlrpclib.dumps((value,), encoding='iso-8859-15') strg = "<?xml version='1.0' encoding='iso-8859-15'?>" + strg self.assertEqual(xmlrpclib.loads(strg)[0][0], value) strg = strg.encode('iso-8859-15') self.assertEqual(xmlrpclib.loads(strg)[0][0], value) strg = xmlrpclib.dumps((value,), encoding='iso-8859-15', methodresponse=True) self.assertEqual(xmlrpclib.loads(strg)[0][0], value) strg = strg.encode('iso-8859-15') self.assertEqual(xmlrpclib.loads(strg)[0][0], value)
def test_dump_bare_datetime(self): # This checks that an unwrapped datetime.date object can be handled # by the marshalling code. This can't be done via test_dump_load() # since with use_datetime set to 1 the unmarshaller would create # datetime objects for the 'datetime[123]' keys as well dt = datetime.datetime(2005, 2, 10, 11, 41, 23) s = xmlrpclib.dumps((dt,)) (newdt,), m = xmlrpclib.loads(s, use_datetime=1) self.assertEqual(newdt, dt) self.assertEqual(m, None) (newdt,), m = xmlrpclib.loads(s, use_datetime=0) self.assertEqual(newdt, xmlrpclib.DateTime('20050210T11:41:23'))
def test_datetime_before_1900(self): dt = datetime.datetime(1, 2, 10, 11, 41, 23) self.assertEqual(dt, xmlrpclib.DateTime('00010210T11:41:23')) s = xmlrpclib.dumps((dt, )) result, m = xmlrpclib.loads(s, use_builtin_types=True) newdt, = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), datetime.datetime) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_builtin_types=False) newdt, = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), xmlrpclib.DateTime) self.assertIsNone(m)
def _marshaled_dispatch(self, data, dispatch_method = None): """Dispatches an XML-RPC method from marshalled (XML) data. XML-RPC methods are dispatched from the marshalled (XML) data using the _dispatch method and the result is returned as marshalled data. For backwards compatibility, a dispatch function can be provided as an argument (see comment in SimpleXMLRPCRequestHandler.do_POST) but overriding the existing method through subclassing is the prefered means of changing method dispatch behavior. """ params, method = xmlrpc_client.loads(data) # generate response try: if dispatch_method is not None: response = dispatch_method(method, params) else: response = self._dispatch(method, params) # wrap response in a singleton tuple response = (response,) response = xmlrpc_client.dumps(response, methodresponse=1) except Fault as fault: response = xmlrpc_client.dumps(fault) except: # report exception back to server ftb = self.debug and '\n'+str(traceback.format_tb(sys.exc_info()[2])) or '' response = xmlrpc_client.dumps( xmlrpc_client.Fault(1, "%s:%s%s" % (sys.exc_info()[0], sys.exc_info()[1],ftb)) ) return response
def handle(self) -> Union[Response, tuple]: """ Handle a FastRPC request, returns Flask response """ accept_cts = self._get_accepted_content_types() if not accept_cts.intersection(self.allowed_content_types): logging.warning('No supported content type requested: "%s"', accept_cts) return 'Content types in Accept not supported', 400 if request.headers['Content-Type'] not in self.allowed_content_types: logging.warning('Content-Type "%s" is not supported', request.headers['Content-Type']) return 'Content-Type not supported', 400 if fastrpc: if FRPC_CONTENT_TYPE == request.headers['Content-Type']: # We will be loading binary data, which is sent through chunked transfer encoding - not very friendly. # Werkzeug doesn't recognize the header, so the data should be in request.stream BUT # since chunked transfer encoding isn't sending Content-Length header, as it does not make sense, # werkzeug needs some kind of middleware that handles it. In ideal world, we could use stream # because the middleware would set request.environ['wsgi.input_terminated'] - I found none that do that # which means for now we'll be supporting just uwsgi until I figure out how to do with with the others # like gunicorn etc. big TODO ! if uwsgi is None: raise NotImplementedError("This application needs to be running on uWSGI, I'm sorry! TODO :) ") request_data = uwsgi.chunked_read() else: request_data = request.data args, method_name = fastrpc.loads(request_data) else: args, method_name = xmlrpc.loads(request.data) logging.info('Calling method %s with args: %s', method_name, args) return self._create_response(method_name, args, accept_cts)
def test_dump_none(self): value = alist + [None] arg1 = (alist + [None],) strg = xmlrpclib.dumps(arg1, allow_none=True) self.assertEqual(value, xmlrpclib.loads(strg)[0][0]) self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
def parse_input(data): """Parse input data and return a method path and argument tuple The data is a string. """ # # For example, with the input: # # <?xml version="1.0"?> # <methodCall> # <methodName>examples.getStateName</methodName> # <params> # <param> # <value><i4>41</i4></value> # </param> # </params> # </methodCall> # # the function should return: # # ('examples.getStateName', (41,)) params, method = xmlrpclib.loads(data) # Translate '.' to '/' in meth to represent object traversal. method = method.replace('.', '/') return method, params
def parse_request(self, request_body): try: params, method_name = xmlrpclib.loads(request_body) except: # Bad request formatting, bad. return self.faults.parse_error() return ((method_name, params),)
def check_loads(self, s, value, **kwargs): dump = '<params><param><value>%s</value></param></params>' % s result, m = xmlrpclib.loads(dump, **kwargs) newvalue, = result self.assertEqual(newvalue, value) self.assertIs(type(newvalue), type(value)) self.assertIsNone(m)
def parse_request(self, request_body): try: params, method_name = xmlrpclib.loads(request_body) except: # Bad request formatting, bad. return self.faults.parse_error() return ((method_name, params), )
def send_rpc(self, cmd, in_fd, out_fd, *args, **kwargs): xml = _xmlrpc_client.dumps(sum(kwargs.items(), args), cmd) self._debug_fn( "calling ikiwiki procedure `{0}': [{1}]".format(cmd, repr(xml))) # ensure that encoded is a str (bytestring in Python 2, Unicode in 3) if str is bytes and not isinstance(xml, str): encoded = xml.encode('utf8') else: encoded = xml _IkiWikiExtPluginXMLRPCHandler._write(out_fd, encoded) self._debug_fn('reading response from ikiwiki...') response = _IkiWikiExtPluginXMLRPCHandler._read(in_fd) if str is bytes and not isinstance(response, str): xml = response.encode('utf8') else: xml = response self._debug_fn( 'read response to procedure {0} from ikiwiki: [{1}]'.format( cmd, repr(xml))) if xml is None: # ikiwiki is going down self._debug_fn('ikiwiki is going down, and so are we...') raise GoingDown() data = _xmlrpc_client.loads(xml)[0][0] self._debug_fn( 'parsed data from response to procedure {0}: [{1}]'.format( cmd, repr(data))) return data
def process_body(): """Return (params, method) from request body.""" try: from xmlrpc import client return client.loads(cherrypy.request.body.read()) except Exception: return ('ERROR PARAMS', ), 'ERRORMETHOD'
def test_bug_1164912(self): d = xmlrpclib.DateTime() (new_d, ), dummy = xmlrpclib.loads( xmlrpclib.dumps((d, ), methodresponse=True)) self.assertIsInstance(new_d.value, str) s = xmlrpclib.dumps((new_d, ), methodresponse=True) self.assertIsInstance(s, str)
def test_dump_bytes(self): sample = b'my dog has fleas' self.assertEqual(sample, xmlrpclib.Binary(sample)) for type_ in (bytes, bytearray, xmlrpclib.Binary): value = type_(sample) s = xmlrpclib.dumps((value, )) result, m = xmlrpclib.loads(s, use_builtin_types=True) newvalue, = result self.assertEqual(newvalue, sample) self.assertIs(type(newvalue), bytes) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_builtin_types=False) newvalue, = result self.assertEqual(newvalue, sample) self.assertIs(type(newvalue), xmlrpclib.Binary) self.assertIsNone(m)
def wsgi_xmlrpc(environ, start_response): """ Two routes are available for XML-RPC /xmlrpc/<service> route returns faultCode as strings. This is a historic violation of the protocol kept for compatibility. /xmlrpc/2/<service> is a new route that returns faultCode as int and is therefore fully compliant. """ if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith( '/xmlrpc/'): length = int(environ['CONTENT_LENGTH']) data = environ['wsgi.input'].read(length) # Distinguish betweed the 2 faultCode modes string_faultcode = True if environ['PATH_INFO'].startswith('/xmlrpc/2/'): service = environ['PATH_INFO'][len('/xmlrpc/2/'):] string_faultcode = False else: service = environ['PATH_INFO'][len('/xmlrpc/'):] params, method = xmlrpclib.loads(data) return xmlrpc_return(start_response, service, method, params, string_faultcode)
def server_view(request, root='/'): ''' Server view handling pingback requests. Include this view in your urlconf under any path you like and provide a link to this URL in your HTML: <link rel="pingback" href="..."/> Or send it in an HTTP server header: X-Pingback: ... The optional parameter "root" sets a root path within which server will consider incoming target URLs as its own. ''' try: args, method = loads(request.raw_post_data) if method != 'pingback.ping': raise errors.Error('Unknown method "%s"' % method) _handle_pingback(request, root, *args) result = dumps(('OK', ), methodresponse=True) except Fault as fault: result = dumps(fault) except Exception as e: result = dumps(errors.Error(str(e))) return http.HttpResponse(result)
def _marshaled_dispatch(self, data, dispatch_method = None, path = None): """Dispatches an XML-RPC method from marshalled (XML) data. XML-RPC methods are dispatched from the marshalled (XML) data using the _dispatch method and the result is returned as marshalled data. For backwards compatibility, a dispatch function can be provided as an argument (see comment in SimpleXMLRPCRequestHandler.do_POST) but overriding the existing method through subclassing is the preferred means of changing method dispatch behavior. """ try: params, method = loads(data, use_builtin_types=self.use_builtin_types) # generate response if dispatch_method is not None: response = dispatch_method(method, params) else: response = self._dispatch(method, params) # wrap response in a singleton tuple response = (response,) response = dumps(response, methodresponse=1, allow_none=self.allow_none, encoding=self.encoding) except Fault as fault: response = dumps(fault, allow_none=self.allow_none, encoding=self.encoding) except BaseException as exc: response = dumps( Fault(1, "%s:%s" % (type(exc), exc)), encoding=self.encoding, allow_none=self.allow_none, ) return response.encode(self.encoding, 'xmlcharrefreplace')
def wsgi_xmlrpc(environ, start_response): """ Two routes are available for XML-RPC /xmlrpc/<service> route returns faultCode as strings. This is a historic violation of the protocol kept for compatibility. /xmlrpc/2/<service> is a new route that returns faultCode as int and is therefore fully compliant. """ if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith('/xmlrpc/'): length = int(environ['CONTENT_LENGTH']) data = environ['wsgi.input'].read(length) # Distinguish betweed the 2 faultCode modes string_faultcode = True service = environ['PATH_INFO'][len('/xmlrpc/'):] if environ['PATH_INFO'].startswith('/xmlrpc/2/'): service = service[len('2/'):] string_faultcode = False params, method = xmlrpclib.loads(data) try: result = odoo.http.dispatch_rpc(service, method, params) response = xmlrpclib.dumps((result,), methodresponse=1, allow_none=False) except Exception as e: if string_faultcode: response = xmlrpc_handle_exception_string(e) else: response = xmlrpc_handle_exception_int(e) return werkzeug.wrappers.Response( response=response, mimetype='text/xml', )(environ, start_response)
def test_nil(self): body = FauxInstance(public=None) faux = FauxResponse() response = self._makeOne(faux) response.setBody(body) data, method = xmlrpclib.loads(faux._body) self.assert_(data[0]['public'] is None)
async def listen(self): """ Listen to socket. """ try: while True: head = await self.reader.readexactly(8) size, handle = struct.unpack_from('<LL', head) body = await self.reader.readexactly(size) data = method = fault = None try: data, method = loads(body, use_builtin_types=True) except Fault as e: fault = e except ExpatError as e: # See #121 for this solution. handle_exception(exception=e, module_name=__name__, func_name='listen', extra_data={'body': body}) continue if data and len(data) == 1: data = data[0] self.event_loop.create_task(self.handle_payload(handle, method, data, fault)) except ConnectionResetError as e: logger.critical( 'Connection with the dedicated server has been closed, we will now close down the subprocess! {}'.format(str(e)) ) # When the connection has been reset, we will close the controller process so it can be restarted by the god # process. Exit code 10 gives the information to the god process. exit(10) except Exception as e: handle_exception(exception=e, module_name=__name__, func_name='listen') raise
def _marshaled_dispatch(self, data, dispatch_method=None, path=None): """Dispatches an XML-RPC method from marshalled (XML) data. XML-RPC methods are dispatched from the marshalled (XML) data using the _dispatch method and the result is returned as marshalled data. For backwards compatibility, a dispatch function can be provided as an argument (see comment in SimpleXMLRPCRequestHandler.do_POST) but overriding the existing method through subclassing is the preferred means of changing method dispatch behavior. """ try: params, method = loads(data, use_builtin_types=self.use_builtin_types) # generate response if dispatch_method is not None: response = dispatch_method(method, params) else: response = self._dispatch(method, params) # wrap response in a singleton tuple response = (response,) response = dumps(response, methodresponse=1, allow_none=self.allow_none, encoding=self.encoding) except Fault as fault: response = dumps(fault, allow_none=self.allow_none, encoding=self.encoding) except: # report exception back to server exc_type, exc_value, exc_tb = sys.exc_info() response = dumps( Fault(1, "%s:%s" % (exc_type, exc_value)), encoding=self.encoding, allow_none=self.allow_none ) return response.encode(self.encoding)
def server_view(request, root='/'): ''' Server view handling pingback requests. Include this view in your urlconf under any path you like and provide a link to this URL in your HTML: <link rel="pingback" href="..."/> Or send it in an HTTP server header: X-Pingback: ... The optional parameter "root" sets a root path within which server will consider incoming target URLs as its own. ''' try: args, method = xmlrpcclient.loads(request.raw_post_data) if method != 'pingback.ping': raise errors.Error('Unknown method "%s"' % method) _handle_pingback(request, root, *args) result = xmlrpcclient.dumps(('OK',), methodresponse=True) except xmlrpcclient.Fault as fault: result = xmlrpcclient.dumps(fault) except Exception as e: result = xmlrpcclient.dumps(errors.Error(str(e))) return http.HttpResponse(result)
def _marshaled_dispatch(self, data, dispatch_method=None): """override SimpleXMLRPCDispatcher._marshaled_dispatch() fault string""" try: import xmlrpc.client as client from xmlrpc.client import Fault except ImportError: import xmlrpclib as client from xmlrpclib import Fault params, method = client.loads(data) # generate response try: if dispatch_method is not None: response = dispatch_method(method, params) else: response = self._dispatch(method, params) # wrap response in a singleton tuple response = (response, ) response = client.dumps(response, methodresponse=1) except Fault as fault: # breaks 2.5 compatibility fault.faultString = print_exc_info() response = client.dumps(fault) except: # report exception back to server response = client.dumps(client.Fault(1, "\n%s" % print_exc_info())) return _b(response)
def send_rpc(self, cmd, in_fd, out_fd, *args, **kwargs): xml = _xmlrpc_client.dumps(sum(kwargs.items(), args), cmd) self._debug_fn("calling ikiwiki procedure `{0}': [{1}]".format( cmd, repr(xml))) # ensure that encoded is a str (bytestring in Python 2, Unicode in 3) if str is bytes and not isinstance(xml, str): encoded = xml.encode('utf8') else: encoded = xml _IkiWikiExtPluginXMLRPCHandler._write(out_fd, encoded) self._debug_fn('reading response from ikiwiki...') response = _IkiWikiExtPluginXMLRPCHandler._read(in_fd) if str is bytes and not isinstance(response, str): xml = response.encode('utf8') else: xml = response self._debug_fn( 'read response to procedure {0} from ikiwiki: [{1}]'.format( cmd, repr(xml))) if xml is None: # ikiwiki is going down self._debug_fn('ikiwiki is going down, and so are we...') raise GoingDown() data = _xmlrpc_client.loads(xml)[0][0] self._debug_fn( 'parsed data from response to procedure {0}: [{1}]'.format( cmd, repr(data))) return data
def test_nil(self): body = FauxInstance(public=None) faux = FauxResponse() response = self._makeOne(faux) response.setBody(body) data, method = xmlrpclib.loads(faux._body) self.assertIs(data[0]['public'], None)
def do_POST(self): """ Access point from HTTP handler """ def onParent(pid, fromchild, tochild): self._server._registerChild(pid, fromchild) tochild.write(_b('done\n')) tochild.flush() def onChild(pid, fromparent, toparent): try: response = self._server._marshaled_dispatch(data) self._sendResponse(response) line = _str(fromparent.readline()) toparent.write(_b('done\n')) toparent.flush() except: logger(name='pathos.xmlrpc', level=30).error(print_exc_info()) os._exit(0) try: data = self.rfile.read(int(self.headers['content-length'])) params, method = client.loads(data) if method == 'run': #XXX: _str? return spawn2(onParent, onChild) else: response = self._server._marshaled_dispatch(data) self._sendResponse(response) return except: self._debug.error(print_exc_info()) self.send_response(500) self.end_headers() return
def handler(req): # Only accept POST requests if req.method != 'POST': req.content_type = 'text/plain' req.send_http_header() req.write("Not valid XML-RPC POST request") return apache.OK # Fetch the request body = req.read() # Prepare response req.content_type = "text/xml" req.send_http_header() # Process request try: args, method = loads(body) except: fault = Fault(0x001, "Invalid XML-RPC error") req.write(dumps(fault, methodresponse=1)) return apache.OK # Execute it. The calling function is # responsive for responding to the request. Dispatch(req, method, args) return apache.OK
def _marshaled_dispatch(self, data, dispatch_method=None): """override SimpleXMLRPCDispatcher._marshaled_dispatch() fault string""" try: import xmlrpc.client as client from xmlrpc.client import Fault except ImportError: import xmlrpclib as client from xmlrpclib import Fault params, method = client.loads(data) # generate response try: if dispatch_method is not None: response = dispatch_method(method, params) else: response = self._dispatch(method, params) # wrap response in a singleton tuple response = (response,) response = client.dumps(response, methodresponse=1) except Fault as fault: # breaks 2.5 compatibility fault.faultString = print_exc_info() response = client.dumps(fault) except: # report exception back to server response = client.dumps( client.Fault(1, "\n%s" % print_exc_info()) ) return _b(response)
def wsgi_xmlrpc(environ, start_response): """ Two routes are available for XML-RPC /xmlrpc/<service> route returns faultCode as strings. This is a historic violation of the protocol kept for compatibility. /xmlrpc/2/<service> is a new route that returns faultCode as int and is therefore fully compliant. """ if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith('/xmlrpc/'): length = int(environ['CONTENT_LENGTH']) data = environ['wsgi.input'].read(length) # Distinguish betweed the 2 faultCode modes string_faultcode = True service = environ['PATH_INFO'][len('/xmlrpc/'):] if environ['PATH_INFO'].startswith('/xmlrpc/2/'): service = service[len('2/'):] string_faultcode = False params, method = xmlrpclib.loads(data) try: result = flectra.http.dispatch_rpc(service, method, params) response = xmlrpclib.dumps((result,), methodresponse=1, allow_none=False) except Exception as e: if string_faultcode: response = xmlrpc_handle_exception_string(e) else: response = xmlrpc_handle_exception_int(e) return werkzeug.wrappers.Response( response=response, mimetype='text/xml', )(environ, start_response)
async def execute(self, method, *args): payload = dumps(args, methodname=method, allow_none=True) body = gzip.compress(payload.encode('utf8')) try: res = await self.loop.run_in_executor(None, self.__request, body) data, _ = loads(res.text, use_datetime=True) if isinstance(data, (tuple, list)) and len(data) > 0 and len(data[0]) > 0: if isinstance(data[0][0], dict) and 'faultCode' in data[0][0]: raise DedimaniaFault(faultCode=data[0][0]['faultCode'], faultString=data[0][0]['faultString']) self.retries = 0 return data[0] raise DedimaniaTransportException('Invalid response from dedimania!') except (ConnectionError, ReadTimeout, ConnectionRefusedError, requests.exceptions.ConnectionError) as e: raise DedimaniaTransportException(e) from e except ConnectTimeout as e: raise DedimaniaTransportException(e) from e except DedimaniaTransportException: # Try to setup new session. self.retries += 1 if self.retries > 5: raise DedimaniaTransportException('Dedimania didn\'t gave the right answer after few retries!') self.client = requests.session() try: await self.authenticate() return await self.execute(method, *args) except Exception as e: logger.error('XML-RPC Fault retrieved from Dedimania: {}'.format(str(e))) handle_exception(e, __name__, 'execute') raise DedimaniaTransportException('Could not retrieve data from dedimania!') except DedimaniaFault as e: if 'Bad SessionId' in e.faultString or ('SessionId' in e.faultString and 'not found' in e.faultString): try: self.retries += 1 if self.retries > 5: raise DedimaniaTransportException('Max retries reached for reauthenticating with dedimania!') # Save original session ID. original_session_id = '{}'.format(self.session_id) # Reauthenticate await self.authenticate() # Replace session_id in args. if len(args) > 0 and len(args[0]) > 0 and isinstance(args[0][0], dict) and 'params' in args[0][0]: new_params = list(args[0][0]['params']) if (new_params and isinstance(new_params[0], str) and new_params[0] == original_session_id): new_params[0] = self.session_id args[0][0]['params'] = tuple(new_params) # Try again. return await self.execute(method, *args) except: return logger.error('XML-RPC Fault retrieved from Dedimania: {}'.format(str(e))) handle_exception(e, __name__, 'execute', extra_data={ 'dedimania_retries': self.retries, }) raise DedimaniaTransportException('Could not retrieve data from dedimania!')
def test_dump_fault(self): f = xmlrpclib.Fault(42, 'Test Fault') s = xmlrpclib.dumps((f, )) (newf, ), m = xmlrpclib.loads(s) self.assertEqual(newf, {'faultCode': 42, 'faultString': 'Test Fault'}) self.assertEqual(m, None) s = xmlrpclib.Marshaller().dumps(f) self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, s)
def _get_response(self, params, method): xmlparm = xmlrpclib.dumps(params, method) req = urllib2.Request('https://pypi.python.org/pypi', xmlparm.encode('utf-8'), {'Content-Type': 'text/xml'}) data = urllib2.urlopen(req, timeout=1).read() xml = xmlrpclib.loads(data)[0][0] return xml
def call_FUT(app, method, params): xml = xmlrpclib.dumps(params, methodname=method).encode('utf-8') print(xml) resp = app.post('/RPC2', content_type='text/xml', params=xml) assert resp.status_int == 200 assert resp.content_type == 'text/xml' print(resp.body) return xmlrpclib.loads(resp.body)[0][0]
def test_newstyle_class(self): class T(object): pass t = T() t.x = 100 t.y = "Hello" ((t2,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((t,))) self.assertEqual(t2, t.__dict__)
def test_datetime_before_1900(self): # same as before but with a date before 1900 dt = datetime.datetime(1, 2, 10, 11, 41, 23) self.assertEqual(dt, xmlrpclib.DateTime('00010210T11:41:23')) s = xmlrpclib.dumps((dt,)) result, m = xmlrpclib.loads(s, use_builtin_types=True) (newdt,) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), datetime.datetime) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_builtin_types=False) (newdt,) = result self.assertEqual(newdt, dt) self.assertIs(type(newdt), xmlrpclib.DateTime) self.assertIsNone(m)
def test_bug_1164912(self): d = xmlrpclib.DateTime() ((new_d,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((d,), methodresponse=True)) self.assertIsInstance(new_d.value, str) # Check that the output of dumps() is still an 8-bit string s = xmlrpclib.dumps((new_d,), methodresponse=True) self.assertIsInstance(s, str)
def test_dump_fault(self): f = xmlrpclib.Fault(42, "Test Fault") s = xmlrpclib.dumps((f,)) (newf,), m = xmlrpclib.loads(s) self.assertEqual(newf, {"faultCode": 42, "faultString": "Test Fault"}) self.assertEqual(m, None) s = xmlrpclib.Marshaller().dumps(f) self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, s)
def test_dump_fault(self): f = xmlrpclib.Fault(42, 'Test Fault') s = xmlrpclib.dumps((f,)) (newf,), m = xmlrpclib.loads(s) self.assertEqual(newf, {'faultCode': 42, 'faultString': 'Test Fault'}) self.assertEqual(m, None) s = xmlrpclib.Marshaller().dumps(f) self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, s)
def test_dump_bytes(self): sample = b"my dog has fleas" self.assertEqual(sample, xmlrpclib.Binary(sample)) for type_ in bytes, bytearray, xmlrpclib.Binary: value = type_(sample) s = xmlrpclib.dumps((value,)) result, m = xmlrpclib.loads(s, use_builtin_types=True) (newvalue,) = result self.assertEqual(newvalue, sample) self.assertIs(type(newvalue), bytes) self.assertIsNone(m) result, m = xmlrpclib.loads(s, use_builtin_types=False) (newvalue,) = result self.assertEqual(newvalue, sample) self.assertIs(type(newvalue), xmlrpclib.Binary) self.assertIsNone(m)
def test_bug_1164912(self): d = xmlrpclib.DateTime() ((new_d, ), dummy) = xmlrpclib.loads(xmlrpclib.dumps((d, ), methodresponse=True)) self.assertIsInstance(new_d.value, str) # Check that the output of dumps() is still an 8-bit string s = xmlrpclib.dumps((new_d, ), methodresponse=True) self.assertIsInstance(s, str)
def test_instance(self): # Instances are turned into dicts with their private # attributes removed. body = FauxInstance(_secret='abc', public='def') faux = FauxResponse() response = self._makeOne(faux) response.setBody(body) data, method = xmlrpclib.loads(faux._body) data = data[0] self.assertEqual(data, {'public': 'def'})
def test_zopedatetimeattribute(self): # DateTime instance as attribute body = FauxInstance(public=DateTime('2006-05-24 07:00:00 GMT+0')) faux = FauxResponse() response = self._makeOne(faux) response.setBody(body) data, method = xmlrpclib.loads(faux._body) data = data[0]['public'] self.assertTrue(isinstance(data, xmlrpclib.DateTime)) self.assertEqual(data.value, u'2006-05-24T07:00:00+00:00')
def test_zopedatetimeinstance_in_dict(self): # DateTime instance embedded in a dict body = {'date': DateTime('2006-05-24 07:00:00 GMT+0')} faux = FauxResponse() response = self._makeOne(faux) response.setBody(body) data, method = xmlrpclib.loads(faux._body) data = data[0]['date'] self.assertTrue(isinstance(data, xmlrpclib.DateTime)) self.assertEqual(data.value, u'2006-05-24T07:00:00+00:00')
def test_instanceattribute_recursive(self): # Instance "flattening" should work recursively, ad infinitum body = FauxInstance(public=FauxInstance(public=FauxInstance( _secret='abc', public='def'))) faux = FauxResponse() response = self._makeOne(faux) response.setBody(body) data, method = xmlrpclib.loads(faux._body) data = data[0]['public']['public'] self.assertEqual(data, {'public': 'def'})
def _process_rpc_response(self, response): try: if fastrpc is not None: response_data = fastrpc.loads(response.body)[0] else: response_data = xmlrpclib.loads(response.body)[0][0] except self.fault_cls as e: raise Fault(e.faultCode, e.faultString) else: return response_data