o
    NK&hi5                     @  s  d dl mZ d dlZd dlmZmZ d dlmZ d dl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 d d
l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% d dl&m'Z' z.d dl(m)Z)m*Z* d dl+m,Z,m-Z- d dl.m/Z/m0Z0m1Z1m2Z2m3Z3 d dl4m5Z5 d dl6m7Z7 dZ8W n e9y   dZ8Y nw e	rd dl:m;Z; d dl<m=Z= d dl>m?Z? d dl@mAZA ee*e-f ZBG dd de%ZCG dd deZDG dd  d eDeZEG d!d" d"eDZFG d#d$ d$eDZGG d%d& d&ZHG d'd( d(ZId/d-d.ZJdS )0    )annotationsN)ABCabstractmethod)
SSLContext)TYPE_CHECKINGAnyCallableOptionalUnioncast)Header)LocalCertCreator)
BadRequestPayloadTooLargeSanicExceptionServerError)has_message_body)Stage)Stream)CertSelectorSanicSSLContext)Colorslogger)TransportProtocol)ConnInfo)H0_ALPNH0Connection)H3_ALPNH3Connection)DatagramReceivedDataReceivedH3EventHeadersReceivedWebTransportStreamDataReceived)QuicConfiguration)SessionTicketTF)Sanic)Request)BaseHTTPResponse)Http3Protocolc                   @  s4   e Zd ZdZdZdddZddd	ZddddZd
S )HTTP3Transportz HTTP/3 transport implementation.	_protocolprotocolr)   c                 C  s
   || _ d S Nr+   )selfr-    r0   C/var/www/html/venv/lib/python3.10/site-packages/sanic/http/http3.py__init__@      
zHTTP3Transport.__init__returnc                 C  s   | j S r.   r+   r/   r0   r0   r1   get_protocolC   s   zHTTP3Transport.get_protocolNinfostrdefaultr   c                 C  sJ   |dv r| j jr| j j||S |dkr| j jjS |dkr#| j jjjS |S )N)socketsocknamepeernamenetwork_pathsssl_context)r,   
_transportget_extra_info_quic_network_pathsappstatessl)r/   r7   r9   r0   r0   r1   r@   F   s   
zHTTP3Transport.get_extra_info)r-   r)   )r4   r)   r.   )r7   r8   r9   r   r4   r   )__name__
__module____qualname____doc__	__slots__r2   r6   r@   r0   r0   r0   r1   r*   ;   s    

r*   c                   @  s0   e Zd ZU dZded< ddd	Zed
d ZdS )ReceiverzHTTP/3 receiver base class.zasyncio.Futurefuturerequestr'   r4   Nonec                 C  s   || _ || _|| _d S r.   )transmitr-   rM   )r/   rO   r-   rM   r0   r0   r1   r2   X   s   
zReceiver.__init__c                      d S r.   r0   r5   r0   r0   r1   run]   s   zReceiver.runN)rM   r'   r4   rN   )rF   rG   rH   rI   __annotations__r2   r   rQ   r0   r0   r0   r1   rK   S   s   
 
rK   c                      s   e Zd ZU dZded< ded< d% fdd	Zd&d'ddZd(ddZd)ddZd%ddZ	d*ddZ
d+ddZd,d!d"Zd,d#d$Z  ZS )-HTTPReceiverzHTTP/3 receiver implementation.r   stager'   rM   r4   rN   c                   s@   t  j|i | d | _tj| _d| _d | _| jj	| _	d| _
d S )NFr   )superr2   request_bodyr   IDLErT   headers_sentresponser-   request_max_sizerequest_bytes)r/   argskwargs	__class__r0   r1   r2   h   s   

zHTTPReceiver.__init__N	exceptionOptional[Exception]c              
     s   t j| _| jj dk| _|r/tjt	j
 dt	j | t	j dddid | |I dH  n;z tjt	j
 dt	j d	| j ddid
 | j| jI dH  W n tyi } z| |I dH  W Y d}~nd}~ww t j| _dS )z&Handle the request and response cycle.HEADz[exception]: T	verbosity   )exc_infoextraNz
[request]: rf   )r   HANDLERrT   rM   methodupper	head_onlyr   r7   r   BLUEREDENDerror_responser-   request_handler	ExceptionrQ   rW   )r/   r`   er0   r0   r1   rQ   q   s6   zHTTPReceiver.runrr   c                   s"   | j j}|| j|I dH  dS )z*Handle response when exception encounteredN)r-   rC   handle_exceptionrM   )r/   r`   rC   r0   r0   r1   rp      s   zHTTPReceiver.error_responserY   r(   list[tuple[bytes, bytes]]c                 C  s   |j rt|j nd}|j}|j}t|s9|sd|v sd|v r9|dd  |dd  td| jj	 d| d nd|vrH|rD||d< nd|d< dt
|j fg|j}|S )	Nr   zcontent-lengthtransfer-encodingz Message body set in response on z. A z) response may only have headers, no body.chunkeds   :status)bodylenheadersstatusr   popr   warningrM   pathr8   encodeprocessed_headers)r/   rY   sizerz   r{   r0   r0   r1   _prepare_headers   s0   
zHTTPReceiver._prepare_headersc                 C  s   t jtj dtj dtj ddid | jstd| j}| |}| j	j
j| jj|d d| _tj| _| jjrF| jsF| | jjd	 d
S | jrP| j  d
S d
S )zSend response headers to client[send]: HEADERSrc      rh   zno response)	stream_idrz   TFN)r   debugr   rm   GREENro   rY   RuntimeErrorr   r-   
connectionsend_headersrM   r   rX   r   RESPONSErT   rx   rl   _sendrL   cancel)r/   rY   rz   r0   r0   r1   r      s&   
zHTTPReceiver.send_headersc                 C  sf   t jtj dtj d| ddid | jtjur!tj| _t	d| j
dur*d| j
_|| | _
|_|S )zPrepare response to clientz
[respond]:rg   rc   r   rh   zResponse already startedN)r   r   r   rm   ro   rT   r   ri   FAILEDr   rY   stream)r/   rY   r0   r0   r1   respond   s   
zHTTPReceiver.responddatabytesc                 C  s:   |  j t|7  _ | j | jkrtd| j j|7  _dS )z Receive request body from clientz#Request body exceeds the size limitN)r[   ry   rZ   r   rM   rx   )r/   r   r0   r0   r1   receive_body   s   zHTTPReceiver.receive_body
end_streamboolc              	     sH   t jtj dtj d|  d| tj ddid | || dS )zSend data to clientr   zdata=z end_stream=rc   r   rh   N)r   r   r   rm   r   decodero   r   )r/   r   r   r0   r0   r1   send   s   zHTTPReceiver.sendc                 C  s   | j s|   | jtjurtd| j | jr:| jjddkr:t	|}|r2|r/d||f nd}n|r:d||f }t
jtj dtj dd	id
 | jjj| jj||d |   |rbtj| _d S d S )Nznot ready to send: rv   rw   s   %x
%b
0

s   0

s   %x
%b
z[transmitting]rc   r   rh   )r   r   r   )rX   r   rT   r   r   r   rY   rz   getry   r   r   r   rm   ro   r-   r   	send_datarM   r   rO   rW   )r/   r   r   r   r0   r0   r1   r      s8   zHTTPReceiver._sendr4   rN   r.   )r`   ra   )r`   rr   r4   rN   )rY   r(   r4   ru   )rY   r(   r4   r(   )r   r   r4   rN   )r   r   r   r   r4   rN   )rF   rG   rH   rI   rR   r2   rQ   rp   r   r   r   r   r   r   __classcell__r0   r0   r^   r1   rS   b   s   
 	





	rS   c                   @     e Zd ZdZdd ZdS )WebsocketReceiverz"Websocket receiver implementation.c                   rP   r.   r0   r5   r0   r0   r1   rQ         zWebsocketReceiver.runNrF   rG   rH   rI   rQ   r0   r0   r0   r1   r         r   c                   @  r   )WebTransportReceiverz%WebTransport receiver implementation.c                   rP   r.   r0   r5   r0   r0   r1   rQ     r   zWebTransportReceiver.runNr   r0   r0   r0   r1   r     r   r   c                   @  sZ   e Zd ZdZeredededediZ	dddZ
dddZdddZd ddZd!ddZdS )"Http3z>Internal helper for managing the HTTP/3 request/response cycler   flow_id
session_idr-   r)   rO   Callable[[], None]r4   rN   c                 C  s   || _ || _i | _d S r.   )r-   rO   	receivers)r/   r-   rO   r0   r0   r1   r2   '  s   
zHttp3.__init__eventr!   c              
   C  s   t jtj dtj | tj ddid | |\}}tt|}t	|t
r2|r2t| |_d S t	|trbz	||j W d S  tya } z|j  t|||_W Y d }~d S d }~ww 	 t jtj dtj ddid d S )Nz[http_event_received]: rc   r   rh   zDOING NOTHING)r   r   r   rm   YELLOWro   get_or_make_receiverr   rS   
isinstancer"   asyncioensure_futurerQ   rL   r    r   r   rr   r   rn   )r/   r   receivercreated_newrs   r0   r0   r1   http_event_received0  s6   


 
zHttp3.http_event_receivedtuple[Receiver, bool]c                 C  sl   t |tr%|j| jvr%| |}t| j| j|}||_|| j|j< |dfS t	|| j
t| }| j| dfS )NTF)r   r"   r   r   _make_requestrS   rO   r-   r   getattrHANDLER_PROPERTY_MAPPINGtype)r/   r   rM   r   identr0   r0   r1   r   H  s   
zHttp3.get_or_make_receiverintrK   c                 C  s
   | j | S r.   )r   )r/   r   r0   r0   r1   get_receiver_by_stream_idW  r3   zHttp3.get_receiver_by_stream_idr"   r'   c           
   	   C  s   zt dd |jD }W n ty   tdw |d }|d }|dd}|dd}|r2||d	< z|d
}W n tyD   tdw t| j}| j	||d||| jj
d}	t||	_|j|	_||	_|	S )Nc                 s  s*    | ]\}}| d |j ddfV  qdS )ASCIIsurrogateescape)errorsN)r   ).0kvr0   r0   r1   	<genexpr>]  s
    
z&Http3._make_request.<locals>.<genexpr>z2Header names may only contain US-ASCII characters.z:methodz:pathz:scheme z
:authorityhostr   z)URL may only contain US-ASCII characters.3    )r   rz   UnicodeDecodeErrorr   r|   r   UnicodeEncodeErrorr*   r-   request_classrC   r   	conn_infor   
_stream_id_scheme)
r/   r   rz   rj   r~   scheme	authority	url_bytes	transportrM   r0   r0   r1   r   Z  sH   

	zHttp3._make_requestN)r-   r)   rO   r   r4   rN   )r   r!   r4   rN   )r   r!   r4   r   )r   r   r4   rK   )r   r"   r4   r'   )rF   rG   rH   rI   HTTP3_AVAILABLEr    r"   r   r#   r   r2   r   r   r   r   r0   r0   r0   r1   r     s    

	

r   c                   @  s.   e Zd ZdZdddZddd	ZdddZdS )SessionTicketStorez5
    Simple in-memory store for session tickets.
    r4   rN   c                 C  s
   i | _ d S r.   )ticketsr5   r0   r0   r1   r2     r3   zSessionTicketStore.__init__ticketr%   c                 C  s   || j |j< d S r.   )r   r   )r/   r   r0   r0   r1   add  s   zSessionTicketStore.addlabelr   Optional[SessionTicket]c                 C  s   | j |d S r.   )r   r|   )r/   r   r0   r0   r1   r|     s   zSessionTicketStore.popNr   )r   r%   r4   rN   )r   r   r4   r   )rF   rG   rH   rI   r2   r   r|   r0   r0   r0   r1   r     s
    

r   rC   r&   rE   0Union[SanicSSLContext, CertSelector, SSLContext]c                 C  s   t |trtt|jd }| jjtju rt	dt |ts!t	dt
tt dg ddd}| jjp2d }|j|jd |jd	 |d
 |S )Nr   zSorry, you cannot currently use trustme as a local certificate generator for an HTTP/3 server. This is not yet supported. You should be able to use mkcert instead. For more information, see: https://github.com/aiortc/aioquic/issues/295.z!SSLContext is not SanicSSLContextsiduckFi   )alpn_protocols	is_clientmax_datagram_frame_sizecertkey)password)r   r   r   r   sanic_selectconfigLOCAL_CERT_CREATORr   TRUSTMEr   r$   r   r   TLS_CERT_PASSWORDload_cert_chainsanic)rC   rE   r   r   r0   r0   r1   
get_config  s$   

r   )rC   r&   rE   r   )K
__future__r   r   abcr   r   rE   r   typingr   r   r   r	   r
   r   sanic.compatr   sanic.constantsr   sanic.exceptionsr   r   r   r   sanic.helpersr   sanic.http.constantsr   sanic.http.streamr   sanic.http.tls.contextr   r   	sanic.logr   r   sanic.models.protocol_typesr   sanic.models.server_typesr   aioquic.h0.connectionr   r   aioquic.h3.connectionr   r   aioquic.h3.eventsr   r    r!   r"   r#   aioquic.quic.configurationr$   aioquic.tlsr%   r   ModuleNotFoundErrorr   r&   sanic.requestr'   sanic.responser(   $sanic.server.protocols.http_protocolr)   HttpConnectionr*   rK   rS   r   r   r   r   r   r0   r0   r0   r1   <module>   sP     	 /h