U
    Rh                     @  s   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m	Z	 d dl
mZ d dlmZmZmZmZmZmZmZmZmZmZmZmZ dddd	d
ddZG dd dZG dd dZzd dlmZ W n ek
r   eZY nX dS )    )annotationsN)deque)Iterable)ASGIReceiveCallableASGIReceiveEventASGISendCallableASGISendEventEnvironExcInfoHTTPRequestEventHTTPResponseBodyEventHTTPResponseStartEvent	HTTPScopeStartResponseWSGIAppr   r   z
io.BytesIOr	   )scopemessagebodyreturnc                 C  sf  |  dddd}| d dd}||rF|t|d }| d ||| d d	d
| d  d|  dd|tjdddd}|  d}|dkrd}|d |d< |d |d< |  d}|dk	r|d |d< |  dg D ]\}}	|d}
|
dkrd}n$|
dkrd}nd|
 d d! }|	d}||krX|| }t	|t
sLt|d" | }|||< q|S )#zH
    Builds a scope and request message into a WSGI environ object.
    Z	root_path utf8latin1pathNmethodZquery_stringasciizHTTP/%sZhttp_version)   r   ZschemehttpTF)ZREQUEST_METHODZSCRIPT_NAMEZ	PATH_INFOZQUERY_STRINGZSERVER_PROTOCOLzwsgi.versionzwsgi.url_schemez
wsgi.inputzwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_onceserver)Z	localhostP   r   ZSERVER_NAMEr   ZSERVER_PORTclientZREMOTE_ADDRheaderszcontent-lengthZCONTENT_LENGTHzcontent-typeZCONTENT_TYPEzHTTP_%s-_,)getencodedecode
startswithlensysstdoutupperreplace
isinstancestrAssertionError)r   r   r   script_nameZ	path_infoenvironr   r   namevalueZname_strZcorrected_nameZ	value_strZcorrected_name_environ r4   =./venv/lib/python3.8/site-packages/uvicorn/middleware/wsgi.pybuild_environ   sN    









r6   c                   @  s2   e Zd ZddddddZddd	d
dddZdS )_WSGIMiddleware
   r   int)appworkersc                 C  s&   t dt || _tjj|d| _d S )NzgUvicorn's native WSGI implementation is deprecated, you should switch to a2wsgi (`pip install a2wsgi`).)max_workers)warningswarnDeprecationWarningr:   
concurrentZfuturesZThreadPoolExecutorexecutor)selfr:   r;   r4   r4   r5   __init__S   s    z_WSGIMiddleware.__init__r   r   r   None)r   receivesendr   c                   s4   |d dkst t| j| j|}|||I d H  d S )Ntyper   )r/   WSGIResponderr:   rA   )rB   r   rE   rF   instancer4   r4   r5   __call__\   s    z_WSGIMiddleware.__call__N)r8   )__name__
__module____qualname__rC   rJ   r4   r4   r4   r5   r7   R   s   	r7   c                   @  sh   e Z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d	dddZddd	dddZdS )rH   r   z%concurrent.futures.ThreadPoolExecutorr   )r:   rA   r   c                 C  sJ   || _ || _|| _d | _d | _t | _t | _	t
 | _d| _d | _d S )NF)r:   rA   r   statusresponse_headersasyncioEvent
send_eventr   
send_queueget_event_looploopresponse_startedexc_info)rB   r:   rA   r   r4   r4   r5   rC   h   s    

zWSGIResponder.__init__r   r   rD   )rE   rF   r   c           
   
     s(  | I d H }t |dd}|dd}|rv|dt j |rl| I d H }||dd |dd}q<|d t| j||}t	 | _
| j
| j| j|| j}| j
| |}	zt|d I d H  W 5 | jd  | j  t|	d I d H  X | jd k	r$| jd | jd | jd d S )Nr       	more_bodyFr   r      )ioBytesIOr$   seekSEEK_ENDwriter6   r   rP   rT   rU   Zrun_in_executorrA   wsgistart_responseZcreate_tasksenderrS   appendrR   setwait_forrW   with_traceback)
rB   rE   rF   r   r   rY   Zbody_messager1   r`   rb   r4   r4   r5   rJ   y   s,    



zWSGIResponder.__call__)rF   r   c                   sL   | j r,| j  }|d krd S ||I d H  q | j I d H  | j  q d S )N)rS   popleftrR   waitclear)rB   rF   r   r4   r4   r5   rb      s    
zWSGIResponder.senderNr.   zIterable[tuple[str, str]]zExcInfo | None)rN   rO   rW   r   c           	      C  sd   || _ | js`d| _|dd\}}t|}dd |D }d||d}| j| | j| jj	 d S )NT r   c                 S  s$   g | ]\}}| d | d fqS )r   )r%   ).0r2   r3   r4   r4   r5   
<listcomp>   s     z0WSGIResponder.start_response.<locals>.<listcomp>zhttp.response.start)rG   rN   r    )
rW   rV   splitr9   rS   rc   rU   call_soon_threadsaferR   rd   )	rB   rN   rO   rW   Zstatus_code_strr"   Zstatus_coder    Zhttp_response_start_eventr4   r4   r5   ra      s    zWSGIResponder.start_responser	   r   )r1   ra   r   c                 C  sf   |  ||D ],}d|dd}| j| | j| jj qdddd}| j| | j| jj d S )Nzhttp.response.bodyT)rG   r   rY   rX   F)r:   rS   rc   rU   rn   rR   rd   )rB   r1   ra   chunkZresponse_bodyZ
empty_bodyr4   r4   r5   r`      s    zWSGIResponder.wsgi)N)rK   rL   rM   rC   rJ   rb   ra   r`   r4   r4   r4   r5   rH   g   s    rH   )WSGIMiddleware)Z
__future__r   rP   concurrent.futuresr@   r[   r)   r=   collectionsr   typingr   Zuvicorn._typesr   r   r   r   r	   r
   r   r   r   r   r   r   r6   r7   rH   Za2wsgirp   ModuleNotFoundErrorr4   r4   r4   r5   <module>   s   87^