o
    NK&h$                     @  s   d dl mZ d dlZd dlmZ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 d d
lmZ d dlmZ d dlmZ d dlmZ er`d dlm Z  G dd dZ!G dd dZ"dS )    )annotationsN)TYPE_CHECKINGOptional)Header)
BadRequestServerError)Default)Stage)error_loggerlogger)ASGIReceive	ASGIScopeASGISendMockTransport)Request)BaseHTTPResponse)ConnInfo)WebSocketConnection)Sanicc                   @  s4   e Zd Zdd	d
ZdddZdddZdddZdS )Lifespanscoper   receiver   sendr   returnNonec                 C  s`   || _ || _|| _|| _d| j jjv rtjdddid d| j jjv r.tjdddid d S d S )Nzserver.init.beforezYou have set a listener for "before_server_start" in ASGI mode. It will be executed as early as possible, but not before the ASGI server is started.	verbosity   )extrazserver.shutdown.afterzYou have set a listener for "after_server_stop" in ASGI mode. It will be executed as late as possible, but not after the ASGI server is stopped.)	sanic_appr   r   r   signal_router
name_indexr   debug)selfr   r   r   r    r#   =/var/www/html/venv/lib/python3.10/site-packages/sanic/asgi.py__init__   s   
zLifespan.__init__c                   s\   | j  I dH  | j ddI dH  | j ddI dH  t| j jjts,td dS dS )ay  
        Gather the listeners to fire on server start.
        Because we are using a third-party server and not Sanic server, we do
        not have access to fire anything BEFORE the server starts.
        Therefore, we fire before_server_start and after_server_start
        in sequence since the ASGI lifespan protocol only supports a single
        startup event.
        NinitbeforeafterzYou have set the USE_UVLOOP configuration option, but Sanic cannot control the event loop when running in ASGI mode.This option will be ignored.)	r   _startup_server_event
isinstanceconfig
USE_UVLOOPr   warningswarnr"   r#   r#   r$   startup1   s   	zLifespan.startupc                   s.   | j ddI dH  | j ddI dH  dS )au  
        Gather the listeners to fire on server stop.
        Because we are using a third-party server and not Sanic server, we do
        not have access to fire anything AFTER the server stops.
        Therefore, we fire before_server_stop and after_server_stop
        in sequence since the ASGI lifespan protocol only supports a single
        shutdown event.
        shutdownr'   Nr(   )r   r*   r0   r#   r#   r$   r2   E   s   	zLifespan.shutdownc              
     s  	 |   I d H }|d dkrHz	|  I d H  W n$ ty< } zt| | dt|dI d H  W Y d }~nQd }~ww | ddiI d H  nA|d dkrz	|  I d H  W n% ty| } zt| | dt|dI d H  W Y d }~d S d }~ww | dd	iI d H  d S q)
NTtypezlifespan.startupzlifespan.startup.failed)r3   messagezlifespan.startup.completezlifespan.shutdownzlifespan.shutdown.failedzlifespan.shutdown.complete)r   r1   	Exceptionr
   	exceptionr   strr2   )r"   r4   er#   r#   r$   __call__Q   s8   

zLifespan.__call__N)r   r   r   r   r   r   r   r   r   r   )__name__
__module____qualname__r%   r1   r2   r9   r#   r#   r#   r$   r      s
    


r   c                   @  s   e Zd ZU ded< ded< ded< ded< d	ed
< ded< ded< ed'ddZd(ddZdd Zd)ddZd d! Z	d"Z
d*d$d%Zd&S )+ASGIAppr   r   r   requestr   	transportr   lifespanzOptional[WebSocketConnection]wsr	   stagezOptional[BaseHTTPResponse]responser   r   r   r   r   r   r   c                   sx  |  }d |_ ||_t||||_|j|j_tj|_d |_d|jj	_
t|jd|jj ztdd |dg D }W n tyE   tdw |d dkrU|d	 }|d
 }n|d dkrhd}d}|j|||_ ntd|d |d }	}
|
r|	ddd }	d|	|
f }	|jpt}||	||||j||_|j|j ||j_d|_t|j|j_|jjddd|jiddI d H  |S )NTadd_taskc                 S  s&   g | ]\}}| d |j ddfqS )ASCIIsurrogateescape)errors)decode).0keyvaluer#   r#   r$   
<listcomp>   s    
z"ASGIApp.create.<locals>.<listcomp>headersz1Header names can only contain US-ASCII charactersr3   httphttp_versionmethod	websocketz1.1GETzReceived unknown ASGI scoperaw_pathquery_string   ?r   r   s   %b?%bzhttp.lifecycle.requestr?   F)inlinecontextfail_not_found)rB   r   r   r@   loopr	   IDLErC   rD   state
is_startedsetattrcreate_taskr   getUnicodeDecodeErrorr   create_websocket_connectionr   splitrequest_classr   r?   _currentsetstreamrequest_bodyr   	conn_infodispatch)clsr   r   r   r   instancerN   versionrQ   	url_bytesqueryrd   r#   r#   r$   createt   sn   


	

zASGIApp.createOptional[bytes]c                   sP   | j tju rtj| _ | j I dH }|dd}|dds&d| _|s&dS |S )zS
        Read and stream the body in chunks from an incoming ASGI message.
        Nbody    	more_bodyF)rC   r	   r[   REQUESTr@   r   r`   rh   )r"   r4   rr   r#   r#   r$   read   s   zASGIApp.readc                 C s.   | j r|  I d H }|r|V  | j sd S d S )N)rh   rv   )r"   datar#   r#   r$   	__aiter__   s   zASGIApp.__aiter__r   c                 C  s@   | j tjurtj| _ td| jd urd | j_| ||_| _|S )NzResponse already started)rC   r	   HANDLERFAILEDRuntimeErrorrD   rg   )r"   rD   r#   r#   r$   respond   s   
zASGIApp.respondc                   s   | j tju r|r|rtdd S | jr<| j tju r<| jd| jj| jj	dI d H  t
| jdd }|r<|r:|| n|}|rAtjntj| _ | jdt|drR| n|| dI d H  d S )NzvThere is no request to respond to, either the response has already been sent or the request has not been received yet.zhttp.response.start)r3   statusrN   rr   zhttp.response.bodyencode)r3   rr   rt   )rC   r	   r[   r{   rD   ry   r@   r   r}   processed_headersgetattrRESPONSEhasattrr~   )r"   rw   
end_streamresponse_bodyr#   r#   r$   r      s0   
zASGIApp.sendTr   c                   s   zt j| _| j| jI dH  W dS  tyX } z:z| j| j|I dH  W n tyE } z| j| j|dI dH  W Y d}~nd}~ww W Y d}~dS W Y d}~dS d}~ww )z.
        Handle the incoming request.
        NF)r	   ry   rC   r   handle_requestr?   r5   handle_exception)r"   r8   excr#   r#   r$   r9      s   $zASGIApp.__call__N)
r   r   r   r   r   r   r   r   r   r>   )r   rq   )rD   r   r:   )r;   r<   r=   __annotations__classmethodrp   rv   rx   r|   r   _asgi_single_callabler9   r#   r#   r#   r$   r>   k   s    
 
K
	r>   )#
__future__r   r.   typingr   r   sanic.compatr   sanic.exceptionsr   r   sanic.helpersr   
sanic.httpr	   	sanic.logr
   r   sanic.models.asgir   r   r   r   sanic.requestr   sanic.responser   sanic.serverr   "sanic.server.websockets.connectionr   sanicr   r   r>   r#   r#   r#   r$   <module>   s"    T