o
    4ήc>                     @   s   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m	Z	m
Z
mZmZ er:d dlmZmZmZmZmZmZmZmZ d dlmZmZmZmZ dddd	d
ejdefddZG dd dZG dd dZdS )    N)deque)TYPE_CHECKINGDequeIterableOptionalTuple)ASGIReceiveCallableASGIReceiveEventASGISendCallableASGISendEventHTTPRequestEventHTTPResponseBodyEventHTTPResponseStartEvent	HTTPScope)EnvironExcInfoStartResponseWSGIAppscoper   messager	   bodyreturnc                 C   s*  | d d| d  dd| d dd| d	  d
| dd|tjdddd}| d}|du r2d}|d |d< |d |d< | d}|durM|d |d< | dg D ]?\}}|d}|dkrcd}	n|dkrjd}	n
d| dd  }	|d}
|	|v r||	 }t|tsJ |d! |
 }
|
||	< qS|S )"zH
    Builds a scope and request message into a WSGI environ object.
    method pathutf8latin1query_stringasciizHTTP/%shttp_version)   r   schemehttpTF)REQUEST_METHODSCRIPT_NAME	PATH_INFOQUERY_STRINGSERVER_PROTOCOLzwsgi.versionzwsgi.url_schemez
wsgi.inputzwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_onceserverN)	localhostP   r   SERVER_NAMEr    SERVER_PORTclientREMOTE_ADDRheaderszcontent-lengthCONTENT_LENGTHzcontent-typeCONTENT_TYPEzHTTP_%s-_,)	encodedecodegetsysstdoutupperreplace
isinstancestr)r   r   r   environr(   r-   namevaluename_strcorrected_name	value_strcorrected_name_environ rE   >/tmp/pip-target-vg8gfxp4/lib/python/uvicorn/middleware/wsgi.pybuild_environ   sF   






rG   c                   @   s:   e Zd ZddedefddZ						
			dddZdS )WSGIMiddleware
   appworkersc                 C   s   || _ tjj|d| _d S )N)max_workers)rJ   
concurrentfuturesThreadPoolExecutorexecutor)selfrJ   rK   rE   rE   rF   __init__M   s   zWSGIMiddleware.__init__r   r   receiver   sendr
   r   Nc                    s6   |d dks	J t | j| j|}|||I d H  d S )Ntyper"   )WSGIResponderrJ   rP   )rQ   r   rS   rT   instancerE   rE   rF   __call__Q   s   zWSGIMiddleware.__call__)rI   )r   r   rS   r   rT   r
   r   N)__name__
__module____qualname__r   intrR   rX   rE   rE   rE   rF   rH   L   s    rH   c                	   @   s   e Zd ZdedejjddfddZ					
		dddZdddZ		dde
deee
e
f  dee ddfddZdededdfddZdS )rV   rJ   rP   r   r   c                 C   sJ   || _ || _|| _d | _d | _t | _t | _	t
 | _d| _d | _d S )NF)rJ   rP   r   statusresponse_headersasyncioEvent
send_eventr   
send_queueget_event_looploopresponse_startedexc_info)rQ   rJ   rP   r   rE   rE   rF   rR   ]   s   


zWSGIResponder.__init__rS   r   rT   r
   r   Nc           
   
      sR  | I d H }t |dd}|dd}|r=|dt j |r8| I d H }||dd |dd}|s!|d t| j||}t	 | _
| j
| j| j|| j}| j
| |}	zt|d I d H  W | jd  | j  t|	d I d H  n| jd  | j  t|	d I d H  w | jd ur| jd | jd | jd d S )Nr       	more_bodyFr   r       )ioBytesIOr7   seekSEEK_ENDwriterG   r   r_   rc   rd   run_in_executorrP   wsgistart_responsecreate_tasksenderwait_forrb   appendra   setrf   with_traceback)
rQ   rS   rT   r   r   rh   body_messager>   rp   rs   rE   rE   rF   rX   n   s<   





zWSGIResponder.__call__c                    sL   	 | j r| j  }|d u rd S ||I d H  n| j I d H  | j  qN)rb   popleftra   waitclear)rQ   rT   r   rE   rE   rF   rs      s   

zWSGIResponder.senderr]   r^   rf   c           	      C   sh   || _ | js2d| _|dd\}}t|}dd |D }d||d}| j| | j| jj	 d S d S )NT r    c                 S   s$   g | ]\}}| d | d fqS )r   )r5   ).0r?   r@   rE   rE   rF   
<listcomp>   s    z0WSGIResponder.start_response.<locals>.<listcomp>zhttp.response.start)rU   r]   r/   )
rf   re   splitr\   rb   ru   rd   call_soon_threadsafera   rv   )	rQ   r]   r^   rf   status_code_strr3   status_coder/   http_response_start_eventrE   rE   rF   rq      s   zWSGIResponder.start_responser>   rq   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)rU   r   rh   rg   F)rJ   rb   ru   rd   r   ra   rv   )rQ   r>   rq   chunkresponse_body
empty_bodyrE   rE   rF   rp      s   zWSGIResponder.wsgi)rS   r   rT   r
   r   N)rT   r
   r   Nry   )rY   rZ   r[   r   rM   rN   rO   rR   rX   rs   r=   r   r   r   r   rq   r   r   rp   rE   rE   rE   rF   rV   \   s6    



rV   )r_   concurrent.futuresrM   rj   r8   collectionsr   typingr   r   r   r   r   asgiref.typingr   r	   r
   r   r   r   r   r   uvicorn._typesr   r   r   r   rk   rG   rH   rV   rE   rE   rE   rF   <module>   s(    (
5