Ñò
mÈKc           @   s\  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 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()
iÿÿÿÿN(   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.6/SimpleXMLRPCServer.pyt   resolve_dotted_attributer   s    
	 c         C   sS   g  } t  |  ƒ D]; } | i d ƒ o$ t t |  | ƒ d ƒ o | | q q ~ S(   sk   Returns a list of attribute strings, found in the specified
    object, which represent callable attributesR   t   __call__(   t   dirR   t   hasattrR   (   R   t   _[1]t   member(    (    s(   /usr/lib/python2.6/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.6/SimpleXMLRPCServer.pyt   remove_duplicates’   s
     t   SimpleXMLRPCDispatcherc           B   s€   e  Z d  Z e d 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.6/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.6/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.6/SimpleXMLRPCServer.pyt   register_functionÑ   s    c         C   s2   |  i  i h |  i d 6|  i d 6|  i d 6ƒ 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.6/SimpleXMLRPCServer.pyt    register_introspection_functionsÜ   s    
c         C   s   |  i  i h |  i d 6ƒ 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.6/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 ƒ} Wnˆ t j
 o* } t  i | d |  i d |  i ƒ} nT t i	 ƒ  \ } } }	 t  i t  i d d | | 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_info(
   R   t   datat   dispatch_methodt   paramst   methodt   responset   faultt   exc_typet	   exc_valuet   exc_tb(    (    s(   /usr/lib/python2.6/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   R   R   R=   R   t   sort(   R   t   methods(    (    s(   /usr/lib/python2.6/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.6/SimpleXMLRPCServer.pyR'   +  s    c         C   s×   d } | |  i j o |  i | } n‚ |  i d j	 oq t |  i d ƒ o |  i i | ƒ St |  i d ƒ p6 y t |  i | |  i ƒ } Wq¤ t j
 o q¤ Xq¨ n | d j o d S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    iÿÿÿÿN(
   R   R   R   R   RA   R   R	   R   t   pydoct   getdoc(   R   R@   R6   RC   (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyR(   8  s$    c   
      C   sÈ   g  } x» | D]³ } | d } | d } y  | i  |  i | | ƒ g ƒ Wq t j
 o* } | i  h | i d 6| i d 6ƒ q t i ƒ  \ } } }	 | i  h d d 6d | | f d 6ƒ 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    RF   RG   R1   R2   (
   R   t	   call_listt   resultst   callR@   R5   R8   R9   R:   R;   (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyR*   X  s"    
 

 
c         C   sÆ   d } y |  i | } Wn€ t j
 ot |  i d j	 o] t |  i d ƒ o |  i i | | ƒ Sy t |  i | |  i ƒ } Wq• t j
 o q• Xqš n X| d j	 o | | Œ  S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.6/SimpleXMLRPCServer.pyR/   x  s"    N(   R!   t
   __module__t   __doc__t   FalseR   R   R    R$   R)   R+   R<   R&   R'   R(   R*   R/   (    (    (    s(   /usr/lib/python2.6/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 St Sd  S(   N(   t	   rpc_pathst   patht   True(   R   (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyt   is_rpc_path_valid±  s    
c      	   C   s­  |  i  ƒ  p |  i ƒ  d Syž d } t |  i d ƒ } g  } xH | o@ t | | ƒ } | i |  i i | ƒ ƒ | t | d ƒ 8} qA Wd i	 | ƒ } |  i
 i | t |  d d ƒ ƒ } Wn| t j
 op } |  i d ƒ t |  i
 d	 ƒ o= |  i
 i o0 |  i d
 t | ƒ ƒ |  i d t i ƒ  ƒ n |  i ƒ  nr 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-lengthiÿÿÿÿRB   R/   iô  t   _send_traceback_headers   X-exceptions   X-tracebackiÈ   s   Content-types   text/xmls   Content-lengthi   i (  i    (   RW   t
   report_404t   intt   headerst   minRH   t   rfilet   readt   lent   joint   serverR<   R   R   RM   t   send_responseR   RX   t   send_headert   strt	   tracebackt
   format_exct   end_headerst   wfilet   writet   flusht
   connectiont   shutdown(   R   t   max_chunk_sizet   size_remainingt   Lt
   chunk_sizeR3   R7   t   e(    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyt   do_POST¸  s:    
 	
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   (
   Rb   Rc   Rd   R_   Rg   Rh   Ri   Rj   Rk   Rl   (   R   R7   (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyRY   ñ  s    
t   -c         C   s+   |  i  i o t i i |  | | ƒ n d S(   s$   Selectively log an accepted request.N(   Ra   t   logRequestst   BaseHTTPServert   BaseHTTPRequestHandlert   log_request(   R   t   codet   size(    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyRw   ý  s    (   RS   s   /RPC2(   R!   RO   RP   RT   RW   Rr   RY   Rw   (    (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyRR   ¦  s   		9	t   SimpleXMLRPCServerc           B   s2   e  Z d  Z e Z e Z e e e d e 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(   Rt   R   R   t   SocketServert	   TCPServert   fcntlR   R   t   filenot   F_GETFDR{   t   F_SETFD(   R   t   addrt   requestHandlerRt   R   R   t   bind_and_activatet   flags(    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyR     s    	N(
   R!   RO   RP   RV   t   allow_reuse_addressRQ   RX   RR   R   R   (    (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyRz     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.6/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(   R<   R_   R1   t   stdoutRi   (   R   t   request_textR7   (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyt   handle_xmlrpc+  s
    c         C   sv   d } t  i i | \ } } t  i h | d 6| d 6| d 6} 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  Rx   t   messaget   explains   Status: %d %ss   Content-Type: text/htmls   Content-Length: %dN(   Ru   Rv   t	   responsest   DEFAULT_ERROR_MESSAGER_   R1   Rˆ   Ri   (   R   Rx   R‹   RŒ   R7   (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyt
   handle_get5  s    c         C   s¬   | d j o* t i i d d ƒ d j o |  i ƒ  nr y t t i i d d ƒ ƒ } Wn t t f j
 o d } n X| 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   GETt   CONTENT_LENGTHiÿÿÿÿN(   R   t   ost   environt   getR   RZ   t	   TypeErrort
   ValueErrorR1   t   stdinR^   RŠ   (   R   R‰   t   length(    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyt   handle_requestL  s    N(	   R!   RO   RP   RQ   R   R   RŠ   R   Rš   (    (    (    s(   /usr/lib/python2.6/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.6/SimpleXMLRPCServer.pyt   <lambda>f  s    t   add(   RP   R-   R    R|   Ru   R1   R“   Re   R~   t   ImportErrorR   RV   R   R   R   R   Rv   RR   R}   Rz   R‡   R!   Ra   R$   t   powt   serve_forever(    (    (    s(   /usr/lib/python2.6/SimpleXMLRPCServer.pyt   <module>a   s4   		ÿ ]	!=