m %UIc@s dZdkZdklZdkZdkZdkZdkZedZdZ dZ dfdYZ dei fd YZ d eie fd YZd e fd YZedjo@eddfZeieeiddeindS(s9 Simple XML-RPC Server. This module can be used to create simple XML-RPC servers by creating a server and either installing functions, a class instance, or by extending the SimpleXMLRPCServer class. It can also be used to handle XML-RPC requests in a CGI environment using CGIXMLRPCRequestHandler. A list of possible usage patterns follows: 1. Install functions: server = SimpleXMLRPCServer(("localhost", 8000)) server.register_function(pow) server.register_function(lambda x,y: x+y, 'add') server.serve_forever() 2. Install an instance: class MyFuncs: def __init__(self): # make all of the string functions available through # string.func_name import string self.string = string def _listMethods(self): # implement this method so that system.listMethods # knows to advertise the strings methods return list_public_methods(self) + ['string.' + method for method in list_public_methods(self.string)] def pow(self, x, y): return pow(x, y) def add(self, x, y) : return x + y server = SimpleXMLRPCServer(("localhost", 8000)) server.register_introspection_functions() server.register_instance(MyFuncs()) server.serve_forever() 3. Install an instance with custom dispatch method: class Math: def _listMethods(self): # this method must be present for system.listMethods # to work return ['add', 'pow'] def _methodHelp(self, method): # this method must be present for system.methodHelp # to work if method == 'add': return "add(2,3) => 5" elif method == 'pow': return "pow(x, y[, z]) => number" else: # By convention, return empty # string if no help is available return "" def _dispatch(self, method, params): if method == 'pow': return pow(*params) elif method == 'add': return params[0] + params[1] else: raise 'bad method' server = SimpleXMLRPCServer(("localhost", 8000)) server.register_introspection_functions() server.register_instance(Math()) server.serve_forever() 4. Subclass SimpleXMLRPCServer: class MathServer(SimpleXMLRPCServer): def _dispatch(self, method, params): try: # We are forcing the 'export_' prefix on methods that are # callable through XML-RPC to prevent potential security # problems func = getattr(self, 'export_' + method) except AttributeError: raise Exception('method "%s" is not supported' % method) else: return func(*params) def export_add(self, x, y): return x + y server = MathServer(("localhost", 8000)) server.serve_forever() 5. CGI script: server = CGIXMLRPCRequestHandler() server.register_function(pow) server.handle_request() N(sFaultcCsk|o|id}n |g}xA|D]9}|idotd|q*t||}q*W|S(sGresolve_dotted_attribute(a, 'b.c.d') => a.b.c.d Resolves a dotted attribute name to an object. Raises an AttributeError if any attribute in the chain starts with a '_'. If the optional allow_dotted_names argument is false, dots are not supported and this function operates similar to getattr(obj, attr). t.t_s(attempt to access private attribute "%s"N( tallow_dotted_namestattrtsplittattrstit startswithtAttributeErrortgetattrtobj(R RRRR((t//data/zmath/lib/python2.4/SimpleXMLRPCServer.pytresolve_dotted_attributems cCsPg}t|D]8}|id o!tt||o ||qq~S(skReturns a list of attribute strings, found in the specified object, which represent callable attributesRN(t_[1]tdirR tmemberRtcallableR (R RR ((R tlist_public_methodsscCs+h}x|D]}d|| [3,1,2] Returns a copy of a list without duplicates. Every list item must be hashable and the order of the items in the resulting list is not defined. iN(tutlsttxtkeys(RRR((R tremove_duplicatess tSimpleXMLRPCDispatchercBsztZdZdZedZedZdZdZ edZ dZ dZ d Z d Zd ZRS( sMix-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. cCsh|_d|_dS(N(tselftfuncstNonetinstance(R((R t__init__s cCs||_||_dS(sRegisters an instance to respond to XML-RPC requests. Only one instance can be installed at a time. If the registered instance has a _dispatch method then that method will be called with the name of the XML-RPC method and its parameters as a tuple e.g. instance._dispatch('add',(2,3)) If the registered instance does not have a _dispatch method then the instance will be searched to find a matching method and, if found, will be called. Methods beginning with an '_' are considered private and will not be called by SimpleXMLRPCServer. If a registered function matches a XML-RPC request, then it will be called instead of the registered instance. If the optional allow_dotted_names argument is true and the instance does not have a _dispatch method, method names containing dots are supported and resolved, as long as none of the name segments start with an '_'. *** SECURITY WARNING: *** Enabling the allow_dotted_names options allows intruders to access your module's global variables and may allow intruders to execute arbitrary code on your machine. Only use this option on a secure, closed network. N(RRR(RRR((R tregister_instances cCs+|djo |i}n||i| ['add', 'subtract', 'multiple'] Returns a list of the methods supported by the server.t _listMethodsR1N( RRRtmethodsRRthasattrRR9Rtsort(RR:((R R# s! cCsdS(s#system.methodSignature('add') => [double, int, int] Returns a list describing the signature of the method. In the above example, the add method takes two integers as arguments and returns a double result. This server does NOT support system.methodSignature.ssignatures not supportedN((Rt method_name((R R$ scCsd}|ii|o|i|}n|idj ott|ido|ii|Sqt|idp6yt |i||i }Wqt j oqXqn|djodSndk }|i |SdS(ssystem.methodHelp('add') => "Adds two integers together" Returns a string containing documentation for the specified method.t _methodHelpR1tN(RR.RRthas_keyR=RR;R>R RRtpydoctgetdoc(RR=RAR.((R R%-s$    cCsg}x|D]}|d}|d}y |i|i||gWq tj o.}|ihd|i <d|i <q |ihdd<ddt i t if<q Xq W|S(ssystem.multicall([{'methodName': 'add', 'params': [2, 2]}, ...]) => [[4], ...] Allows the caller to package multiple XML-RPC calls into a single request. See http://www.xmlrpc.com/discuss/msgReader$1208 t methodNameR-t faultCodet faultStringis%s:%sN(tresultst call_listtcallR=R-tappendRR1R3R4RDRER5R6R7(RRGR4RFR=R-RH((R R'Ms   )7cCsd}y|i|}Wntj ow|idj o`t|ido|ii||Sqyt |i||i }Wqt j oqXqnX|dj o||Snt d|dS(sDispatches the XML-RPC method. XML-RPC calls are forwarded to a registered function that matches the called XML-RPC method name. If no such function exists then the call is forwarded to the registered instance, if available. If the registered instance has a _dispatch method then that method will be called with the name of the XML-RPC method and its parameters as a tuple e.g. instance._dispatch('add',(2,3)) If the registered instance does not have a _dispatch method then the instance will be searched to find a matching method and, if found, will be called. Methods beginning with an '_' are considered private and will not be called. R1smethod "%s" is not supportedN(RtfuncRRR.tKeyErrorRR;R1R-R RRt Exception(RR.R-RJ((R R1ls"  (R t __module__t__doc__RtFalseRRR!R&R(R8R#R$R%R'R1(((R Rs   $  !  tSimpleXMLRPCRequestHandlercBs&tZdZdZdddZRS(sSimple XML-RPC request handler class. Handles all HTTP POST requests and attempts to decode them as XML-RPC requests. cCsyD|iit|id}|ii|t|dd }Wn|i d|i nqX|i d|i dd|i dtt||i |ii||ii|iidd S( sHandles the HTTP POST request. Attempts to interpret all HTTP POST requests as XML-RPC calls, which are forwarded to the server's _dispatch method for handling. scontent-lengthR1iis Content-typestext/xmlsContent-lengthiN(RtrfiletreadtinttheadersR,tserverR8R RR0t send_responset end_headerst send_headertstrtlentwfiletwritetflusht connectiontshutdown(RR,R0((R tdo_POSTs%    t-cCs+|iiotii|||ndS(s$Selectively log an accepted request.N(RRUt logRequeststBaseHTTPServertBaseHTTPRequestHandlert log_requesttcodetsize(RRfRg((R Res (R RMRNR`Re(((R RPs  "tSimpleXMLRPCServercBstZdZeddZRS(sgSimple XML-RPC server. Simple XML-RPC server that allows functions and a single instance to be installed to handle requests. The default implementation attempts to dispatch XML-RPC calls to the functions or instance installed in the server. Override the _dispatch method inhereted from SimpleXMLRPCDispatcher to change this behavior. icCs0||_ti|tii|||dS(N(RbRRRt SocketServert TCPServertaddrtrequestHandler(RRkRlRb((R Rs  (R RMRNRPR(((R Rhs tCGIXMLRPCRequestHandlercBs5tZdZdZdZdZedZRS(s3Simple handler for XML-RPC data passed through CGI.cCsti|dS(N(RRR(R((R RscCs8|i|}dGHdt|GHHtii|dS(sHandle a single XML-RPC requestsContent-Type: text/xmlsContent-Length: %dN(RR8t request_textR0RZR5tstdoutR\(RRnR0((R t handle_xmlrpcs cCs|d}tii|\}}tihd|<d|<d|<}d||fGHdGHdt|GHHt i i |dS( sHandle a single HTTP GET request. Default implementation indicates an error because XML-RPC uses the POST method. iRftmessagetexplains Status: %d %ssContent-Type: text/htmlsContent-Length: %dN( RfRcRdt responsesRqRrtDEFAULT_ERROR_MESSAGER0RZR5RoR\(RRfRrR0Rq((R t handle_gets(cCsh|djo*tiidddjo|in.|djotii }n|i |dS(sHandle a single XML-RPC request passed through a CGI post method. If no XML data is given then it is read from stdin. The resulting XML-RPC response is printed to stdout along with the correct HTTP headers. tREQUEST_METHODtGETN( RnRtostenvirontgetRRuR5tstdinRRRp(RRn((R thandle_requests ) (R RMRNRRpRuRR|(((R Rms   t__main__t localhosti@cCs||S(N(Rty(RR((R tstadd(RNR*R3RiRcR5RxtTrueR RRRRdRPRjRhRmR RUR!tpowt serve_forever(RRiRPR3R*RhRmR5RRRcR RURx((R t?as&         /9