o
    4ήcN                     @   sj  d dl Z d dlZd dlZd dl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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 ej d	k rdd d
l!m"Z" nd d
lm"Z" erd dl#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ e
ej,ej-ej.ej/ej0ej1f Z2de3de4fddZ5dd e6ddD Z7G dd de j8Z9G dd dZ:dS )    N)TYPE_CHECKINGCallableListOptionalTupleUnioncast)unquote)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)      )Literal)ASGI3ApplicationASGIReceiveEventASGISendEventHTTPDisconnectEventHTTPRequestEventHTTPResponseBodyEventHTTPResponseStartEvent	HTTPScopestatus_codereturnc                 C   s(   z	t | j W S  ty   Y dS w )N    )http
HTTPStatusphraseencode
ValueError)r!    r)   F/tmp/pip-target-vg8gfxp4/lib/python/uvicorn/protocols/http/h11_impl.py_get_status_phrase6   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	d+dededeej ddfddZdej	ddfd	d
Z
dee ddfddZd,ddZd,ddZdee fddZdefddZdeddfddZd,ddZdeddfddZdeddfdd Zd,d!d"Zd,d#d$Zd,d%d&Zd,d'd(Zd,d)d*ZdS )-H11ProtocolNconfigserver_state_loopr"   c                 C   s   |j s|  || _|j| _|pt | _t	d| _
t	d| _| j | _ttj|j| _|j| _|j| _|j| _d | _|j| _|| _|j| _|j| _d | _d | _d | _d | _d | _d | _ d | _!d | _"d S )Nzuvicorn.errorzuvicorn.access)#loadedloadr0   
loaded_appappasyncioget_event_looplooplogging	getLoggerloggeraccess_loggerhasHandlers
access_logh11
ConnectionSERVERh11_max_incomplete_event_sizeconnws_protocol_class	root_pathlimit_concurrencytimeout_keep_alive_tasktimeout_keep_aliver1   connectionstasks	transportflowserverclientschemescopeheaderscycle)selfr0   r1   r2   r)   r)   r*   __init__C   s2   
zH11Protocol.__init__rL   c                 C   sz   | j |  || _t|| _t|| _t|| _t	|rdnd| _
| jjtkr;| jr/d| j nd}| jtd| d S d S )Nhttpsr$   %s:%d -  z%sHTTP connection made)rJ   addrL   r   rM   r   rN   r   rO   r   rP   r<   levelr   log)rT   rL   prefixr)   r)   r*   connection_madem   s   


zH11Protocol.connection_madeexcc                 C   s   | j |  | jjtkr| jrd| j nd}| jtd| | jr)| jjs)d| j_	| j
jtjkrGt }z| j
| W n
 tjyF   Y nw | jd urR| jj  | jd ur\| j  |d u rk| j  |   d S d S )NrW   rX   z%sHTTP connection lostT)rJ   discardr<   rZ   r   rO   r[   rS   response_completedisconnectedrD   	our_stater@   ERRORConnectionClosedsendLocalProtocolErrormessage_eventsetrM   resume_writingrL   close_unset_keepalive_if_required)rT   r^   r\   eventr)   r)   r*   connection_lost|   s*   



zH11Protocol.connection_lostc                 C      d S Nr)   rT   r)   r)   r*   eof_received   s   zH11Protocol.eof_receivedc                 C   s"   | j d ur| j   d | _ d S d S ro   )rH   cancelrp   r)   r)   r*   rk      s   


z(H11Protocol._unset_keepalive_if_requiredc                 C   sT   g }d }| j D ]\}}|dkrdd |dD }|dkr!| }qd|v r(|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)rR   splitrt   )rT   
connectionupgradenamevaluer)   r)   r*   _get_upgrade   s   zH11Protocol._get_upgradec                 C   s>   | j d u r| jjdkrd}| j| d}| j| dS dS )NautozUnsupported upgrade request.zNo supported WebSocket library detected. Please use 'pip install uvicorn[standard]', or install 'websockets' or 'wsproto' manually.FT)rE   r0   wsr<   warning)rT   msgr)   r)   r*   _should_upgrade_to_ws   s   
z!H11Protocol._should_upgrade_to_wsdatac                 C   s    |    | j| |   d S ro   )rk   rD   receive_datahandle_events)rT   r   r)   r)   r*   data_received   s   zH11Protocol.data_receivedc                 C   s^  	 z| j  }W n tjy    d}| j| | | Y d S w t|}|tju r,d S |tj	u r8| j
  d S |tju rdd |jD | _|jd\}}}d| jjdd|jd	| j| j| j|jd	| jt|d	||| jd
| _|  }|dkr|  r| | d S | jd urt| j | jkst| j!| jkrt"}d}	| j|	 n| j#}t$| j| j | j%| j
| j| j&| j'| j(j)t*+ | j,d
| _-| j./| j-0|}
|
1| j!j2 | j!3|
 nO|tj4u r| j j5tj6u rq | j- j7|j87  _7t| j-j7t9kr| j
  | j-j:;  n#|tj<u r.| j j5tj6u r$| j%=  | j >  q d| j-_?| j-j:;  q)NTzInvalid HTTP request received.c                 S   s   g | ]
\}}|  |fqS r)   )rt   )r,   keyr}   r)   r)   r*   rw      s    z-H11Protocol.handle_events.<locals>.<listcomp>   ?r$   z2.3)versionspec_versionascii)typeasgihttp_versionrN   rO   rP   methodrF   pathraw_pathquery_stringrR   s	   websocketzExceeded concurrency limit.)
rQ   rD   rL   rM   r<   r=   r?   default_headersrg   on_responseF)@rD   
next_eventr@   RemoteProtocolErrorr<   r   send_400_responser   	NEED_DATAPAUSEDrM   pause_readingRequestrR   target	partitionr0   asgi_versionr   decoderN   rO   rP   r   rF   r	   rQ   r~   r   handle_websocket_upgraderG   lenrJ   rK   r   r6   RequestResponseCyclerL   r=   r?   r1   r   r7   Eventon_response_completerS   r9   create_taskrun_asgiadd_done_callbackr_   rY   Datarb   DONEbodyr   r   rg   rh   EndOfMessageresume_readingstart_next_cycle	more_body)rT   rl   r   
event_typer   _r   r{   r6   messagetaskr)   r)   r*   r      s   











zH11Protocol.handle_eventsrl   c                 C   s   | j jtkr| jrd| j nd}| j td| | j|  |jd|jdg}| j	D ]\}}||d|dg7 }q)|
d | j| j| jd}|| j |d	| | j| d S )
NrW   rX   z%sUpgrading to WebSocket    s    HTTP/1.1
s   : s   
)r0   r1   r#   )r<   rZ   r   rO   r[   rJ   r_   r   r   rR   appendrE   r0   r1   r]   rL   r   joinset_protocol)rT   rl   r\   outputr|   r}   protocolr)   r)   r*   r     s   
z$H11Protocol.handle_websocket_upgrader   c                 C   s   t d }ddg}tjd||d}| j|}| j| tj|dd}| j|}| j| t	 }| j|}| j| | j
  d S )Ni  s   content-types   text/plain; charset=utf-8rs   s   closer!   rR   reasonr   r   )STATUS_PHRASESr@   ResponserD   re   rL   writer   r'   r   rj   )rT   r   r   rR   rl   r   r)   r)   r*   r   %  s   zH11Protocol.send_400_responsec                 C   s~   | j  jd7  _| j rd S |   | j| j| j| _	| j
  | jjtju r;| jjtju r=| j  |   d S d S d S )N   )r1   total_requestsrL   
is_closingrk   r9   
call_laterrI   timeout_keep_alive_handlerrH   rM   r   rD   rb   r@   r   their_stater   r   rp   r)   r)   r*   r   7  s   


z H11Protocol.on_response_completec                 C   s@   | j du s	| j jrt }| j| | j  dS d| j _dS )zG
        Called by the server to commence a graceful shutdown.
        NF)	rS   r`   r@   rd   rD   re   rL   rj   
keep_aliverT   rl   r)   r)   r*   shutdownL  s
   zH11Protocol.shutdownc                 C      | j   dS )z\
        Called by the transport when the write buffer exceeds the high water mark.
        N)rM   pause_writingrp   r)   r)   r*   r   W     zH11Protocol.pause_writingc                 C   r   )z_
        Called by the transport when the write buffer drops below the low water mark.
        N)rM   ri   rp   r)   r)   r*   ri   ]  r   zH11Protocol.resume_writingc                 C   s0   | j  st }| j| | j   dS dS )zk
        Called on a keep-alive connection if no new data is received after a short
        delay.
        N)rL   r   r@   rd   rD   re   rj   r   r)   r)   r*   r   c  s
   
z&H11Protocol.timeout_keep_alive_handlerro   r"   N)__name__
__module____qualname__r
   r   r   r7   AbstractEventLooprU   	Transportr]   	Exceptionrm   rq   rk   bytesr~   boolr   r   r   H11Eventr   strr   r   r   r   ri   r   r)   r)   r)   r*   r/   B   s<    
*




[



r/   c                   @   s   e Zd Zdddejdejdedej	dej	de
d	eeeef  d
ejded ddfddZdddZdddZd ddZd!ddZdS )"r   rQ   r    rD   rL   rM   r<   r=   r?   r   rg   r   ).Nr"   Nc                 C   sl   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	d| _
d| _|j| _d| _d| _d| _d| _d S )NFTr#   )rQ   rD   rL   rM   r<   r=   r?   r   rg   r   ra   r   !they_are_waiting_for_100_continuewaiting_for_100_continuer   r   response_startedr`   )rT   rQ   rD   rL   rM   r<   r=   r?   r   rg   r   r)   r)   r*   rU   o  s"   
zRequestResponseCycle.__init__r6   r   c              
      s^  zz|| j | j| jI d H }W n, ty< } z d}| jj||d | js-|  I d H  n| j	  W Y d }~nId }~ww |d urPd}| j|| | j	  n9| jsf| j
sfd}| j| |  I d H  n3| js| j
sd}| j| | j	  W dd | _d S W dd | _d S W dd | _d S W dd | _d S W dd | _d S W dd | _d S dd | _w )Nz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.c                   S   rn   ro   r)   r)   r)   r)   r*   <lambda>  s    z/RequestResponseCycle.run_asgi.<locals>.<lambda>)rQ   receivere   BaseExceptionr<   errorr   send_500_responserL   rj   ra   r`   r   )rT   r6   resultr^   r   r)   r)   r*   r     sH   
 
zRequestResponseCycle.run_asgic                    sB   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   statusrR   http.response.bodys   Internal Server ErrorFr   r   r   )re   )rT   response_start_eventresponse_body_eventr)   r)   r*   r     s   z&RequestResponseCycle.send_500_responser   r   c                    s0  |d }| j jr| js| j  I d H  | jrd S | js|dkr(d}t|| td|}d| _d| _|d }ttt	t
t
f  |dg }| j| }t| jd v r[t|vr[|tg }| jru| jd	t| j| jd
 t| j| jd | t| }tj|||d}| j|}	| j|	 nc| js|dkrd}t|| td|}|dd}
|dd}| jd
 dkrtjdd}ntj|
d}| j|}	| j|	 |sd| _| j  t }| j|}	| j|	 nd}t|| | jr| jj tj!u s| j"st# }| j| | j$  | %  d S d S )Nr   r   z:Expected ASGI message 'http.response.start', but got '%s'.r   TFr   rR   z%s - "%s %s HTTP/%s" %dr   r   r   r   z9Expected ASGI message 'http.response.body', but got '%s'.r   r   r#   r   HEADr   zDUnexpected ASGI message '%s' sent, after response already completed.)&rM   write_pausedra   drainr   RuntimeErrorr   r   r   r   r   getr   r   rQ   r?   r=   infor   r   r   r@   r   rD   re   rL   r   r`   r   rg   rh   r   rb   
MUST_CLOSEr   rd   rj   r   )rT   r   message_typer   r!   message_headersrR   r   rl   r   r   r   r)   r)   r*   re     s~   






zRequestResponseCycle.sendr   c                    s   | j r | j s tjdg dd}| j|}| j| d| _ | js8| j	s8| j
  | j I d H  | j  | js>| j	rDddi}|S d| j| jd}d	| _|S )
Nr.   Continuer   Fr   zhttp.disconnectzhttp.requestr   r#   )r   rL   r   r@   InformationalResponserD   re   r   ra   r`   rM   r   rg   waitclearr   r   )rT   rl   r   r   r)   r)   r*   r     s*   

	zRequestResponseCycle.receive)r6   r   r"   Nr   )r   r   r"   N)r"   r   )r   r   r   r@   rA   r7   r   r   r:   Loggerr   r   r   r   r   r   rU   r   r   re   r   r)   r)   r)   r*   r   n  s8    	


&

Tr   );r7   r$   r:   systypingr   r   r   r   r   r   r   urllib.parser	   r@   uvicorn.configr
   uvicorn.loggingr   #uvicorn.protocols.http.flow_controlr   r   r   r   uvicorn.protocols.utilsr   r   r   r   r   uvicorn.serverr   version_infotyping_extensionsr   asgiref.typingr   r   r   r   r   r   r   r    r   r   r   r   r   rd   r   intr   r+   ranger   Protocolr/   r   r)   r)   r)   r*   <module>   sD    $
(
  .