U
    RhP                     @  s   d dl mZ d dlZd dlZd dlZd dlmZmZmZm	Z	 d dl
mZ d dlZd dlmZ d dlmZmZmZmZmZmZm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 m!Z!m"Z"m#Z#m$Z$m%Z% d dl&m'Z' dddddZ(dd e)ddD Z*G dd dej+Z,G dd dZ-dS )    )annotationsN)AnyCallableLiteralcast)unquote)!DEFAULT_MAX_INCOMPLETE_EVENT_SIZE)ASGI3ApplicationASGIReceiveEventASGISendEventHTTPRequestEventHTTPResponseBodyEventHTTPResponseStartEvent	HTTPScope)Config)TRACE_LOG_LEVEL)CLOSE_HEADERHIGH_WATER_LIMITFlowControlservice_unavailable)get_client_addrget_local_addrget_path_with_query_stringget_remote_addris_ssl)ServerStateintbytes)status_codereturnc                 C  s.   zt | j W S  tk
r(   Y dS X d S )N    )httpZ
HTTPStatusphraseencode
ValueError)r    r%   E./venv/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py_get_status_phrase   s    r'   c                 C  s   i | ]}|t |qS r%   )r'   ).0r   r%   r%   r&   
<dictcomp>#   s      r)   d   iX  c                   @  s  e Zd Zd9dddddddd	Zd
ddddZdddddZddddZddddZddddZddddZ	ddddZ
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.Zddd/d0Zddd1d2Zddd3d4Zddd5d6Zddd7d8ZdS ):H11ProtocolNr   r   zdict[str, Any]z asyncio.AbstractEventLoop | NoneNone)configserver_state	app_state_loopr   c                 C  s   |j s|  || _|j| _|p&t | _t	d| _
t	d| _| j | _ttj|jd k	rf|jnt| _|j| _|j| _|j| _|| _d | _|j| _|| _|j| _|j| _d | _d | _d | _d | _ d | _!d | _"d | _#d | _$d S )Nzuvicorn.errorzuvicorn.access)%Zloadedloadr-   Z
loaded_appappasyncioZget_event_looplooploggingZ	getLoggerloggeraccess_loggerZhasHandlers
access_logh11Z
ConnectionZSERVERZh11_max_incomplete_event_sizer   connws_protocol_class	root_pathlimit_concurrencyr/   timeout_keep_alive_tasktimeout_keep_aliver.   connectionstasks	transportflowserverclientschemescopeheaderscycle)selfr-   r.   r/   r0   r%   r%   r&   __init__'   s>    zH11Protocol.__init__asyncio.Transport)rB   r   c                 C  sv   | j |  || _t|| _t|| _t|| _t	|r<dnd| _
| jjtkrr| jr^d| j nd}| jtd| d S )NZhttpsr!   %s:%d -  z%sHTTP connection made)r@   addrB   r   rC   r   rD   r   rE   r   rF   r6   levelr   log)rJ   rB   prefixr%   r%   r&   connection_madeX   s    


zH11Protocol.connection_madezException | None)excr   c                 C  s   | j |  | jjtkr<| jr(d| j nd}| jtd| | jrR| jjsRd| j_	| j
jtjkrt }z| j
| W n tjk
r   Y nX | jd k	r| jj  | jd k	r| j  |d kr| j  |   d S )NrM   rN   z%sHTTP connection lostT)r@   discardr6   rP   r   rE   rQ   rI   response_completedisconnectedr:   	our_stater9   ZERRORConnectionClosedsendZLocalProtocolErrormessage_eventsetrC   resume_writingrB   close_unset_keepalive_if_required)rJ   rT   rR   eventr%   r%   r&   connection_lostg   s&    



zH11Protocol.connection_lostr   c                 C  s   d S Nr%   rJ   r%   r%   r&   eof_received   s    zH11Protocol.eof_receivedc                 C  s   | j d k	r| j   d | _ d S rc   )r>   cancelrd   r%   r%   r&   r_      s    

z(H11Protocol._unset_keepalive_if_requiredzbytes | Nonec                 C  sT   g }d }| j D ]4\}}|dkr2dd |dD }|dkr| }qd|krP|S d S )N
   connectionc                 S  s   g | ]}|   qS r%   )lowerstrip)r(   tokenr%   r%   r&   
<listcomp>   s     z,H11Protocol._get_upgrade.<locals>.<listcomp>   ,s   upgrade)rH   splitrh   )rJ   Z
connectionupgradenamevaluer%   r%   r&   _get_upgrade   s    
zH11Protocol._get_upgradeboolc                 C  s   | j d krdS dS )NFT)r;   rd   r%   r%   r&   _should_upgrade_to_ws   s    
z!H11Protocol._should_upgrade_to_wsc                 C  s,   d}| j | |  s(d}| j | d S )NzUnsupported upgrade request.zNo supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.)r6   warningrs   )rJ   msgr%   r%   r&   _unsupported_upgrade_warning   s
    z(H11Protocol._unsupported_upgrade_warningc                 C  s0   |   }|dkr|  rdS |d k	r,|   dS )Ns	   websocketTF)rq   rs   rv   )rJ   rn   r%   r%   r&   _should_upgrade   s    zH11Protocol._should_upgrader   )datar   c                 C  s    |    | j| |   d S rc   )r_   r:   Zreceive_datahandle_events)rJ   rx   r%   r%   r&   data_received   s    zH11Protocol.data_receivedc                 C  s  z| j  }W n2 tjk
r@   d}| j| | | Y d S X |tjkrRqq |tjkrl| j	
  qq t|tjrdd |jD | _|jd\}}}t|d}| j| }| jd| }d| jjdd|jd| j| j| j|jd| j|||| j| j d	| _|  r*| | d S | j d k	rpt!| j"| j ksZt!| j#| j krpt$}	d
}
| j|
 n| j%}	| &  t'| j| j | j(| j	| j| j)| j*| j+j,t-. | j/d
| _0| j12| j03|	}|4| j#j5 | j#6| q t|tj7r@| j j8tj9krq | j0 j:|j;7  _:t!| j0j:t<kr2| j	
  | j0j=>  q t|tj?r | j j8tj9krr| j(@  | j A  q d| j0_B| j0j=>  | j jCtjDkr qq d S )NzInvalid HTTP request received.c                 S  s   g | ]\}}|  |fqS r%   )rh   )r(   keyrp   r%   r%   r&   rk      s     z-H11Protocol.handle_events.<locals>.<listcomp>   ?asciir!   z2.3)versionZspec_version)typeZasgihttp_versionrD   rE   rF   methodr<   pathraw_pathquery_stringrH   statezExceeded concurrency limit.)
rG   r:   rB   rC   r6   r7   r8   default_headersr[   on_responseF)Er:   Z
next_eventr9   ZRemoteProtocolErrorr6   rt   send_400_responseZ	NEED_DATAZPAUSEDrC   Zpause_reading
isinstanceZRequestrH   target	partitionr   decoder<   r#   r-   Zasgi_versionr   rD   rE   rF   r   r/   copyrG   rw   handle_websocket_upgrader=   lenr@   rA   r   r2   r_   RequestResponseCyclerB   r7   r8   r.   r   r3   Eventon_response_completerI   r4   Zcreate_taskrun_asgiZadd_done_callbackrU   rO   DatarX   DONEbodyrx   r   r[   r\   EndOfMessageresume_readingstart_next_cycle	more_bodytheir_state
MUST_CLOSE)rJ   r`   ru   r   _r   r   	full_pathZfull_raw_pathr2   messageZtaskr%   r%   r&   ry      s    











zH11Protocol.handle_eventszh11.Request)r`   r   c                 C  s   | j jtkr0| jrd| j nd}| j td| | j|  |jd|jdg}| j	D ]\}}||d|dg7 }qR|
d | j| j| j| jd}|| j |d	| | j| d S )
NrM   rN   z%sUpgrading to WebSocket    s    HTTP/1.1
s   : s   
)r-   r.   r/   r    )r6   rP   r   rE   rQ   r@   rU   r   r   rH   appendr;   r-   r.   r/   rS   rB   rz   joinZset_protocol)rJ   r`   rR   outputro   rp   Zprotocolr%   r%   r&   r     s     
z$H11Protocol.handle_websocket_upgradestr)ru   r   c                 C  s   t d }ddg}tjd||d}| j|}| j| | jjtj|ddd}| j| | jjt	 d}| j| | j
  d S )Ni  s   content-types   text/plain; charset=utf-8rg   s   closer   rH   reasonr}   rx   r`   )STATUS_PHRASESr9   Responser:   rZ   rB   writer   r#   r   r^   )rJ   ru   r   rH   r`   r   r%   r%   r&   r   #  s    zH11Protocol.send_400_responsec                 C  sv   | j  jd7  _| j rd S |   | j| j| j| _	| j
  | jjtjkrr| jjtjkrr| j  |   d S )N   )r.   Ztotal_requestsrB   
is_closingr_   r4   Z
call_laterr?   timeout_keep_alive_handlerr>   rC   r   r:   rX   r9   r   r   r   ry   rd   r%   r%   r&   r   5  s    


z H11Protocol.on_response_completec                 C  s>   | j dks| j jr2t }| j| | j  nd| j _dS )zG
        Called by the server to commence a graceful shutdown.
        NF)	rI   rV   r9   rY   r:   rZ   rB   r^   
keep_aliverJ   r`   r%   r%   r&   shutdownH  s
    zH11Protocol.shutdownc                 C  s   | j   dS )z\
        Called by the transport when the write buffer exceeds the high water mark.
        N)rC   pause_writingrd   r%   r%   r&   r   S  s    zH11Protocol.pause_writingc                 C  s   | j   dS )z_
        Called by the transport when the write buffer drops below the low water mark.
        N)rC   r]   rd   r%   r%   r&   r]   Y  s    zH11Protocol.resume_writingc                 C  s,   | j  s(t }| j| | j   dS )zk
        Called on a keep-alive connection if no new data is received after a short
        delay.
        N)rB   r   r9   rY   r:   rZ   r^   r   r%   r%   r&   r   _  s    
z&H11Protocol.timeout_keep_alive_handler)N)__name__
__module____qualname__rK   rS   ra   re   r_   rq   rs   rv   rw   rz   ry   r   r   r   r   r   r]   r   r%   r%   r%   r&   r+   &   s&    1br+   c                   @  sj   e Zd Zdddddddd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ZdS )r   r   zh11.ConnectionrL   r   zlogging.Loggerrr   zlist[tuple[bytes, bytes]]zasyncio.EventzCallable[(Ellipsis, None)]r,   )rG   r:   rB   rC   r6   r7   r8   r   r[   r   r   c                 C  sl   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d| _
d| _|j| _d| _d| _d| _d| _d S )NFTr    )rG   r:   rB   rC   r6   r7   r8   r   r[   r   rW   r   Z!they_are_waiting_for_100_continuewaiting_for_100_continuer   r   response_startedrV   )rJ   rG   r:   rB   rC   r6   r7   r8   r   r[   r   r%   r%   r&   rK   k  s"    zRequestResponseCycle.__init__r	   )r2   r   c              
     s  zz|| j| j| jI d H }W nV tk
rt } z8d}| jj||d | jsZ|  I d H  n
| j	
  W 5 d }~X Y nzX |d k	rd}| j|| | j	
  nR| js| jsd}| j| |  I d H  n&| js| jsd}| j| | j	
  W 5 dd | _ X d S )Nc                   S  s   d S rc   r%   r%   r%   r%   r&   <lambda>  r    z/RequestResponseCycle.run_asgi.<locals>.<lambda>zException in ASGI application
)exc_infoz4ASGI callable should return None, but returned '%s'.z1ASGI callable returned without starting response.z3ASGI callable returned without completing response.)r   rG   receiverZ   BaseExceptionr6   errorr   send_500_responserB   r^   rW   rV   )rJ   r2   resultrT   ru   r%   r%   r&   r     s2      zRequestResponseCycle.run_asgirb   c                   s@   ddddgd}|  |I d H  dddd	}|  |I d H  d S )
Nhttp.response.starti  r   r   )r   statusrH   http.response.bodys   Internal Server ErrorFr   r   r   )rZ   )rJ   Zresponse_start_eventZresponse_body_eventr%   r%   r&   r     s    z&RequestResponseCycle.send_500_responser   )r   r   c                   s  |d }| j jr&| js&| j  I d H  | jr0d S | js|dkrPd}t|| td|}d| _d| _|d }| jt	|
dg  }t| jd krt|kr|tg }| jr| jd	t| j| jd
 t| j| jd | t| }tj|||d}| jj|d}| j| n| js|dkr.d}t|| td|}|
dd}	|
dd}
| jd
 dkrddn|	}| jjtj|dd}| j| |
sd| _| j  | jjt d}| j| nd}t|| | jr| jjtjks| j s| jjt! d | j"  | #  d S )Nr   r   z:Expected ASGI message 'http.response.start', but got '%s'.r   TFr   rH   z%s - "%s %s HTTP/%s" %dr   r   r   r   r   z9Expected ASGI message 'http.response.body', but got '%s'.r   r   r    r   ZHEADr   zDUnexpected ASGI message '%s' sent, after response already completed.)$rC   Zwrite_pausedrW   Zdrainr   RuntimeErrorr   r   r   listgetr   rG   r8   r7   infor   r   r   r9   r   r:   rZ   rB   r   rV   r   r[   r\   r   rX   r   r   rY   r^   r   )rJ   r   Zmessage_typeru   r   rH   r   Zresponser   r   r   rx   r%   r%   r&   rZ     sf    






zRequestResponseCycle.sendr
   c                   s   | j rD| j sDg }tjd|dd}| jj|d}| j| d| _ | jst| j	st| j
  | j I d H  | j  | js| j	rddiS d| j| jd	}d
| _|S )Nr*   ZContinuer   r   Fr   zhttp.disconnectzhttp.requestr   r    )r   rB   r   r9   ZInformationalResponser:   rZ   r   rW   rV   rC   r   r[   waitclearr   r   )rJ   rH   r`   r   r   r%   r%   r&   r   	  s$    

zRequestResponseCycle.receiveN)r   r   r   rK   r   r   rZ   r   r%   r%   r%   r&   r   j  s
   "&Jr   ).Z
__future__r   r3   r!   r5   typingr   r   r   r   Zurllib.parser   r9   Zh11._connectionr   Zuvicorn._typesr	   r
   r   r   r   r   r   Zuvicorn.configr   Zuvicorn.loggingr   Z#uvicorn.protocols.http.flow_controlr   r   r   r   Zuvicorn.protocols.utilsr   r   r   r   r   Zuvicorn.serverr   r'   ranger   ZProtocolr+   r   r%   r%   r%   r&   <module>   s&   $	  F