Index: Lib/SimpleXMLRPCServer.py |
=================================================================== |
--- Lib/SimpleXMLRPCServer.py (revision 74098) |
+++ Lib/SimpleXMLRPCServer.py (working copy) |
@@ -157,12 +157,40 @@ |
return u.keys() |
+class MultiPathXMLRPCDispatcher: |
+ """Mix-in class that allows multiple dispatchers per request path.""" |
+ def __init__(self, allow_none=False, encoding=None): |
+ self.dispatchers = {} |
+ self.allow_none = allow_none |
+ self.encoding = encoding |
+ |
+ def add_dispatcher(self, path, dispatcher): |
+ self.dispatchers[path] = dispatcher |
+ return dispatcher |
+ |
+ def get_dispatcher(self, path): |
+ return self.dispatchers[path] |
+ |
+ def _marshaled_dispatch(self, data, dispatch_method = None, path = None): |
+ try: |
+ response = self.dispatchers[path]._marshaled_dispatch( |
+ data, dispatch_method, path) |
+ except: |
+ # report exception back to server |
+ exc_type, exc_value = sys.exc_info()[:2] |
+ response = xmlrpclib.dumps( |
+ xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)), |
+ encoding=self.encoding, allow_none=self.allow_none, |
+ ) |
+ return response |
+ |
class SimpleXMLRPCDispatcher: |
"""Mix-in class that dispatches XML-RPC requests. |
This class is used to register XML-RPC method handlers |
- and then to dispatch them. There should never be any |
- reason to instantiate this class directly. |
+ and then to dispatch them. This class doesn't need to be |
+ instanced directly when used by SimpleXMLRPCServer but it |
+ can be instanced when used by the MultiPathXMLRPCDispatcher |
""" |
def __init__(self, allow_none=False, encoding=None): |
@@ -237,7 +265,7 @@ |
self.funcs.update({'system.multicall' : self.system_multicall}) |
- def _marshaled_dispatch(self, data, dispatch_method = None): |
+ 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 |
@@ -499,7 +527,7 @@ |
# check to see if a subclass implements _dispatch and dispatch |
# using that method if present. |
response = self.server._marshaled_dispatch( |
- data, getattr(self, '_dispatch', None) |
+ data, getattr(self, '_dispatch', None), self.path |
) |
except Exception, e: # This should only happen if the module is buggy |
# internal error, report as HTTP server error |
@@ -596,6 +624,15 @@ |
flags |= fcntl.FD_CLOEXEC |
fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags) |
+class MultiPathXMLRPCServer(MultiPathXMLRPCDispatcher, SimpleXMLRPCServer): |
+ def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler, |
+ logRequests=True, allow_none=False, encoding=None, |
+ bind_and_activate=True): |
+ |
+ MultiPathXMLRPCDispatcher.__init__(self, allow_none, encoding) |
+ SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests, |
+ allow_none, encoding, bind_and_activate) |
+ |
class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): |
"""Simple handler for XML-RPC data passed through CGI.""" |