a
    a*j                  	   @   s  d dl Z d dlmZmZmZmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZ d dlmZ d dlmZmZ d d	lmZmZmZmZmZ d d
lmZmZ ee eee dddZedddZeeee eeee eee  f dddZ!eeee eeee ef dddZ"eeee eeee ef dddZ#eee edddZ$G dd deZ%G dd dZ&G dd  d Z'dS )!    N)CallableIterableOptionalTuple)	Starlette)MutableHeaders)BaseHTTPMiddlewareRequestResponseEndpoint)Request)Response)	BaseRouteMatch)ASGIAppMessageScopeReceiveSend)Limiter_rate_limit_exceeded_handler)routesscopereturnc                 C   s:   d }| D ],}| |\}}|tjkrt|dr|j}q|S )Nendpoint)matchesr   ZFULLhasattrr   )r   r   handlerZroutematch_ r   N/var/www/html/assistant/venv/lib/python3.9/site-packages/slowapi/middleware.py_find_route_handler   s    r    r   c                 C   s   | j  d| j S )N.)
__module____name__r!   r   r   r   _get_route_name   s    r%   )limiterrequestr   appr   c              
   C   sp   | j rlt|jddslz| ||d W n@ tyf } z(|jt|t}|d|fW  Y d}~S d}~0 0 dS dS )a  
    Utils to check (if needed) current requests limit.
    It returns a tuple of size 3:
        1. The exception handler to run, if needed
        2. a bool, True if we need to inject some headers, False otherwise
        3. the exception that happened, if any
    Z_rate_limiting_completeFTN)NTN)NFN)	Z_auto_checkgetattrstateZ_check_request_limit	ExceptionZexception_handlersgettyper   )r&   r'   r   r(   eexception_handlerr   r   r   _check_limits!   s    
 r0   c                 C   s@   t | |||\}}}|r|s$d|fS t|r2t}||||fS )a  
    Returns a `Response` object if an error occurred, as well as a boolean to know
    whether we should inject headers or not.
    Used in our WSGI middleware, it only supports synchronous exception_handler.
    This will fallback on _rate_limit_exceeded_handler otherwise.
    N)r0   inspectiscoroutinefunctionr   r&   r'   r   r(   r/   _boolexcr   r   r   sync_check_limits;   s    	
r6   c                    sP   t | |||\}}}|s d|fS t|r>|||I dH |fS ||||fS dS )z
    Returns a `Response` object if an error occurred, as well as a boolean to know
    whether we should inject headers or not.
    Used in our ASGI middleware, this support both synchronous or asynchronous exception handlers.
    N)r0   r1   r2   r3   r   r   r   async_check_limitsP   s    
r7   )r&   r   r   c                 C   s4   |d u rdS t |}|| jv r"dS || jv r0dS dS )NTF)r%   Z_exempt_routesZ_route_limits)r&   r   namer   r   r   _should_exemptb   s    

r9   c                   @   s   e Zd ZeeedddZdS )SlowAPIMiddleware)r'   	call_nextr   c           	         s   |j }|jj}|js"||I d H S t|j|j}t||rH||I d H S t||||\}}|d urf|S ||I d H }|r|	||jj
}|S N)r(   r*   r&   enabledr    r   r   r9   r6   Z_inject_headersview_rate_limit)	selfr'   r;   r(   r&   r   error_responseshould_inject_headersresponser   r   r   dispatchu   s     
zSlowAPIMiddleware.dispatchN)r$   r#   __qualname__r
   r	   r   rC   r   r   r   r   r:   t   s   r:   c                   @   s0   e Zd ZeddddZeeeddddZdS )SlowAPIASGIMiddlewareNr(   r   c                 C   s
   || _ d S r<   )r(   r?   r(   r   r   r   __init__   s    zSlowAPIASGIMiddleware.__init__r   receivesendr   c                    s<   |d dkr |  |||I d H S t| j |||I d H  d S )Nr-   http)r(   _ASGIMiddlewareResponder)r?   r   rJ   rK   r   r   r   __call__   s    zSlowAPIASGIMiddleware.__call__)	r$   r#   rD   r   rH   r   r   r   rN   r   r   r   r   rE      s   rE   c                   @   s@   e Zd ZeddddZeddddZeee	ddd	d
Z
dS )rM   NrF   c                 C   s   || _ d | _i | _d| _d S )NF)r(   r@   initial_messageinject_headersrG   r   r   r   rH      s    z!_ASGIMiddlewareResponder.__init__)messager   c                    s   |d dkr|| _ nl|d dkr| jr4| jj| j d< | jr^t| j d d}| j|| jjj	}| 
| j I d H  | 
|I d H  d S )Nr-   zhttp.response.startzhttp.response.bodystatusheaders)raw)rO   r@   status_coderP   r   r&   Z_inject_asgi_headersr'   r*   r>   rK   )r?   rQ   rS   r   r   r   send_wrapper   s    
z%_ASGIMiddlewareResponder.send_wrapperrI   c           
         s   || _ |d }|jj}|js2| ||| j I d H S t|j|}t||| j d}t||rn| ||| j I d H S t	||||I d H \}}	|d ur|||| j
I d H S |	rd| _|| _|| _| ||| j
I d H S )Nr(   )rJ   rK   T)rK   r*   r&   r=   r(   r    r   r
   r9   r7   rV   rP   r'   )
r?   r   rJ   rK   Z_appr&   r   r'   r@   rA   r   r   r   rN      s&    
z!_ASGIMiddlewareResponder.__call__)r$   r#   rD   r   rH   r   rV   r   r   r   rN   r   r   r   r   rM      s   rM   )(r1   typingr   r   r   r   Zstarlette.applicationsr   Zstarlette.datastructuresr   Zstarlette.middleware.baser   r	   Zstarlette.requestsr
   Zstarlette.responsesr   Zstarlette.routingr   r   Zstarlette.typesr   r   r   r   r   Zslowapir   r   r    r%   boolr+   r0   r6   r7   r9   r:   rE   rM   r   r   r   r   <module>   s4   