o
    NK&hv$                     @  s   d dl mZ d dlmZmZ d dlmZ erd dlm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mZ G d
d de	jZdddZdS )    )annotations)TYPE_CHECKINGOptional)RequestCancelled)SanicN)	Transport)	monotonic)error_logger)ConnInfoSignalc                   @  s~   e Zd ZdZddddd ddZedd	 Zd
d Zdd Zd!d"ddZ	dd Z
dd Zdd Zdd Zdd Zd#ddZdS )$SanicProtocol)apploop	transportconnections	conn_infosignal
_can_write_time_task_unix_data_receivedN)r   r   unixr   r   c                K  sv   t | || _|| _|pt | _d | _|d ur|nt | _d | _	t 
 | _| j  || _d| _d | _t 
 | _d S )Ng        )asyncioset_event_loopr   r   r   r   r   setr   r   Eventr   r   r   r   r   )selfr   r   r   r   r   kwargs r   W/var/www/html/venv/lib/python3.10/site-packages/sanic/server/protocols/base_protocol.py__init__$   s   



zSanicProtocol.__init__c                 C  s   | j d ur	| j jS d S N)r   ctxr   r   r   r    r#   <   s   
zSanicProtocol.ctxc                   s8   | j  I dH  | j rt| j| t | _dS )zN
        Generic data write implementation with backpressure control.
        N)r   waitr   
is_closingr   writecurrent_timer   r   datar   r   r    sendC   s   
zSanicProtocol.sendc                   s*   | j   | j  | j I dH  dS )zT
        Wait until more data is received into the Server protocol's buffer
        N)r   resume_readingr   clearr%   r$   r   r   r    receive_moreM   s   

zSanicProtocol.receive_moretimeoutOptional[float]c              	   C  s   | j du s
| j  rdS | j  }| j   z| j  }W n ttfy+   d}Y nw |s2|dkr<|du r;| jj	j
}n|du rBd}| jt| | j| dS )z/
        Attempt close the connection.
        Nr   )r   r&   r   is_setcloseget_write_buffer_sizeAttributeErrorNotImplementedErrorr   configGRACEFUL_TCP_CLOSE_TIMEOUTr   	call_soon_async_protocol_transport_close)r   r/   write_was_paused	data_leftr   r   r    r2   U   s*   

zSanicProtocol.closec                 C  s   | j r| j   d| _ dS dS )z-
        Force close the connection.
        N)r   abortr$   r   r   r    r<      s   

zSanicProtocol.abortc                 C  sX   z|j ddd | j|  || _t| j| jd| _W dS  ty+   t	d Y dS w )z
        Generic connection-made, with no connection_task, and no recv_buffer.
        Override this for protocol-specific connection implementations.
        i @  i   )lowhigh)r   zprotocol.connect_madeN)
set_write_buffer_limitsr   addr   r
   r   r   	Exceptionr	   	exception)r   r   r   r   r    connection_made   s   zSanicProtocol.connection_madec                 C  sX   z| j |  |   d| j_| jr| j  W dS W dS  ty+   t	d Y dS w )a  
        This is a callback handler that is called from the asyncio
        transport layer implementation (eg, UVLoop's UVStreamTransport).
        It is scheduled to be called async after the transport has closed.
        When data is still in the send buffer, this call to connection_lost
        will be delayed until _after_ the buffer is finished being sent.

        So we can use this callback as a confirmation callback
        that the async write-buffer transfer is finished.
        Tzprotocol.connection_lostN)
r   discardresume_writingr   lostr   cancelBaseExceptionr	   rB   )r   excr   r   r    connection_lost   s   zSanicProtocol.connection_lostc                 C     | j   d S r"   )r   r-   r$   r   r   r    pause_writing      zSanicProtocol.pause_writingc                 C  rK   r"   )r   r   r$   r   r   r    rE      rM   zSanicProtocol.resume_writingr*   bytesc                 C  sR   zt  | _|s|  W S | jr| j  W d S W d S  ty(   td Y d S w )Nzprotocol.data_received)r(   r   r2   r   r   rH   r	   rB   r)   r   r   r    data_received   s   
zSanicProtocol.data_received)r   r   r"   )r/   r0   )r*   rN   )__name__
__module____qualname__	__slots__r!   propertyr#   r+   r.   r2   r<   rC   rJ   rL   rE   rO   r   r   r   r    r      s"    

.r   protocolr   asyncio.AbstractEventLoopr/   floatc              	   C  s   | j du rdS | jdur| jjrd| _ dS | j  std| j  }z| j  }W n tt	fy8   d}Y nw |s?|dkr`|dkrL|
tj|  dS t|d}|| }||t| || dS |
tj|  dS )a  
    This function is scheduled to be called after close() is called.
    It checks that the transport has shut down properly, or waits
    for any remaining data to be sent, and aborts after a timeout.
    This is required if the transport is closed while there is an async
    large async transport write operation in progress.
    This is observed when NGINX reverse-proxy is the client.
    NzNYou must call transport.close() before protocol._async_transport_close() runs.r   g?)r   r   rF   r&   RuntimeErrorr   r1   r3   r4   r5   r8   r   r<   min
call_laterr9   )rU   r   r/   write_is_pausedr;   next_check_intervalnext_check_timeoutr   r   r    r9      s8   
	

r9   )rU   r   r   rV   r/   rW   )
__future__r   typingr   r   sanic.exceptionsr   	sanic.appr   r   asyncio.transportsr   timer   r(   	sanic.logr	   sanic.models.server_typesr
   r   Protocolr   r9   r   r   r   r    <module>   s     1