U
    nËjÒ2  ã                   @  s2  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dl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mZmZmZ d dlZd dlmZ eräd dlmZ d dlmZ d d	lmZ d d
lmZ eeeeef Z ej!ej"fZ#e	jdk�re#ej$f7 Z#e %d¡Z&G dd„ dƒZ'G dd„ dƒZ(dS )é    )ÚannotationsN)Ú
formatdate)Ú	FrameType)ÚTYPE_CHECKINGÚ	GeneratorÚSequenceÚUnion)ÚConfig)ÚH11Protocol)ÚHttpToolsProtocol)ÚWebSocketProtocol)Ú
WSProtocolÚwin32zuvicorn.errorc                   @  s   e Zd ZdZddœdd„ZdS )ÚServerStatezP
    Shared servers state that is available between all protocol instances.
    ÚNone©Úreturnc                 C  s    d| _ tƒ | _tƒ | _g | _d S )Nr   )Útotal_requestsÚsetÚconnectionsÚtasksÚdefault_headers©Úself© r   ú2/tmp/pip-unpacked-wheel-8f32qnwz/uvicorn/server.pyÚ__init__,   s    zServerState.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   '   s   r   c                   @  sØ   e Zd Zdddœdd„Zd(dddœd	d
„Zd)dddœdd„Zd*dddœdd„Zd+dddœdd„Zdddœdd„Zddœdd„Z	dddœdd„Z
d,dddœdd„Zddœdd „Zejd!dœd"d#„ƒZdd$dd%œd&d'„ZdS )-ÚServerr	   r   )Úconfigr   c                 C  s0   || _ tƒ | _d| _d| _d| _d| _g | _d S )NFg        )r"   r   Úserver_stateÚstartedÚshould_exitÚ
force_exitÚlast_notifiedÚ_captured_signals)r   r"   r   r   r   r   4   s    zServer.__init__Nzlist[socket.socket] | None)Úsocketsr   c                 C  s   | j  ¡  t | j|d�¡S )N©r)   )r"   Zsetup_event_loopÚasyncioÚrunÚserve©r   r)   r   r   r   r,   ?   s    
z
Server.runc              	   Ã  s(   |   ¡ � |  |¡I d H  W 5 Q R X d S )N)Úcapture_signalsÚ_server.   r   r   r   r-   C   s    
zServer.servec                 Ã  sÄ   t  ¡ }| j}|js| ¡  | |¡| _d}dtjddd� d }t	j
||d|id� | j|d	�I d H  | jrrd S |  ¡ I d H  | j|d	�I d H  d
}dtjddd� d }t	j
||d|id� d S )NzStarted server process [%d]zStarted server process [z%dZcyan)Zfgú]Úcolor_message©Úextrar*   zFinished server process [%d]zFinished server process [)ÚosÚgetpidr"   ZloadedÚloadZlifespan_classÚlifespanÚclickÚstyleÚloggerÚinfoÚstartupr%   Ú	main_loopÚshutdown)r   r)   Z
process_idr"   Úmessager2   r   r   r   r0   G   s     zServer._servec              
   ƒ  sH  ˆj  ¡ I d H  ˆj jr"dˆ_d S ˆj‰ ddddœ‡ ‡fdd„}t ¡ }|d k	rÂdddœd	d
„}g ˆ_|D ]N}t ¡ dk}ˆ j	dkr�|r�||ƒ}|j
||ˆ jˆ jd�I d H }ˆj |¡ qj|}�nfˆ jd k	�r t ˆ jtjtj¡}|j
||ˆ jˆ jd�I d H }|jd k	�st‚|j}|gˆ_�nˆ jd k	�ršd}	tj ˆ j¡�rNt ˆ j¡j}	|j|ˆ jˆ jˆ jd�I d H }t ˆ j|	¡ |jd k	�sŠt‚|j}|gˆ_nŽz&|j
|ˆ jˆ jˆ jˆ jd�I d H }W nH tk
�r }
 z(t  !|
¡ ˆj  "¡ I d H  t# $d¡ W 5 d }
~
X Y nX |jd k	�st‚|j}|gˆ_|d k�r>ˆ %|¡ n dˆ_&d S )NTz asyncio.AbstractEventLoop | Nonezasyncio.Protocol)Ú_loopr   c                   s   ˆ j ˆ ˆjˆjj| d�S )N)r"   r#   Z	app_staterA   )Zhttp_protocol_classr#   r8   Ústate)rA   ©r"   r   r   r   Úcreate_protocolf   s    üz'Server.startup.<locals>.create_protocolzsocket.SocketType)Úsockr   c                 S  s"   ddl m} |  t ¡ ¡}||ƒS )Nr   )Ú	fromshare)ÚsocketrF   Zsharer5   r6   )rE   rF   Z	sock_datar   r   r   Ú_share_socketw   s    z%Server.startup.<locals>._share_socketÚWindowsé   )rE   ÚsslÚbacklogi¶  )ÚpathrK   rL   )ÚhostÚportrK   rL   )N)'r8   r=   r%   r"   r+   Zget_running_loopÚserversÚplatformÚsystemÚworkersÚcreate_serverrK   rL   ÚappendÚfdrG   ÚfromfdÚAF_UNIXÚSOCK_STREAMr)   ÚAssertionErrorÚudsr5   rM   ÚexistsÚstatÚst_modeZcreate_unix_serverÚchmodrN   rO   ÚOSErrorr;   Úerrorr?   ÚsysÚexitÚ_log_started_messager$   )r   r)   rD   ZlooprH   rE   Z
is_windowsÚserverÚ	listenersZ	uds_permsÚexcr   rC   r   r=   ^   sp     ÿ

   ÿ
û

zServer.startupzSequence[socket.SocketType])rf   r   c           
      C  sÒ   | j }|jd k	r*|d }t d| ¡ ¡ n¤|jd k	rDt d|j¡ nŠd}|jd krVdn|j}d|krhd}|j}|dkr†|d  ¡ d }|jr�d	nd
}d|› d�}dt	j
|dd� d }	tj||||d|	id� d S )Nr   z3Uvicorn running on socket %s (Press CTRL+C to quit)z8Uvicorn running on unix socket %s (Press CTRL+C to quit)z
%s://%s:%dz0.0.0.0ú:z%s://[%s]:%drJ   ÚhttpsÚhttpzUvicorn running on z (Press CTRL+C to quit)T)Zboldr2   r3   )r"   rV   r;   r<   Úgetsocknamer[   rN   rO   rK   r9   r:   )
r   rf   r"   rE   Zaddr_formatrN   rO   Zprotocol_namer@   r2   r   r   r   rd   »   s4    
þ
ûzServer._log_started_messager   c                 Ã  sN   d}|   |¡I d H }|sJ|d7 }|d }t d¡I d H  |   |¡I d H }qd S )Nr   rJ   i / çš™™™™™¹?)Úon_tickr+   Úsleep)r   Úcounterr%   r   r   r   r>   Þ   s    zServer.main_loopÚintÚbool)ro   r   c                 Ã  sÀ   |d dkr€t   ¡ }t|dd� ¡ }| jjr8d|fg}ng }|| jj | j_| jjd k	r€|| j	 | jj
kr€|| _	| j ¡ I d H  | jrŠdS | jj}|d k	r¼| jj|kr¼t d|› d�¡ dS dS )	Né
   r   T)Úusegmts   datezMaximum request limit of z exceeded. Terminating process.F)Útimer   Úencoder"   Údate_headerZencoded_headersr#   r   Zcallback_notifyr'   Ztimeout_notifyr%   Zlimit_max_requestsr   r;   Úwarning)r   ro   Úcurrent_timeZcurrent_daterv   Zmax_requestsr   r   r   rm   ç   s$    zServer.on_tickc                 Ã  sò   t  d¡ | jD ]}| ¡  q|p$g D ]}| ¡  q&t| jjƒD ]}| ¡  q@t 	d¡I d H  z tj
|  ¡ | jjd�I d H  W nX tjk
rÖ   t  dt| jjƒ¡ | jjD ]$}tjdk rÄ| ¡  q¬|jdd� q¬Y nX | jsî| j ¡ I d H  d S )NzShutting downrl   )Útimeoutz=Cancel %s running task(s), timeout graceful shutdown exceeded)é   é	   z2Task cancelled, timeout graceful shutdown exceeded)Úmsg)r;   r<   rP   ÚcloseÚlistr#   r   r?   r+   rn   Úwait_forÚ_wait_tasks_to_completer"   Ztimeout_graceful_shutdownÚTimeoutErrorra   Úlenr   rb   Úversion_infoÚcancelr&   r8   )r   r)   re   rE   Ú
connectionÚtr   r   r   r?     s0    




þ
þ

zServer.shutdownc                 Ã  s–   | j jr<| js<d}t |¡ | j jr<| js<t d¡I d H  q| j jrx| jsxd}t |¡ | j jrx| jsxt d¡I d H  qX| jD ]}| 	¡ I d H  q~d S )Nz8Waiting for connections to close. (CTRL+C to force quit)rl   z@Waiting for background tasks to complete. (CTRL+C to force quit))
r#   r   r&   r;   r<   r+   rn   r   rP   Zwait_closed)r   r|   re   r   r   r   r€   (  s    


zServer._wait_tasks_to_completezGenerator[(None, None, None)]c                 #  sv   t  ¡ t  ¡ k	rd V  d S ‡ fdd„tD ƒ}z
d V  W 5 | ¡ D ]\}}t ||¡ q@X tˆ jƒD ]}t |¡ qbd S )Nc                   s   i | ]}|t   |ˆ j¡“qS r   )ÚsignalÚhandle_exit)Ú.0Úsigr   r   r   Ú
<dictcomp>B  s      z*Server.capture_signals.<locals>.<dictcomp>)	Ú	threadingÚcurrent_threadÚmain_threadÚHANDLED_SIGNALSÚitemsr‡   Úreversedr(   Úraise_signal)r   Zoriginal_handlersrŠ   ÚhandlerZcaptured_signalr   r   r   r/   :  s    
zServer.capture_signalszFrameType | None)rŠ   Úframer   c                 C  s.   | j  |¡ | jr$|tjkr$d| _nd| _d S )NT)r(   rU   r%   r‡   ÚSIGINTr&   )r   rŠ   r”   r   r   r   rˆ   N  s    zServer.handle_exit)N)N)N)N)N)r   r   r   r   r,   r-   r0   r=   rd   r>   rm   r?   r€   Ú
contextlibÚcontextmanagerr/   rˆ   r   r   r   r   r!   3   s   ]#	#r!   ))Ú
__future__r   r+   r–   Úloggingr5   rQ   r‡   rG   rb   rŒ   rt   Úemail.utilsr   Útypesr   Útypingr   r   r   r   r9   Zuvicorn.configr	   Zuvicorn.protocols.http.h11_implr
   Z%uvicorn.protocols.http.httptools_implr   Z,uvicorn.protocols.websockets.websockets_implr   Z)uvicorn.protocols.websockets.wsproto_implr   Z	Protocolsr•   ÚSIGTERMr�   ZSIGBREAKÚ	getLoggerr;   r   r!   r   r   r   r   Ú<module>   s:   þ
