o
    MK&h]                     @  s  d dl m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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ddZ!G dd dej"Z#G dd deZ$G dd dZ%dS )    )annotationsN   )AsyncNetworkStream)ConnectionNotAvailableLocalProtocolErrorRemoteProtocolError)OriginRequestResponse)	AsyncLockAsyncSemaphoreAsyncShieldCancellation)Trace   )AsyncConnectionInterfacezhttpcore.http2requestr	   returnboolc                 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   H/var/www/html/venv/lib/python3.10/site-packages/httpcore/_async/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                   @  s2  e Zd ZdZejjddZ	dWdXddZdYddZ	dZd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	dWd`d,d-Zdad0d1Zdbd2d3Zdcd4d5Zddd7d8ZdZd9d:Zded;d<Zdfd>d?Zdgd@dAZdgdBdCZdgdDdEZdgdFdGZdhdIdJZdhdKdLZdidMdNZ 			djdkdUdVZ!dS )lAsyncHTTP2Connection   F)validate_inbound_headersNoriginr   streamr   keepalive_expiryfloat | Nonec                 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AsyncHTTP2Connection.__init__r   r	   r   r
   c                   sD  |  |jjstd|jj d| j | j4 I d H & | jtjtj	fv r5|  j
d7  _
d | _tj| _nt W d   I d H  n1 I d H sHw   Y  | j4 I d H  | jsz2d|i}tdt||4 I d H  | jdi |I d H  W d   I d H  n1 I d H sw   Y  W n) ty } zt  |  I d H  W d    |1 sw   Y  |d }~ww d| _d| _| jjj}t|| _t|| j D ]
}| j I d H  qW d   I d H  n1 I d H sw   Y  | j I d H  z| j }g | j|< W n tj j!y   d| _"|  j
d8  _
t w z||d}tdt||4 I d H  | j#||dI d H  W d   I d H  n1 I d H sDw   Y  td	t||4 I d H  | j$||dI d H  W d   I d H  n1 I d H spw   Y  td
t||4 I d H }| j%||dI d H \}	}
|	|
f|_&W d   I d H  n1 I d H sw   Y  t'|	|
t(| ||dd| j)|ddW S  ty! } zZt 7 d|i}tdt||4 I d H  | j*|dI d H  W d   I d H  n1 I d H sw   Y  W d    n	1 sw   Y  t+|tj j,r| j-rt.| 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rK   s   HTTP/2)http_versionnetwork_streamrK   )statusr   content
extensionsrK   response_closedr   )0can_handle_requesturlr,   RuntimeErrorr1   r=   r9   r!   r&   r'   r;   r:   r   r<   r@   r   logger_send_connection_initBaseExceptionr   aclose_max_streamsr8   local_settingsmax_concurrent_streamsr   _max_streams_semaphorerangeacquireget_next_available_stream_idrC   r4   
exceptionsNoAvailableStreamIDErrorrA   _send_request_headers_send_request_body_receive_responsereturn_valuer
   HTTP2ConnectionByteStreamr2   _response_closed
isinstanceProtocolErrorrD   r   r   )rG   r   
sci_kwargsexclocal_settings_max_streams_rK   kwargstracerR   r   r   r   r   handle_async_requestU   s   
((

(

***
*

z)AsyncHTTP2Connection.handle_async_requestNonec                   sn   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 | |I dH  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)r4   settingsSettingsSettingCodesENABLE_PUSHMAX_CONCURRENT_STREAMSMAX_HEADER_LIST_SIZEr8   r^   ENABLE_CONNECT_PROTOCOLinitiate_connectionincrement_flow_control_window_write_outgoing_data)rG   r   r   r   r   rZ      s   




z*AsyncHTTP2Connection._send_connection_initrK   intc                   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 | 	|I dH  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     z>AsyncHTTP2Connection._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_streamry   rO   N)
r    r   methodrW   schemetargetr8   send_headersr   r   )rG   r   rK   r   	authorityr   r   r   r   rf      s   


z*AsyncHTTP2Connection._send_request_headersc                   s`   t |sdS t|jtjsJ |j2 z3 dH W }| |||I dH  q6 | ||I dH  dS )zP
        Iterate over the request body sending it to a given stream ID.
        N)r    rl   r-   typingAsyncIterable_send_stream_data_send_end_stream)rG   r   rK   datar   r   r   rg      s   z'AsyncHTTP2Connection._send_request_bodyr   bytesc                   sj   |r3|  ||I dH }tt||}|d| ||d }}| j|| | |I dH  |sdS dS )zI
        Send a single chunk of data in one or more data frames.
        N)_wait_for_outgoing_flowminlenr8   	send_datar   )rG   r   rK   r   max_flow
chunk_sizechunkr   r   r   r   	  s   z&AsyncHTTP2Connection._send_stream_datac                   s"   | j | | |I dH  dS )z`
        Send an empty data frame on on a given stream ID with the END_STREAM flag set.
        N)r8   r   r   )rG   r   rK   r   r   r   r     s   z%AsyncHTTP2Connection._send_end_stream%tuple[int, list[tuple[bytes, bytes]]]c                   s   	 |  ||I dH }t|tjjrnqd}g }|jdusJ |jD ]\}}|dkr4t|jddd}q"|ds@|	||f q"||fS )	zT
        Return the response status code and headers for a given stream ID.
        TN   s   :statusasciiignore)errors   :)
_receive_stream_eventrl   r4   eventsResponseReceivedr   r   decode
startswithappend)rG   r   rK   eventstatus_coder   r   r   r   r   r   rh     s    
z&AsyncHTTP2Connection._receive_responsetyping.AsyncIterator[bytes]c                 C s   	 |  ||I dH }t|tjjr7|jdusJ |jdus J |j}| j|| | 	|I dH  |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   rl   r4   r   DataReceivedflow_controlled_lengthr   r8   acknowledge_received_datar   StreamEnded)rG   r   rK   r   amountr   r   r   _receive_response_body5  s   
z+AsyncHTTP2Connection._receive_response_bodyKh2.events.ResponseReceived | h2.events.DataReceived | h2.events.StreamEndedc                   sV   | j |s| ||I dH  | 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.
        Nr   )	rC   get_receive_eventspoprl   r4   r   StreamResetr   )rG   r   rK   r   r   r   r   r   G  s   z*AsyncHTTP2Connection._receive_stream_event
int | Nonec                   sz  | j 4 I dH  | jdur)| jj}|r$|r$||kr$|  jd8  _t t| j|du s3| j|s| |I dH }|D ]`}t	|t
jjrrtdt|4 I dH }| |I dH  ||_W d  I dH  n1 I dH slw   Y  q=t	|t
jjt
jjt
jjt
jjfr|j| jv r| j|j | q=t	|t
jjr|| _q=W d  I dH  n1 I dH sw   Y  | |I dH  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>   rD   last_stream_idr;   r   r   rC   r   _read_incoming_datarl   r4   r   RemoteSettingsChangedr   rY   _receive_remote_settings_changeri   r   r   r   r   rK   r   ConnectionTerminatedr   )rG   r   rK   r   r   r   rs   r   r   r   r   V  sH   

(	('z$AsyncHTTP2Connection._receive_eventsr   h2.events.RemoteSettingsChangedc                   s   |j tjjj}|rPt|j| jj	j
}|rR|| jkrT|| jkr5| j I d H  |  jd7  _|| jks!|| jk rV| j I d H  |  jd8  _|| jk s:d S d S d S d S d S )Nr   )changed_settingsr   r4   rz   r|   r~   r   	new_valuer8   r^   r_   r]   r`   releaserb   )rG   r   r_   new_max_streamsr   r   r   r     s*   


z4AsyncHTTP2Connection._receive_remote_settings_changec              	     s  | j  I d H  | j|= | j4 I d H l | jr#| js#|  I d H  n<| jtjkrT| jsjtj	| _| j
d ur?t }|| j
 | _| jru|  I d H  W d   I d H  d S W d   I d H  d S W d   I d H  d S W d   I d H  d S W d   I d H  d S 1 I d H sw   Y  d S N)r`   r   rC   r=   rD   r\   r9   r!   r&   r'   r3   time	monotonicr:   rA   )rG   rK   nowr   r   r   rk     s,   
	.z%AsyncHTTP2Connection._response_closedc                   s(   | j   tj| _| j I d H  d S r   )r8   close_connectionr!   r(   r9   r2   r\   rG   r   r   r   r\     s   
zAsyncHTTP2Connection.acloselist[h2.events.Event]c              
     s   |j di }|dd }| jd ur| jz| j| j|I d H }|dkr*tdW n ty? } z|| _d| _|d }~ww | j	
|}|S )Ntimeoutread    zServer disconnectedT)rT   r   rE   r2   r   READ_NUM_BYTESr   	ExceptionrB   r8   receive_data)rG   r   timeoutsr   r   ro   r   r   r   r   r     s$   
	z(AsyncHTTP2Connection._read_incoming_datac                   s   |j di }|dd }| j4 I d H : | j }| jd ur#| jz| j||I d H  W n tyC } z|| _d| _	|d }~ww W d   I d H  d S 1 I d H sUw   Y  d S )Nr   writeT)
rT   r   r?   r8   data_to_sendrF   r2   r   r   rB   )rG   r   r   r   r   ro   r   r   r   r     s"   

	.z)AsyncHTTP2Connection._write_outgoing_datac                   sb   | j |}| j j}t||}|dkr/| |I dH  | 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   N)r8   local_flow_control_windowmax_outbound_frame_sizer   r   )rG   r   rK   
local_flowmax_frame_sizeflowr   r   r   r     s   

z,AsyncHTTP2Connection._wait_for_outgoing_flowr   c                 C  s
   || j kS r   )r1   rG   r,   r   r   r   rV     s   
z'AsyncHTTP2Connection.can_handle_requestc                 C  s2   | j tjko| j o| j o| jjjtj	j
jk S r   )r9   r!   r(   rB   rA   r8   state_machinestater4   r5   ConnectionStater   r   r   r   is_available  s   z!AsyncHTTP2Connection.is_availablec                 C  s   t  }| jd uo|| jkS r   )r   r   r:   )rG   r   r   r   r   has_expired
  s   z AsyncHTTP2Connection.has_expiredc                 C     | j tjkS r   )r9   r!   r'   r   r   r   r   is_idle     zAsyncHTTP2Connection.is_idlec                 C  r   r   )r9   r!   r(   r   r   r   r   	is_closed  r   zAsyncHTTP2Connection.is_closedstrc                 C  s$   t | j}|d| jj d| j S )Nz
, HTTP/2, , Request Count: )r   r1   r9   namer;   r   r   r   r   info  s
   
zAsyncHTTP2Connection.infoc              	   C  s6   | j j}t| j}d| d|d| jj d| j d	S )N<z [z, r   z]>)	__class__r#   r   r1   r9   r   r;   )rG   
class_namer,   r   r   r   __repr__  s   
zAsyncHTTP2Connection.__repr__c                   s   | S r   r   r   r   r   r   
__aenter__&  s   zAsyncHTTP2Connection.__aenter__exc_typetype[BaseException] | None	exc_valueBaseException | None	tracebacktypes.TracebackType | Nonec                   s   |   I d H  d S r   )r\   )rG   r   r   r   r   r   r   	__aexit__)  s   zAsyncHTTP2Connection.__aexit__r   )r,   r   r-   r   r.   r/   )r   r	   r   r
   )r   r	   r   ru   )r   r	   rK   r   r   ru   )r   r	   rK   r   r   r   r   ru   )r   r	   rK   r   r   r   )r   r	   rK   r   r   r   )r   r	   rK   r   r   r   )r   r	   rK   r   r   ru   )r   r   r   ru   )rK   r   r   ru   r   ru   )r   r	   r   r   )r   r	   rK   r   r   r   )r,   r   r   r   )r   r   )r   r   )r   r)   )NNN)r   r   r   r   r   r   r   ru   )"r#   r$   r%   r   r4   r0   H2Configurationr7   rH   rt   rZ   rf   rg   r   r   rh   r   r   r   r   rk   r\   r   r   r   rV   r   r   r   r   r   r   r   r   r   r   r   r   r)   *   sD    
'
h
!



	


0


	









r)   c                   @  s*   e Zd Zdd	d
ZdddZdddZdS )rj   r5   r)   r   r	   rK   r   r   ru   c                 C  s   || _ || _|| _d| _d S )NF)_connection_request
_stream_id_closed)rG   r5   r   rK   r   r   r   rH   3  s   
z"HTTP2ConnectionByteStream.__init__r   c                 C s   | j | jd}z<tdt| j |4 I d H " | jj| j | jd2 z	3 d H W }|V  q 6 W d   I d H  W d S 1 I d H s=w   Y  W d S  tym } zt  |  I d H  W d    |1 sbw   Y  |d }~ww )NrJ   receive_response_body)	r   r   r   rY   r   r   r[   r   r\   )rG   rr   r   ro   r   r   r   	__aiter__;  s&   2
z#HTTP2ConnectionByteStream.__aiter__c              	     s|   | j s<d| _ d| ji}tdt| j|4 I d H  | jj| jdI d H  W d   I d H  d S 1 I d H s5w   Y  d S d S )NTrK   rU   rO   )r   r   r   rY   r   r   rk   )rG   rr   r   r   r   r\   K  s   
.z HTTP2ConnectionByteStream.acloseN)r5   r)   r   r	   rK   r   r   ru   )r   r   r   )r#   r$   r%   rH   r   r\   r   r   r   r   rj   2  s    

rj   )r   r	   r   r   )&
__future__r   enumloggingr   typesr   	h2.configr4   h2.connection	h2.eventsh2.exceptionsh2.settings_backends.baser   _exceptionsr   r   r   _modelsr   r	   r
   _synchronizationr   r   r   _tracer   
interfacesr   	getLoggerrY   r    IntEnumr!   r)   rj   r   r   r   r   <module>   s4    

    