o
    0׾g@                     @   s   d Z ddlmZ ddlmZ ddlmZ ddl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 ddlmZ dgZdd ZG dd deZdd Zdd Zdd ZdS )z#Base class for implementing servers    )print_function)absolute_import)divisionN)Greenlet)Event)get_hub)string_types)integer_types)xrange
BaseServerc                 C   s   z	| | W ||  S ||  w N )handleclose
args_tupler   r   [/var/www/html/backend_erp/backend_erp_env/lib/python3.10/site-packages/gevent/baseserver.py_handle_and_close_when_done    s   r   c                   @   s&  e Zd ZdZdZdZdZejZ	dZ
ejejejfZd=ddZd	d
 Zdd Zd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%d& Zd'd( Z e!d)d* Z"e!d+d, Z#d-d. Z$e!d/d0 Z%d1d2 Z&d3d4 Z'e!d5d6 Z(d>d7d8Z)d>d9d:Z*d;d< Z+dS )?r   a  
    An abstract base class that implements some common functionality for the servers in gevent.

    :param listener: Either be an address that the server should bind
        on or a :class:`gevent.socket.socket` instance that is already
        bound (and put into listening mode in case of TCP socket).

    :keyword handle: If given, the request handler. The request
        handler can be defined in a few ways. Most commonly,
        subclasses will implement a ``handle`` method as an
        instance method. Alternatively, a function can be passed
        as the ``handle`` argument to the constructor. In either
        case, the handler can later be changed by calling
        :meth:`set_handle`.

        When the request handler returns, the socket used for the
        request will be closed. Therefore, the handler must not return if
        the socket is still in use (for example, by manually spawned greenlets).

    :keyword spawn: If provided, is called to create a new
        greenlet to run the handler. By default,
        :func:`gevent.spawn` is used (meaning there is no
        artificial limit on the number of concurrent requests). Possible values for *spawn*:

        - a :class:`gevent.pool.Pool` instance -- ``handle`` will be executed
          using :meth:`gevent.pool.Pool.spawn` only if the pool is not full.
          While it is full, no new connections are accepted;
        - :func:`gevent.spawn_raw` -- ``handle`` will be executed in a raw
          greenlet which has a little less overhead then :class:`gevent.Greenlet` instances spawned by default;
        - ``None`` -- ``handle`` will be executed right away, in the :class:`Hub` greenlet.
          ``handle`` cannot use any blocking functions as it would mean switching to the :class:`Hub`.
        - an integer -- a shortcut for ``gevent.pool.Pool(integer)``

    .. versionchanged:: 1.1a1
       When the *handle* function returns from processing a connection,
       the client socket will be closed. This resolves the non-deterministic
       closing of the socket, fixing ResourceWarnings under Python 3 and PyPy.
    .. versionchanged:: 1.5
       Now a context manager that returns itself and calls :meth:`stop` on exit.

    g{Gz?   d   Ndefaultc                 C   s   t  | _| j  d | _d | _d | _d | _z(| | | | | 	| | j
| _t j| _| jdk r;td| jf W d S    |    )Nr   z#max_accept must be positive int: %r)r   _stop_eventset_watcher_timer_handlepoolset_listener	set_spawn
set_handle	min_delaydelayr   loop
max_accept
ValueErrorr   )selflistenerr   spawnr   r   r   __init__o   s$   





zBaseServer.__init__c                 C   s   | S r   r   r$   r   r   r   	__enter__      zBaseServer.__enter__c                 G   s   |    d S r   )stopr$   argsr   r   r   __exit__   s   zBaseServer.__exit__c                 C   sR   t |drt |drtd|f |j| _| | _|| _d S t|\| _| _d S )Nacceptdo_handshakez,Expected a regular socket, not SSLSocket: %r)hasattr	TypeErrorfamilygetsocknameaddresssocketparse_address)r$   r%   r   r   r   r      s   



zBaseServer.set_listenerc                 C   s   |dkrd | _ | j| _n)t|dr|| _ |j| _nt|tr/ddlm} ||| _ | j j| _nd | _ || _t| j dr@| j j| _| j d urO| j j	
| j d S d S )Nr   r&   r   )Poolfull)r   _spawnr1   r&   
isinstancer	   gevent.poolr8   r9   
_semaphorerawlink_start_accepting_if_started)r$   r&   r8   r   r   r   r      s"   






zBaseServer.set_spawnc                 C   s,   |d ur|| _ t| dr| j | _d S td)Nr   z'handle' must be provided)r   r1   r   r2   )r$   r   r   r   r   r      s
   
zBaseServer.set_handlec                 C   s   | j r	|   d S d S r   )startedstart_accepting)r$   _eventr   r   r   r?      s   z&BaseServer._start_accepting_if_startedc                 C   s6   | j d u r| j| j d| _ | j | j d S d S )Nr   )r   r!   ior6   filenostart_do_readr(   r   r   r   rA      s   
zBaseServer.start_acceptingc                 C   sP   | j d ur| j   | j   d | _ | jd ur&| j  | j  d | _d S d S r   )r   r+   r   r   r(   r   r   r   stop_accepting   s   






zBaseServer.stop_acceptingc                 G   sR   | j }| j}| j}z|d u rt||| W d S |t||| W d S    ||   r   )r:   r   do_closer   )r$   r-   r&   r   r   r   r   r   	do_handle   s   zBaseServer.do_handlec                 G   s   d S r   r   r,   r   r   r   rH      r*   zBaseServer.do_closec                 C   s   t  r   )NotImplementedErrorr(   r   r   r   do_read   s   zBaseServer.do_readc              
   C   s  t | jD ]}|  r|   | jd ur| jj| j  d S z|  }| j	| _
|s.W  d S W nX   | jj| gt R   t d }| |rb|   tjd| t|pZt|f  Y  d S | j
dkr|   | j| j
| _| j| j t| j| j
d | _
Y  d S z| j|  W q   | jj|dd  | fgt R   | j
dkr|   | j| j
| _| j| j t| j| j
d | _
Y  d S d S )Nr   zERROR: %s failed with %s
r      )r
   r"   r9   rG   r   r=   r>   r?   rK   r   r    r!   handle_errorsysexc_infois_fatal_errorr   stderrwritestrreprtimerr   rE   min	max_delayrI   )r$   _r-   exr   r   r   rF      sH   

 
$
zBaseServer._do_readc                 C      dS )NFr   r(   r   r   r   r9      s   zBaseServer.fullc                 C   s    dt | jtt| |  f S )Nz<%s at %s %s>)type__name__hexid_formatinfor(   r   r   r   __repr__  s    zBaseServer.__repr__c                 C   s   dt | j|  f S )Nz<%s %s>)r[   r\   r_   r(   r   r   r   __str__  s   zBaseServer.__str__c              
   C   sZ  t | dr(z| j }W n ty" } z
t|}W Y d }~nd }~ww d| }nd}zt| jtr@t| jdkr@|d| j 7 }n|d| jf 7 }W n tyc } z|t|pWd7 }W Y d }~nd }~ww | j	
d}|d urt|d	d }z|| u rd
| jj|jf }nt|}|d| 7 }W |S  ty } z|t|pd7 }W Y d }~|S d }~ww |S )Nr6   z
fileno=%s  rL   zaddress=%s:%sz
address=%sz<error>r   __self__z<bound method %s.%s of self>z handle=)r1   r6   rD   	ExceptionrS   r;   r5   tuplelen__dict__getgetattr	__class__r\   rT   )r$   rD   rY   resultr   fselfhandle_reprr   r   r   r_     sH   

zBaseServer._formatinfoc                 C      t | jtr| jd S dS )z0IP address that the server is bound to (string).r   Nr;   r5   re   r(   r   r   r   server_host0     
zBaseServer.server_hostc                 C   rn   )z.Port that the server is bound to (an integer).r   Nro   r(   r   r   r   server_port6  rq   zBaseServer.server_portc                 C   rZ   )a7  
        If the user initialized the server with an address rather than
        socket, then this function must create a socket, bind it, and
        put it into listening mode.

        It is not supposed to be called by the user, it is called by :meth:`start` before starting
        the accept loop.
        Nr   r(   r   r   r   init_socket<  s    zBaseServer.init_socketc                 C   s   | j   S r   )r   is_setr(   r   r   r   r@   F     zBaseServer.startedc                 C   s2   |    | j  z|   W dS    |    )zStart accepting the connections.

        If an address was provided in the constructor, then also create a socket,
        bind it and put it into the listening mode.
        N)rs   r   clearrA   r   r(   r   r   r   rE   J  s   
zBaseServer.startc                 C   s  | j   z~|   W zFz| j  W n	 ty   Y nw W | jdd | jdd | jdd | jdd | jdd | jdurP| jj	
| j dS dS | jdd | jdd | jdd | jdd | jdd | jdur| jj	
| j w w zDz| j  W n	 ty   Y nw W | jdd | jdd | jdd | jdd | jdd | jdur| jj	
| j w w | jdd | jdd | jdd | jdd | jdd | jdur| jj	
| j w w )z-Close the listener socket and stop accepting.r6   Nr   r   r:   r9   )r   r   rG   r6   r   rd   rg   popr   r=   unlinkr?   r(   r   r   r   r   X  s^   





zBaseServer.closec                 C   s   t | d S )Nr6   )r1   r(   r   r   r   closedp  ru   zBaseServer.closedc                 C   sB   |    |du r| j}| jr| jj|d | jjddd dS dS )aX  
        Stop accepting the connections and close the listening socket.

        If the server uses a pool to spawn the requests, then
        :meth:`stop` also waits for all the handlers to exit. If there
        are still handlers executing after *timeout* has expired
        (default 1 second, :attr:`stop_timeout`), then the currently
        running handlers in the pool are killed.

        If the server does not use a pool, then this merely stops accepting connections;
        any spawned greenlets that are handling requests continue running until
        they naturally complete.
        NtimeoutTr   )blockr{   )r   stop_timeoutr   joinkill)r$   r{   r   r   r   r+   t  s   zBaseServer.stopc              
   C   sJ   | j s|   z| j  W tj| j|d  dS tj| j|d  w )zOStart the server if it hasn't been already started and wait until it's stopped.rz   N)r@   rE   r   waitr   r&   r+   r~   )r$   r}   r   r   r   serve_forever  s
   .zBaseServer.serve_foreverc                 C   s   t |tjo|jd | jv S )Nr   )r;   _socketerrorr-   fatal_errors)r$   rY   r   r   r   rP     s   zBaseServer.is_fatal_error)Nr   r   ),r\   
__module____qualname____doc__r   rW   r"   r   r&   r:   r}   errnoEBADFEINVALENOTSOCKr   r'   r)   r.   r   r   r   r?   rA   rG   rI   rH   rK   rF   r9   r`   ra   r_   propertyrp   rr   rs   r@   rE   r   ry   r+   r   rP   r   r   r   r   r   '   sN    .



%%







c                 C   s4   |  dr| dr| dd } tj| fS tj| fS )N[]r   )
startswithendswithr   AF_INET6AF_INET)hostr   r   r   _extract_family  s   

r   c                 C   s   t | tr| d rd| d v rtj| fS tj| fS t | tr"d| vs't | tr0tjdt| ffS t | ts=tdt	|  | 
dd\}}t|\}}|dkrQd}||t|ffS )Nr   :rb   z Expected tuple or string, got %sr   *)r;   re   r   r   r   r   r	   intr2   r[   rsplitr   )r5   r   portr3   r   r   r   _parse_address  s   



r   c              
   C   s4   zt | W S  ty } ztd| |f d }~ww )NzFailed to parse address %r: %s)r   r#   )r5   rY   r   r   r   r7     s   
r7   )r   
__future__r   r   r   rN   r   r   gevent.greenletr   gevent.eventr   
gevent.hubr   gevent._compatr   r	   r
   __all__r   objectr   r   r   r7   r   r   r   r   <module>   s*      s