
\Kc           @   sP  d  Z  d d k Z d d k l Z d d k Z d d k Z d d k Z d d k Z y d d k Z Wn e j
 o e	 Z n Xe
 d  Z d   Z d   Z d f  d     YZ d	 e i f d
     YZ d e i e f d     YZ d e f d     YZ e d j oE d GHe d d f  Z e i e  e i d   d  e i   n d S(   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()
iN(   t   Faultc         C   sk   | o | i  d  } n
 | g } xA | D]9 } | i d  o t d |   q* t |  |  }  q* W|  S(   sG  resolve_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"(   t   splitt
   startswitht   AttributeErrort   getattr(   t   objt   attrt   allow_dotted_namest   attrst   i(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   resolve_dotted_attributeq   s    
	 c         C   sP   g  } t  |   D]8 } | i d  o! t t |  |   o | | q q ~ S(   sk   Returns a list of attribute strings, found in the specified
    object, which represent callable attributesR   (   t   dirR   t   callableR   (   R   t   _[1]t   member(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   list_public_methods   s    c         C   s+   h  } x |  D] } d | | <q W| i    S(   s   remove_duplicates([2,2,2,1,3,3]) => [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.
    i   (   t   keys(   t   lstt   ut   x(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   remove_duplicates   s
     t   SimpleXMLRPCDispatcherc           B   sz   e  Z d  Z d   Z e d  Z d d  Z d   Z d   Z	 d d  Z
 d   Z d   Z d	   Z d
   Z d   Z RS(   s   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.
    c         C   s(   h  |  _  d  |  _ | |  _ | |  _ d  S(   N(   t   funcst   Nonet   instancet
   allow_nonet   encoding(   t   selfR   R   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   __init__   s    			c         C   s   | |  _  | |  _ d S(   s  Registers 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(   R   R	   (   R   R   R	   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   register_instance   s    !	c         C   s+   | d j o | i } n | |  i | <d S(   s   Registers a function to respond to XML-RPC requests.

        The optional name argument can be used to set a Unicode name
        for the function.
        N(   R   t   __name__R   (   R   t   functiont   name(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   register_function   s    c         C   s8   |  i  i h  |  i d <|  i d <|  i d < d S(   s   Registers the XML-RPC introspection methods in the system
        namespace.

        see http://xmlrpc.usefulinc.com/doc/reserved.html
        s   system.listMethodss   system.methodSignatures   system.methodHelpN(   R   t   updatet   system_listMethodst   system_methodSignaturet   system_methodHelp(   R   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt    register_introspection_functions   s    c         C   s    |  i  i h  |  i d < d S(   s   Registers the XML-RPC multicall method in the system
        namespace.

        see http://www.xmlrpc.com/discuss/msgReader$1208s   system.multicallN(   R   R$   t   system_multicall(   R   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   register_multicall_functions   s    c         C   s   y{ t  i |  \ } } | d j	 o | | |  } n |  i | |  } | f } t  i | d d d |  i d |  i } Wny t j
 o* } t  i | d |  i d |  i } nE t  i t  i d d t i	 t i
 f  d |  i d |  i } n X| S(   s  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.
        t   methodresponsei   R   R   s   %s:%sN(   t	   xmlrpclibt   loadsR   t	   _dispatcht   dumpsR   R   R    t   syst   exc_typet	   exc_value(   R   t   datat   dispatch_methodt   paramst   methodt   responset   fault(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   _marshaled_dispatch   s     	"c         C   s   |  i  i   } |  i d j	 od t |  i d  o t | |  i i    } q t |  i d  p t | t |  i   } q n | i   | S(   sw   system.listMethods() => ['add', 'subtract', 'multiple']

        Returns a list of the methods supported by the server.t   _listMethodsR.   N(	   R   R   R   R   t   hasattrR   R:   R   t   sort(   R   t   methods(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR%     s    
c         C   s   d S(   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.s   signatures not supported(    (   R   t   method_name(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR&   )  s    c         C   s   d } |  i i |  o |  i | } n |  i d j	 ot t |  i d  o |  i i |  Sq t |  i d  p6 y t |  i | |  i  } Wq t j
 o q Xq n | d j o d Sn d d k	 } | i
 |  Sd S(   s   system.methodHelp('add') => "Adds two integers together"

        Returns a string containing documentation for the specified method.t   _methodHelpR.   t    iN(   R   R   t   has_keyR   R;   R?   R   R	   R   t   pydoct   getdoc(   R   R>   R6   RB   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR'   6  s$    c         C   s   g  } x | D] } | d } | d } y  | i  |  i | |  g  Wq t j
 o. } | i  h  | i d <| i d < q | i  h  d d <d t i t i f d < q Xq W| S(   s   system.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
   methodNameR5   t	   faultCodet   faultStringi   s   %s:%s(   t   appendR.   R    RE   RF   R0   R1   R2   (   R   t	   call_listt   resultst   callR>   R5   R8   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR)   V  s     
 

 $c         C   s   d } y |  i | } Wn t j
 ow |  i d j	 o` t |  i d  o |  i i | |  Sq y t |  i | |  i  } Wq t j
 o q Xq n X| d j	 o | |   Sn t	 d |   d S(   s  Dispatches 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.
        R.   s   method "%s" is not supportedN(
   R   R   t   KeyErrorR   R;   R.   R   R	   R   t	   Exception(   R   R6   R5   t   func(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR.   u  s"    N(   R    t
   __module__t   __doc__R   t   FalseR   R   R#   R(   R*   R9   R%   R&   R'   R)   R.   (    (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR      s   	$		$			 	t   SimpleXMLRPCRequestHandlerc           B   s>   e  Z d  Z d Z d   Z d   Z d   Z d d d  Z RS(	   s   Simple XML-RPC request handler class.

    Handles all HTTP POST requests and attempts to decode them as
    XML-RPC requests.
    t   /s   /RPC2c         C   s&   |  i  o |  i |  i  j Sn t Sd  S(   N(   t	   rpc_pathst   patht   True(   R   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   is_rpc_path_valid  s    
c      	   C   sR  |  i    p |  i   d Sn y d } t |  i d  } g  } xH | o@ t | |  } | i |  i i |   | t | d  8} qD Wd i	 |  } |  i
 i | t |  d d   } Wn |  i d  |  i   nq X|  i d	  |  i d
 d  |  i d t t |    |  i   |  i i |  |  i i   |  i i d  d S(   s   Handles 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.
        Ni
   i   s   content-lengthiR@   R.   i  i   s   Content-types   text/xmls   Content-lengthi   i (  i   (   RV   t
   report_404t   intt   headerst   minRG   t   rfilet   readt   lent   joint   serverR9   R   R   t   send_responset   end_headerst   send_headert   strt   wfilet   writet   flusht
   connectiont   shutdown(   R   t   max_chunk_sizet   size_remainingt   Lt
   chunk_sizeR3   R7   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   do_POST  s2    
 	
c         C   sz   |  i  d  d } |  i d d  |  i d t t |    |  i   |  i i |  |  i i   |  i i	 d  d  S(   Ni  s   No such pages   Content-types
   text/plains   Content-lengthi   (
   R`   Rb   Rc   R]   Ra   Rd   Re   Rf   Rg   Rh   (   R   R7   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyRW     s    
t   -c         C   s+   |  i  i o t i i |  | |  n d S(   s$   Selectively log an accepted request.N(   R_   t   logRequestst   BaseHTTPServert   BaseHTTPRequestHandlert   log_request(   R   t   codet   size(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyRr     s    (   RR   s   /RPC2(   R    RN   RO   RS   RV   Rm   RW   Rr   (    (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyRQ     s   		2	t   SimpleXMLRPCServerc           B   s)   e  Z d  Z e Z e e e d d  Z RS(   sg  Simple 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.
    c         C   s   | |  _  t i |  | |  t i i |  | |  t d  j	 oX t t d  oH t i |  i   t i	  } | t i
 O} t i |  i   t i |  n d  S(   Nt
   FD_CLOEXEC(   Ro   R   R   t   SocketServert	   TCPServert   fcntlR   R;   t   filenot   F_GETFDRv   t   F_SETFD(   R   t   addrt   requestHandlerRo   R   R   t   flags(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR     s    	N(	   R    RN   RO   RU   t   allow_reuse_addressRQ   RP   R   R   (    (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyRu     s   	t   CGIXMLRPCRequestHandlerc           B   s;   e  Z d  Z e d d  Z d   Z d   Z d d  Z RS(   s3   Simple handler for XML-RPC data passed through CGI.c         C   s   t  i |  | |  d  S(   N(   R   R   (   R   R   R   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR     s    c         C   s8   |  i  |  } d GHd t |  GHHt i i |  d S(   s   Handle a single XML-RPC requests   Content-Type: text/xmls   Content-Length: %dN(   R9   R]   R0   t   stdoutRe   (   R   t   request_textR7   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   handle_xmlrpc  s
    c         C   s|   d } t  i i | \ } } t  i h  | d <| d <| d <} d | | f GHd GHd t |  GHHt i i |  d S(	   s   Handle a single HTTP GET request.

        Default implementation indicates an error because
        XML-RPC uses the POST method.
        i  Rs   t   messaget   explains   Status: %d %ss   Content-Type: text/htmls   Content-Length: %dN(   Rp   Rq   t	   responsest   DEFAULT_ERROR_MESSAGER]   R0   R   Re   (   R   Rs   R   R   R7   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt
   handle_get%  s    		c         C   sh   | d j o* t i i d d  d j o |  i   n. | d j o t i i   } n |  i |  d S(   s   Handle 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.
        t   REQUEST_METHODt   GETN(	   R   t   ost   environt   getR   R0   t   stdinR\   R   (   R   R   (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   handle_request<  s    N(	   R    RN   RO   RP   R   R   R   R   R   (    (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyR     s
   	
	t   __main__s#   Running XML-RPC server on port 8000t	   localhosti@  c         C   s   |  | S(    (    (   R   t   y(    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pyt   <lambda>R  s    t   add(   RO   R,   R    Rw   Rp   R0   R   Ry   t   ImportErrorR   RU   R   R   R   R   Rq   RQ   Rx   Ru   R   R    R_   R#   t   powt   serve_forever(    (    (    s(   /usr/lib/python2.5/SimpleXMLRPCServer.pys   <module>a   s2   		 V	9