o
    h1[                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Zd dl
ZddlmZ ddlmZmZmZ ddlmZmZmZ ddlmZmZmZ ddlmZ dd	lmZ ed
ZdedefddZ G dd de j!Z"G dd deZ#G dd dZ$dS )    N   )NetworkStream)ConnectionNotAvailableLocalProtocolErrorRemoteProtocolError)OriginRequestResponse)Lock	SemaphoreShieldCancellation)Trace   )ConnectionInterfacezhttpcore.http2requestreturnc                 C   s   t dd | jD S )Nc                 s   s,    | ]\}}|  d kp|  dkV  qdS )s   content-length   transfer-encodingNlower.0kv r   T/var/www/html/flask_server/venv/lib/python3.10/site-packages/httpcore/_sync/http2.py	<genexpr>   s
    
z#has_body_headers.<locals>.<genexpr>)anyheaders)r   r   r   r   has_body_headers   s   r   c                   @   s   e Zd ZdZdZdZdS )HTTPConnectionStater   r      N)__name__
__module____qualname__ACTIVEIDLECLOSEDr   r   r   r   r   "   s    r   c                   @   sz  e Zd ZdZejjddZ	dDdede	de
je fdd	Zd
edefddZd
eddfddZd
ededdfddZd
ededdfddZd
edededdfddZd
ededdfddZd
edede
jee
je
jeef  f fddZd
edede
je fddZd
edede
jejjejj ejj!f fddZ"	dDd
ede
je ddfd d!Z#d"ejj$ddfd#d$Z%deddfd%d&Z&dEd'd(Z'd
ede
jejj$ fd)d*Z(d
eddfd+d,Z)d
ededefd-d.Z*dede+fd/d0Z,de+fd1d2Z-de+fd3d4Z.de+fd5d6Z/de+fd7d8Z0de1fd9d:Z2de1fd;d<Z3dFd=d>Z4			dGd?e
je
j5e6  d@e
je6 dAe
je7j8 ddfdBdCZ9dS )HHTTP2Connection   F)validate_inbound_headersNoriginstreamkeepalive_expiryc                 C   s   || _ || _|| _tjj| jd| _tj	| _
d | _d| _t | _t | _t | _t | _d| _d| _d| _i | _d | _d | _d | _d S )N)configr   F)_origin_network_stream_keepalive_expiryh2
connectionH2ConnectionCONFIG	_h2_stater   r%   _state
_expire_at_request_countr
   
_init_lock_state_lock
_read_lock_write_lock_sent_connection_init_used_all_stream_ids_connection_error_events_connection_terminated_read_exception_write_exception)selfr*   r+   r,   r   r   r   __init__,   s(   
zHTTP2Connection.__init__r   r   c           
      C   s  |  |jjstd|jj d| j | j# | jtjtj	fv r0|  j
d7  _
d | _tj| _nt W d    n1 s=w   Y  | jv | jsz%d|i}tdt|| | jdi | W d    n1 shw   Y  W n& ty } zt  |   W d    |1 sw   Y  |d }~ww d| _d| _| jjj}t|| _t|| j D ]}| j  qW d    n1 sw   Y  | j  z| j }g | j|< W n tj j!y   d| _"|  j
d8  _
t w z|||d}tdt|| | j#||d W d    n	1 sw   Y  td	t|| | j$||d W d    n	1 s*w   Y  td
t||}| j%||d\}}	||	f|_&W d    n	1 sPw   Y  t'||	t(| ||dd| j)|ddW S  ty } zMt * d|i}tdt|| | j*|d W d    n	1 sw   Y  W d    n	1 sw   Y  t+|tj j,r| j-rt.| j-t/||d }~ww )NzAttempted to send request to z on connection to r   r   send_connection_initTr   	stream_idsend_request_headerssend_request_bodyreceive_response_headersrH   s   HTTP/2)http_versionnetwork_streamrH   )statusr   content
extensionsrH   response_closedr   )0can_handle_requesturlr*   RuntimeErrorr.   r:   r6   r   r$   r%   r8   r7   r   r9   r=   r   logger_send_connection_initBaseExceptionr   close_max_streamsr5   local_settingsmax_concurrent_streamsr   _max_streams_semaphorerangeacquireget_next_available_stream_idr@   r1   
exceptionsNoAvailableStreamIDErrorr>   _send_request_headers_send_request_body_receive_responsereturn_valuer	   HTTP2ConnectionByteStreamr/   _response_closed
isinstanceProtocolErrorrA   r   r   )
rD   r   kwargsexclocal_settings_max_streams_rH   tracerO   r   r   r   r   handle_requestU   s   










zHTTP2Connection.handle_requestc                 C   sf   t jjdt jjjdt jjjdt jjjdid| j_| jjt jjj	= | j
  | jd | | dS )z
        The HTTP/2 connection requires some initial setup before we can start
        using individual request/response streams on it.
        Tr   d   r(   )clientinitial_values   N)r1   settingsSettingsSettingCodesENABLE_PUSHMAX_CONCURRENT_STREAMSMAX_HEADER_LIST_SIZEr5   r[   ENABLE_CONNECT_PROTOCOLinitiate_connectionincrement_flow_control_window_write_outgoing_data)rD   r   r   r   r   rW      s   




z%HTTP2Connection._send_connection_initrH   c                 C   s   t | }dd |jD d }d|jfd|fd|jjfd|jjfgdd |jD  }| jj|||d	 | jjd
|d | 	| dS )z@
        Send the request headers to a given stream ID.
        c                 S   s    g | ]\}}|  d kr|qS )   hostr   r   r   r   r   
<listcomp>   s     z9HTTP2Connection._send_request_headers.<locals>.<listcomp>r   s   :methods
   :authoritys   :schemes   :pathc                 S   s(   g | ]\}}|  d vr|  |fqS ))r   r   r   r   r   r   r   r      s    
)
end_streamrt   rL   N)
r   r   methodrT   schemetargetr5   send_headersr}   r~   )rD   r   rH   r   	authorityr   r   r   r   rc      s   


z%HTTP2Connection._send_request_headersc                 C   sH   t |sdS t|jtjsJ |jD ]	}| ||| q| || dS )zP
        Iterate over the request body sending it to a given stream ID.
        N)r   ri   r+   typingIterable_send_stream_data_send_end_stream)rD   r   rH   datar   r   r   rd      s   
z"HTTP2Connection._send_request_bodyr   c                 C   s\   |r,|  ||}tt||}|d| ||d }}| j|| | | |sdS dS )zI
        Send a single chunk of data in one or more data frames.
        N)_wait_for_outgoing_flowminlenr5   	send_datar~   )rD   r   rH   r   max_flow
chunk_sizechunkr   r   r   r     s   
z!HTTP2Connection._send_stream_datac                 C   s   | j | | | dS )z`
        Send an empty data frame on on a given stream ID with the END_STREAM flag set.
        N)r5   r   r~   )rD   r   rH   r   r   r   r     s   z HTTP2Connection._send_end_streamc                 C   st   	 |  ||}t|tjjrnqd}g }|jD ]\}}|dkr)t|jddd}q|ds5|	||f q||fS )zT
        Return the response status code and headers for a given stream ID.
        T   s   :statusasciiignore)errors   :)
_receive_stream_eventri   r1   eventsResponseReceivedr   intdecode
startswithappend)rD   r   rH   eventstatus_coder   r   r   r   r   r   re     s   
z!HTTP2Connection._receive_responsec                 c   sZ    	 |  ||}t|tjjr#|j}| j|| | | |j	V  n	t|tjj
r,dS q)z]
        Iterator that returns the bytes of the response body for a given stream ID.
        TN)r   ri   r1   r   DataReceivedflow_controlled_lengthr5   acknowledge_received_datar~   r   StreamEnded)rD   r   rH   r   amountr   r   r   _receive_response_body2  s   

z&HTTP2Connection._receive_response_bodyc                 C   sN   | j |s| || | j |r| j | d}t|tjjr%t||S )z
        Return the next available event for a given stream ID.

        Will read more data from the network if required.
        r   )	r@   get_receive_eventspopri   r1   r   StreamResetr   )rD   r   rH   r   r   r   r   r   B  s   
z%HTTP2Connection._receive_stream_eventc              
   C   s>  | j  | jdur$| jj}|r|r||kr|  jd8  _t t| j|du s.| j|s| |}|D ]S}t	|t
jjr]tdt|}| | ||_W d   n1 sWw   Y  q5t	|t
jjt
jjt
jjt
jjfr~|j| jv r}| j|j | q5t	|t
jjr|| _q5W d   n1 sw   Y  | | dS )zp
        Read some data from the network until we see one or more events
        for a given stream ID.
        Nr   receive_remote_settings)r;   rA   last_stream_idr8   r   r   r@   r   _read_incoming_datari   r1   r   RemoteSettingsChangedr   rV   _receive_remote_settings_changerf   r   r   r   r   rH   r   ConnectionTerminatedr~   )rD   r   rH   r   r   r   ro   r   r   r   r   S  sF   



	'zHTTP2Connection._receive_eventsr   c                 C   s   |j tjjj}|rIt|j| jj	j
}|rK|| jkrM|| jkr1| j  |  jd7  _|| jks || jk rO| j  |  jd8  _|| jk s6d S d S d S d S d S )Nr   )changed_settingsr   r1   ru   rw   ry   r   	new_valuer5   r[   r\   rZ   r]   releaser_   )rD   r   r\   new_max_streamsr   r   r   r     s(   




z/HTTP2Connection._receive_remote_settings_changec                 C   s   | j   | j|= | jW | jr| js|   n3| jtjkrC| jsStj	| _| j
d ur4t }|| j
 | _| jr[|   W d    d S W d    d S W d    d S W d    d S W d    d S 1 sfw   Y  d S N)r]   r   r@   r:   rA   rY   r6   r   r$   r%   r0   time	monotonicr7   r>   )rD   rH   nowr   r   r   rh     s*   



	"z HTTP2Connection._response_closedc                 C   s    | j   tj| _| j  d S r   )r5   close_connectionr   r&   r6   r/   rY   rD   r   r   r   rY     s   
zHTTP2Connection.closec              
   C   s   |j di }|dd }| jd ur| jz| j| j|}|dkr&tdW n ty; } z|| _d| _|d }~ww | j	
|}|S )Ntimeoutread    zServer disconnectedT)rQ   r   rB   r/   r   READ_NUM_BYTESr   	Exceptionr?   r5   receive_data)rD   r   timeoutsr   r   rl   r   r   r   r   r     s"   
	z#HTTP2Connection._read_incoming_datac                 C   s   |j di }|dd }| j4 | j }| jd ur| jz	| j|| W n ty; } z|| _d| _	|d }~ww W d    d S 1 sGw   Y  d S )Nr   writeT)
rQ   r   r<   r5   data_to_sendrC   r/   r   r   r?   )rD   r   r   r   r   rl   r   r   r   r~     s    

	"z$HTTP2Connection._write_outgoing_datac                 C   sZ   | j |}| j j}t||}|dkr+| | | j |}| j j}t||}|dks|S )a  
        Returns the maximum allowable outgoing flow for a given stream.

        If the allowable flow is zero, then waits on the network until
        WindowUpdated frames have increased the flow rate.
        https://tools.ietf.org/html/rfc7540#section-6.9
        r   )r5   local_flow_control_windowmax_outbound_frame_sizer   r   )rD   r   rH   
local_flowmax_frame_sizeflowr   r   r   r     s   


z'HTTP2Connection._wait_for_outgoing_flowc                 C   s
   || j kS r   )r.   rD   r*   r   r   r   rS     s   
z"HTTP2Connection.can_handle_requestc                 C   s2   | j tjko| j o| j o| jjjtj	j
jk S r   )r6   r   r&   r?   r>   r5   state_machinestater1   r2   ConnectionStater   r   r   r   is_available  s   zHTTP2Connection.is_availablec                 C   s   t  }| jd uo|| jkS r   )r   r   r7   )rD   r   r   r   r   has_expired  s   zHTTP2Connection.has_expiredc                 C      | j tjkS r   )r6   r   r%   r   r   r   r   is_idle     zHTTP2Connection.is_idlec                 C   r   r   )r6   r   r&   r   r   r   r   	is_closed  r   zHTTP2Connection.is_closedc                 C   s$   t | j}|d| jj d| j S )Nz
, HTTP/2, , Request Count: )strr.   r6   namer8   r   r   r   r   info  s
   
zHTTP2Connection.infoc              	   C   s6   | j j}t| j}d| d|d| jj d| j d	S )N<z [z, r   z]>)	__class__r!   r   r.   r6   r   r8   )rD   
class_namer*   r   r   r   __repr__  s   
zHTTP2Connection.__repr__c                 C   s   | S r   r   r   r   r   r   	__enter__#  s   zHTTP2Connection.__enter__exc_type	exc_value	tracebackc                 C   s   |    d S r   )rY   )rD   r   r   r   r   r   r   __exit__&  s   zHTTP2Connection.__exit__r   r   N)r   r'   )NNN):r!   r"   r#   r   r1   r-   H2Configurationr4   r   r   r   OptionalfloatrE   r   r	   rp   rW   r   rc   rd   bytesr   r   TupleListre   Iteratorr   Unionr   r   r   r   r   r   Eventr   rh   rY   r   r~   r   boolrS   r   r   r   r   r   r   r   r   TyperX   typesTracebackTyper   r   r   r   r   r'   (   s    
)f!
	



0
	


r'   c                   @   sD   e Zd ZdedededdfddZdeje	 fdd	Z
dd
dZdS )rg   r2   r   rH   r   Nc                 C   s   || _ || _|| _d| _d S )NF)_connection_request
_stream_id_closed)rD   r2   r   rH   r   r   r   rE   0  s   
z"HTTP2ConnectionByteStream.__init__c                 c   s    | j | jd}z-tdt| j | | jj| j | jdD ]}|V  qW d    W d S 1 s.w   Y  W d S  ty[ } zt  |   W d    |1 sPw   Y  |d }~ww )NrG   receive_response_body)	r   r   r   rV   r   r   rX   r   rY   )rD   rk   r   rl   r   r   r   __iter__8  s&   
&

z"HTTP2ConnectionByteStream.__iter__c                 C   s`   | j s.d| _ d| ji}tdt| j| | jj| jd W d    d S 1 s'w   Y  d S d S )NTrH   rR   rL   )r   r   r   rV   r   r   rh   )rD   rk   r   r   r   rY   H  s   
"zHTTP2ConnectionByteStream.closer   )r!   r"   r#   r'   r   r   rE   r   r   r   r   rY   r   r   r   r   rg   /  s    
rg   )%enumloggingr   r   r   	h2.configr1   h2.connection	h2.eventsh2.exceptionsh2.settings_backends.baser   _exceptionsr   r   r   _modelsr   r   r	   _synchronizationr
   r   r   _tracer   
interfacesr   	getLoggerrV   r   r   IntEnumr   r'   rg   r   r   r   r   <module>   s2    
    