a
    ǹDfc!                     @   s   d Z ddgZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZmZmZmZ dd	lmZ G d
d dee	ZG dd deZedkrdS )ah  
This module contains the base class for pathos XML-RPC servers,
and derives from python's SimpleXMLRPCServer, and the base class
for XML-RPC request handlers, which derives from python's base HTTP
request handler.


Usage
=====

A typical setup for an XML-RPC server will roughly follow this example:

    >>> # establish a XML-RPC server on a host at a given port
    >>> host = 'localhost'
    >>> port = 1234
    >>> server = XMLRPCServer(host, port)
    >>> print('port=%d' % server.port)
    >>>
    >>> # register a method the server can handle requests for
    >>> def add(x, y):
    ...     return x + y
    >>> server.register_function(add)
    >>>
    >>> # activate the callback methods and begin serving requests
    >>> server.activate()
    >>> server.serve()


The following is an example of how to make requests to the above server:

    >>> # establish a proxy connection to the server at (host,port)
    >>> host = 'localhost'
    >>> port = 1234
    >>> proxy = xmlrpclib.ServerProxy('http://%s:%d' % (host, port))
    >>> print('1 + 2 = %s' % proxy.add(1, 2))
    >>> print('3 + 4 = %s' % proxy.add(3, 4))

XMLRPCServerXMLRPCRequestHandler    N)BaseHTTPRequestHandler)SimpleXMLRPCDispatcher)Server)print_exc_infospawn2_str_b)loggerc                   @   sj   e Zd ZdZdd Zdd ZdddZd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )r   z3extends base pathos server to an XML-RPC dispatcherc                 C   s.   t |  | j| j| j | j| j dS )zinstall callbacksN)r   activate	_selectornotifyOnReadReady_socket_onConnectionZnotifyWhenIdle_onSelectorIdleself r   a/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/pathos/xmlrpc/server.pyr   ?   s    
zXMLRPCServer.activatec                 C   s   d}t | d dS )z6enter the select loop... and wait for service requests   N)r   serve)r   timeoutr   r   r   r   G   s    zXMLRPCServer.serveNc           	   
   C   s   ddl m} ddl m} ||\}}z8|dur<|||}n| ||}|f}|j|dd}W nX |y } zt |_||}W Y d}~n,d}~0    ||ddt  }Y n0 t|S )zBoverride SimpleXMLRPCDispatcher._marshaled_dispatch() fault stringr   N)Fault   )methodresponsez
%s)	xmlrpc.clientclientr   loads	_dispatchdumpsr   faultStringr
   )	r   dataZdispatch_methodr   r   paramsmethodresponsefaultr   r   r   _marshaled_dispatchN   s"    
z XMLRPCServer._marshaled_dispatchc                 C   s   || j |< | j|| j dS )z@register a child process so it can be retrieved on select eventsN)_activeProcessesr   r   _handleMessageFromChild)r   pid	fromchildr   r   r   _registerChildk   s    
zXMLRPCServer._registerChildc                 C   s   | j |= dS )z3remove a child process from active process registerN)r(   )r   fdr   r   r   _unRegisterChilds   s    zXMLRPCServer._unRegisterChildc                 C   s@   t | }|dd dkr2| j| }t|d | | dS )z(handler for message from a child processN   doner   )r	   readliner(   oswaitpidr.   )r   selectorr-   liner*   r   r   r   r)   y   s
    
z$XMLRPCServer._handleMessageFromChildc                 C   s   dS )z(something to do when there's no requestsTr   )r   r4   r   r   r   r      s    zXMLRPCServer._onSelectorIdlec                 C   s   ddl m} ttjtj}|dkrj||dd}z| }|||f W qxW q0 tjyd   Y q0Y q00 q0n|||f |d || _|| _	|| _
dS )zprepare a listening socketr   )
portnumberi   )minmax
   N)Zpathos.portpickerr6   socketAF_INETSOCK_STREAMbinderrorlistenr   hostport)r   r@   rA   r6   sZpickr   r   r   _installSocket   s     
zXMLRPCServer._installSocketc                 C   s   t |tjr| |S dS )z3upon socket connection, establish a request handlerN)
isinstancer:   
SocketType_onSocketConnection)r   r4   r-   r   r   r   r      s    
zXMLRPCServer._onConnectionc                 C   s$   |  \}}t| |d}|  dS )z4upon socket connections, establish a request handler)serverr:   T)acceptr   handle)r   r:   connaddrhandlerr   r   r   rF      s    z XMLRPCServer._onSocketConnectionc                 C   s0   t |  tj| ddd | || i | _dS )zcreate a XML-RPC server

Takes two initial inputs:
    host  -- hostname of XML-RPC server host
    port  -- port number for server requests
        FN)
allow_noneencoding)r   __init__r   rC   r(   )r   r@   rA   r   r   r   rO      s    
zXMLRPCServer.__init__)N)__name__
__module____qualname____doc__r   r   r'   r,   r.   r)   r   rC   r   rF   rO   r   r   r   r   r   <   s   

c                   @   s<   e Zd ZdZedddZdd Zdd Zd	d
 Zdd Z	dS )r   z" create a XML-RPC request handler pathos.xmlrpc   namelevelc                    s   fdd} fdd}zXj tjd  t \}}|dkrTt||W S j }	| W dS W n.   j
t  d   Y dS 0 dS )	z  Access point from HTTP handler c                    s(    j | | |td |  d S )Ndone
)_serverr,   writer
   flush)r*   r+   Ztochildr   r   r   onParent   s    z.XMLRPCRequestHandler.do_POST.<locals>.onParentc                    sl   z<j  }| t| }|td |  W n    tddd	t
  Y n0 td d S )NrY   rT   rU   rV   r   )rZ   r'   _sendResponser	   r1   r[   r
   r\   r   r>   r   r2   _exit)r*   Z
fromparentZtoparentr%   r5   r"   r   r   r   onChild   s    
z-XMLRPCRequestHandler.do_POST.<locals>.onChildzcontent-lengthrunNi  )rfilereadintheadersr   r   r   rZ   r'   r^   _debugr>   r   send_responseend_headers)r   r]   ra   r#   r$   r%   r   r`   r   do_POST   s    


zXMLRPCRequestHandler.do_POSTc                 G   s&   | j d|  |  || f  dS )z1 Overriding BaseHTTPRequestHandler.log_message() z%s - - [%s] %s
N)rg   infoZaddress_stringZlog_date_time_string)r   formatargsr   r   r   log_message   s    z XMLRPCRequestHandler.log_messagec                 C   s`   t |}| d | dd | dtt| |   | j| | j  | j	
d dS )z Write the XML-RPC response    zContent-typeztext/xmlzContent-lengthr   N)r
   rh   Zsend_headerstrlenri   wfiler[   r\   
connectionshutdown)r   r%   r   r   r   r^      s    

z"XMLRPCRequestHandler._sendResponsec                 C   s:   | dd| _| dd| _|| _|j|jf| _|| _dS )z
Override BaseHTTPRequestHandler.__init__(): we need to be able
to have (potentially) multiple handler objects at a given time.

Inputs:
    server  -- server object to handle requests for 
    socket  -- socket connection 
        rbwbr   N)makefilerc   rr   rs   r@   rA   client_addressrZ   )r   rG   r:   r   r   r   rO      s
    zXMLRPCRequestHandler.__init__N)
rP   rQ   rR   rS   r   rg   rj   rn   r^   rO   r   r   r   r   r      s   $	__main__)rS   __all__r2   r:   r   r   Zhttp.serverr   Zxmlrpc.serverr   Zpathos.serverr   Zpathos.utilr   r   r	   r
   Zpathosr   r   r   rP   r   r   r   r   <module>
   s   & R