U
    nËjô#  ã                   @  sÞ   d dl mZ d dl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mZ d dlmZmZmZmZmZ ejegeje f Zejeegeje f Ze d¡ZG d	d
„ d
eƒZG dd„ dƒZG dd„ deƒZdS )é    )ÚannotationsN)ÚObjectReceiveStreamÚObjectSendStream)Úcollapse_excgroups)ÚClientDisconnectÚRequest)ÚAsyncContentStreamÚResponse)ÚASGIAppÚMessageÚReceiveÚScopeÚSendÚTc                      s6   e Zd ZdZdddœ‡ fdd„Zddœd	d
„Z‡  ZS )Ú_CachedRequesta  
    If the user calls Request.body() from their dispatch function
    we cache the entire request body in memory and pass that to downstream middlewares,
    but if they call Request.stream() then all we do is send an
    empty body so that downstream things don't hang forever.
    r   r   )ÚscopeÚreceivec                   s(   t ƒ  ||¡ d| _d| _|  ¡ | _d S )NF)ÚsuperÚ__init__Ú_wrapped_rcv_disconnectedÚ_wrapped_rcv_consumedÚstreamZ_wrapped_rc_stream)Úselfr   r   ©Ú	__class__© ú=/tmp/pip-unpacked-wheel-pzfrzqh9/starlette/middleware/base.pyr      s    z_CachedRequest.__init__r   ©Úreturnc                 Ã  sò   | j rddiS | jr^| jr(d| _ ddiS |  ¡ I d H }|d dkrTtd|d › �ƒ‚d| _ |S t| dd ƒd k	r‚d| _d| jddœS | jršd| _dd	ddœS z0|  ¡ }| 	¡ I d H }| j| _d|| j dœW S  t
k
rì   d| _ ddi Y S X d S )
NÚtypeúhttp.disconnectTzUnexpected message received: Ú_bodyzhttp.requestF©r   ÚbodyÚ	more_bodyó    )r   r   Z_is_disconnectedr   ÚRuntimeErrorÚgetattrr!   Z_stream_consumedr   Ú	__anext__r   )r   Úmsgr   Úchunkr   r   r   Úwrapped_receive    sD    ýýýz_CachedRequest.wrapped_receive)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r+   Ú__classcell__r   r   r   r   r      s   r   c                   @  sF   e Zd Zdddddœdd„Zdd	d
ddœdd„Zddddœdd„ZdS )ÚBaseHTTPMiddlewareNr
   zDispatchFunction | NoneÚNone)ÚappÚdispatchr   c                 C  s   || _ |d kr| jn|| _d S ©N)r3   r4   Údispatch_func)r   r3   r4   r   r   r   r   _   s    zBaseHTTPMiddleware.__init__r   r   r   ©r   r   Úsendr   c                 ƒ  s¼   ˆd dkr$ˆ  ˆ||¡I d H  d S tˆ|ƒ}|j‰t ¡ ‰ dddœ‡ ‡‡‡‡fdd„}tƒ �T t ¡ 4 I d H š2‰ˆ ||¡I d H }|ˆˆ|ƒI d H  ˆ  ¡  W 5 Q I d H R X W 5 Q R X d S )Nr   Úhttpr   r	   )Úrequestr   c                 “  s.  d ‰ t  ¡ \‰‰ddœ‡‡	fdd„‰ddœ‡‡fdd„}dddœ‡fd	d
„‰ddœ‡ ‡‡‡‡‡fdd„}ˆ |¡ ˆ |¡ z@ˆ ¡ I d H }| dd ¡}|d dkrº|d k	rºˆ ¡ I d H }W n* t jk
ræ   ˆ d k	rÚˆ ‚tdƒ‚Y nX |d dksøt‚ddœ‡ ‡fdd„}t|d |ƒ |d�}|d |_	|S )Nr   r   c               
   “  sv   ˆ  ¡ rddiS t ¡ 4 I d H š6‰ dddœ‡ fdd„} ˆ  | ˆj¡ | ˆƒI d H }W 5 Q I d H R X ˆ  ¡ rrddiS |S )Nr   r    z(typing.Callable[[], typing.Awaitable[T]]r   )Úfuncr   c                 “  s   | ƒ I d H }ˆ j  ¡  |S r5   )Zcancel_scopeÚcancel)r;   Úresult©Ú
task_groupr   r   Úwrapx   s    
z[BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.receive_or_disconnect.<locals>.wrap)Úis_setÚanyioÚcreate_task_groupÚ
start_soonÚwait)r@   Úmessage)Úresponse_sentr+   r>   r   Úreceive_or_disconnectr   s    zMBaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.receive_or_disconnectr2   c                   “  s   ˆ  ¡ I d H  ˆ  ¡  d S r5   )rE   Úcloser   )Úrecv_streamrG   r   r   Ú"close_recv_stream_on_response_sent…   s    zZBaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.close_recv_stream_on_response_sent)rF   r   c                 “  s2   zˆ   | ¡I d H  W n tjk
r,   Y d S X d S r5   )r8   rB   ZBrokenResourceError)rF   )Úsend_streamr   r   Úsend_no_error‰   s    zEBaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.send_no_errorc                  “  sb   ˆ4 I d H šF zˆ  ˆˆˆ¡I d H  W n& tk
rL }  z| ‰ W 5 d } ~ X Y nX W 5 Q I d H R X d S r5   )r3   Ú	Exception)Úexc)Úapp_excrH   r   r   rM   rL   r   r   Úcoro�   s
    z<BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coroÚinfor   úhttp.response.debugzNo response returned.úhttp.response.startz"typing.AsyncGenerator[bytes, None]c               
    sx   ˆ4 I d H šP ˆ2 zB3 d H W } | d dks.t ‚|  dd¡}|rD|V  |  dd¡s qXq6 W 5 Q I d H R X ˆ d k	rtˆ ‚d S )Nr   úhttp.response.bodyr#   r%   r$   F)ÚAssertionErrorÚget)rF   r#   )rP   rJ   r   r   Úbody_stream¨   s    zCBaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.body_streamÚstatus)Ústatus_codeÚcontentrR   Úheaders)
rB   Zcreate_memory_object_streamrD   r   rW   ZEndOfStreamr&   rV   Ú_StreamingResponseÚraw_headers)r:   rK   rQ   rF   rR   rX   Úresponse©rG   r   r   r?   r+   )rP   rH   rJ   rM   rL   r   Ú	call_nextl   s,    	


z.BaseHTTPMiddleware.__call__.<locals>.call_next)	r3   r   r+   rB   ÚEventr   rC   r6   Úset)r   r   r   r8   r:   ra   r_   r   r`   r   Ú__call__c   s    
MzBaseHTTPMiddleware.__call__r   ÚRequestResponseEndpointr	   )r:   ra   r   c                 Ã  s
   t ƒ ‚d S r5   )ÚNotImplementedError)r   r:   ra   r   r   r   r4   ¿   s    zBaseHTTPMiddleware.dispatch)N)r,   r-   r.   r   rd   r4   r   r   r   r   r1   ^   s   \r1   c                   @  s:   e Zd Zdddddddd	œd
d„Zdddddœdd„ZdS )r]   éÈ   Nr   Úintztyping.Mapping[str, str] | Nonez
str | Nonez&typing.Mapping[str, typing.Any] | Noner2   )r[   rZ   r\   Ú
media_typerR   r   c                 C  s,   || _ || _|| _|| _|  |¡ d | _d S r5   )rR   Úbody_iteratorrZ   ri   Zinit_headersÚ
background)r   r[   rZ   r\   ri   rR   r   r   r   r   Ä   s    
z_StreamingResponse.__init__r   r   r   r7   c                 Ã  s”   | j d k	r |d| j dœƒI d H  |d| j| jdœƒI d H  | j2 z"3 d H W }|d|ddœƒI d H  q@6 |ddd	dœƒI d H  | jr�|  ¡ I d H  d S )
NrS   )r   rR   rT   )r   rY   r\   rU   Tr"   r%   F)rR   rZ   r^   rj   rk   )r   r   r   r8   r*   r   r   r   rd   Ó   s    
ýÿ
z_StreamingResponse.__call__)rg   NNN)r,   r-   r.   r   rd   r   r   r   r   r]   Ã   s       úr]   )Ú
__future__r   ÚtypingrB   Z	anyio.abcr   r   Zstarlette._utilsr   Zstarlette.requestsr   r   Zstarlette.responsesr   r	   Zstarlette.typesr
   r   r   r   r   ÚCallableÚ	Awaitablere   ZDispatchFunctionÚTypeVarr   r   r1   r]   r   r   r   r   Ú<module>   s   
Le