U
    e["                     @   s   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 d dl	m
Z
mZ d dlmZ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 )    N)ObjectReceiveStreamObjectSendStream)collapse_excgroups)BackgroundTask)ClientDisconnectRequest)ContentStreamResponseStreamingResponse)ASGIAppMessageReceiveScopeSendTc                       s6   e Zd ZdZeed fddZe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.
    )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-2mv5qoba/starlette/middleware/base.pyr      s    z_CachedRequest.__init__returnc                    s   | j rddiS | jrX| jr(d| _ ddiS |  I d H }|d dkrTtd|d  |S t| dd d k	r|d| _d| jddS | jrd| _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!   sB    z_CachedRequest.wrapped_receive)
__name__
__module____qualname____doc__r   r   r   r   r+   __classcell__r   r   r   r   r      s   r   c                   @   sL   e Zd Zdeeje ddddZee	e
ddddZeeedd	d
ZdS )BaseHTTPMiddlewareN)appdispatchr   c                 C   s   || _ |d kr| jn|| _d S N)r2   r3   dispatch_func)r   r2   r3   r   r   r   r   _   s    zBaseHTTPMiddleware.__init__)r   r   sendr   c                    s   d dkr$ ||I d H  d S t|}|jt  tt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    http)requestr   c                    s8  d  t  \td	fddd dfdd}t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stt	j
td f d fdd}t|d | |d}|d |_|S )Nr   c               
      s     rddiS t 4 I d H F tjg tjt f td fdd}  | j | I d H }W 5 Q I d H R X   rddiS |S )Nr    r!   )funcr   c                    s   |  I d H } j   |S r4   )Zcancel_scopecancel)r9   result
task_groupr   r   wrapz   s    
z[BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.receive_or_disconnect.<locals>.wrap)	is_setanyiocreate_task_grouptypingCallable	Awaitabler   
start_soonwait)r>   message)response_sentr+   r<   r   receive_or_disconnectt   s    $zMBaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.receive_or_disconnectc                      s     I d H     d S r4   )rF   closer   )recv_streamrH   r   r   "close_recv_stream_on_response_sent   s    zZBaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.close_recv_stream_on_response_sent)rG   r   c                    s2   z  | I d H  W n tjk
r,   Y d S X d S r4   )r6   r@   ZBrokenResourceError)rG   )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 r4   )r2   	Exception)exc)app_excrI   r   r   rN   rM   r   r   coro   s
    z<BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coroinfor    http.response.debugzNo response returned.zhttp.response.startc               
     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    zhttp.response.bodyr#   r%   r$   F)AssertionErrorget)rG   r#   )rQ   rK   r   r   body_stream   s    zCBaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.body_streamstatus)status_codecontentrS   headers)r@   Zcreate_memory_object_streamr   rE   r   rV   ZEndOfStreamr&   rU   rB   AsyncGeneratorbytes_StreamingResponseZraw_headers)r8   rL   rR   rG   rS   rW   responserH   r   r   r=   r+   )rQ   rI   rK   rN   rM   r   	call_nextn   s4    	

  
z.BaseHTTPMiddleware.__call__.<locals>.call_next)r2   r   r+   r@   Eventr   r	   r   rA   r5   set)r   r   r   r6   r8   ra   r_   r   r`   r   __call__e   s    
OzBaseHTTPMiddleware.__call__)r8   ra   r   c                    s
   t  d S r4   )NotImplementedError)r   r8   ra   r   r   r   r3      s    zBaseHTTPMiddleware.dispatch)N)r,   r-   r.   r   rB   OptionalDispatchFunctionr   r   r   r   rd   r   RequestResponseEndpointr	   r3   r   r   r   r   r1   ^   s     _ r1   c                
       sr   e Zd Zd	eeejejeef  eje eje	 ejejeej
f  dd fddZedd fddZ  ZS )
r^      N)rZ   rY   r[   
media_type
backgroundrS   r   c                    s   || _ t ||||| d S r4   )_infor   r   )r   rZ   rY   r[   rj   rk   rS   r   r   r   r      s    	z_StreamingResponse.__init__)r6   r   c                    s.   | j r|d| j dI d H  t |I d H S )NrT   )r    rS   )rl   r   stream_response)r   r6   r   r   r   rm      s    z"_StreamingResponse.stream_response)ri   NNNN)r,   r-   r.   r   intrB   rf   Mappingstrr   Anyr   r   rm   r0   r   r   r   r   r^      s        r^   )rB   r@   Z	anyio.abcr   r   Zstarlette._utilsr   Zstarlette.backgroundr   Zstarlette.requestsr   r   Zstarlette.responsesr   r	   r
   Zstarlette.typesr   r   r   r   r   rC   rD   rh   rg   TypeVarr   r   r1   r^   r   r   r   r   <module>   s   
Kk