U
    	fG]                     @   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eedddZ G dd de j!Z"G dd deZ#G dd dZ$dS )    N   )AsyncNetworkStream)ConnectionNotAvailableLocalProtocolErrorRemoteProtocolError)OriginRequestResponse)	AsyncLockAsyncSemaphoreAsyncShieldCancellation)Trace   )AsyncConnectionInterfacez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   X/var/www/html/apigroqsegura/apigroq/lib/python3.8/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                   @   s:  e Zd ZdZejjddZdBee	e
je dddZeedd	d
ZeddddZeeddddZeeddddZeeeddddZeeddddZeee
jee
je
jeef  f dddZeee
je dddZeee
jejjejj ejj!f dddZ"dCee
je ddddZ#ejj$ddd d!Z%edd"d#d$Z&dd%d&d'Z'ee
jejj$ dd(d)Z(eddd*d+Z)eeedd,d-Z*ee+d.d/d0Z,e+d%d1d2Z-e+d%d3d4Z.e+d%d5d6Z/e+d%d7d8Z0e1d%d9d:Z2e1d%d;d<Z3d d%d=d>Z4dDe
je
j5e6  e
je6 e
je7j8 dd?d@dAZ9dS )EAsyncHTTP2Connection   F)Z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
connectionZ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   c           
         sx  |  |jjs(td|jj d| j | j4 I d H < | jtjtj	fkrh|  j
d7  _
d | _tj| _nt W 5 Q I d H R X | j4 I d H  | jslzFd|i}tdt||4 I d H  | jf |I d H  W 5 Q I d H R X W nH tk
r$ } z(t  |  I d H  W 5 Q R X |W 5 d }~X Y nX d| _d| _| jjj}t|| _t|| j D ]}| j I d H  qTW 5 Q I d H R X | j I d H  z| j }g | j|< W n4 tj j!k
r   d| _"|  j
d8  _
t Y nX z||d}tdt||4 I d H  | j#||dI d H  W 5 Q I d H R X td	t||4 I d H  | j$||dI d H  W 5 Q I d H R X td
t||4 I d H (}| j%||dI d H \}}	||	f|_&W 5 Q I d H R X t'||	t(| ||dd| j)|ddW S  tk
rr } zt H d|i}tdt||4 I d H  | j*|dI d H  W 5 Q I d H R X W 5 Q R X t+|tj j,r^| j-rVt.| j-t/||W 5 d }~X Y nX d S )NzAttempted to send request to z on connection to r   r   Zsend_connection_initTr   	stream_idsend_request_headerssend_request_bodyreceive_response_headersrF   s   HTTP/2)http_versionnetwork_streamrF   )statusr   content
extensionsrF   response_closed)0can_handle_requesturlr*   RuntimeErrorr.   r9   r5   r    r%   r&   r7   r6   r   r8   r<   r   logger_send_connection_initBaseExceptionr   aclose_max_streamsr4   local_settingsmax_concurrent_streamsr   _max_streams_semaphorerangeacquireZget_next_available_stream_idr?   r1   
exceptionsZNoAvailableStreamIDErrorr=   _send_request_headers_send_request_body_receive_responsereturn_valuer	   HTTP2ConnectionByteStreamr/   _response_closed
isinstanceProtocolErrorr@   r   r   )
rC   r   kwargsexcZlocal_settings_max_streams_rF   tracerM   r   r   r   r   handle_async_requestU   s    
&
$

$$    
,

z)AsyncHTTP2Connection.handle_async_requestc                    sl   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)   )clientZinitial_values   N)r1   settingsZSettingsSettingCodesZENABLE_PUSHMAX_CONCURRENT_STREAMSZMAX_HEADER_LIST_SIZEr4   rY   ZENABLE_CONNECT_PROTOCOLZinitiate_connectionincrement_flow_control_window_write_outgoing_data)rC   r   r   r   r   rU      s        

z*AsyncHTTP2Connection._send_connection_init)r   rF   r   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 | 	|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 kr|  |fqS ))rt   r   r   r   r   r   r   ru      s
   )
end_streamrn   rJ   N)
r   r   methodrR   schemetargetr4   Zsend_headersrr   rs   )rC   r   rF   rv   	authorityr   r   r   r   r_      s    


z*AsyncHTTP2Connection._send_request_headersc                    s^   t |sdS t|jtjst|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   re   r+   typingAsyncIterableAssertionError_send_stream_data_send_end_stream)rC   r   rF   datar   r   r   r`      s    z'AsyncHTTP2Connection._send_request_body)r   rF   r   r   c                    sb   |r^|  ||I dH }tt||}|d| ||d  }}| j|| | |I dH  q dS )zI
        Send a single chunk of data in one or more data frames.
        N)_wait_for_outgoing_flowminlenr4   	send_datars   )rC   r   rF   r   Z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)r4   rv   rs   )rC   r   rF   r   r   r   r     s    z%AsyncHTTP2Connection._send_end_streamc                    sx   |  ||I dH }t|tjjr q$q d}g }|jD ]<\}}|dkrVt|jddd}q2|ds2|	||f q2||fS )zT
        Return the response status code and headers for a given stream ID.
        N   s   :statusasciiignore)errors   :)
_receive_stream_eventre   r1   eventsResponseReceivedr   intdecode
startswithappend)rC   r   rF   eventstatus_coder   r   r   r   r   r   ra     s    
z&AsyncHTTP2Connection._receive_responsec                 C  sd   |  ||I dH }t|tjjrN|j}| j|| | |I dH  |j	V  q t|tjj
r q`q dS )z]
        Iterator that returns the bytes of the response body for a given stream ID.
        N)r   re   r1   r   DataReceivedZflow_controlled_lengthr4   Zacknowledge_received_datars   r   StreamEnded)rC   r   rF   r   amountr   r   r   _receive_response_body2  s    
z+AsyncHTTP2Connection._receive_response_bodyc                    sJ   | j |s | ||I dH  q | j | d}t|tjjrFt||S )z
        Return the next available event for a given stream ID.

        Will read more data from the network if required.
        Nr   )	r?   get_receive_eventspopre   r1   r   StreamResetr   )rC   r   rF   r   r   r   r   r   B  s    
z*AsyncHTTP2Connection._receive_stream_eventc                    sL  | j 4 I dH  | jdk	rR| jj}|rH|rH||krH|  jd8  _t t| j|dksh| j|s(| |I dH }|D ]}t	|t
jjrtdt|4 I dH }| |I dH  ||_W 5 Q I dH R X q|t	|t
jjt
jjt
jjt
jjfr|j| jkr&| j|j | q|t	|t
jjr||| _q|W 5 Q I dH R X | |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   Zreceive_remote_settings)r:   r@   last_stream_idr7   r   r   r?   r   _read_incoming_datare   r1   r   ZRemoteSettingsChangedr   rT   _receive_remote_settings_changerb   r   r   r   r   rF   r   ZConnectionTerminatedrs   )rC   r   rF   r   r   r   rj   r   r   r   r   S  s@    

  	z$AsyncHTTP2Connection._receive_events)r   r   c                    s   |j tjjj}|rt|j| jj	j
}|r|| jkr|| jkr`| j I d H  |  jd7  _q6|| jk r| j I d H  |  jd8  _q`d S )Nr   )Zchanged_settingsr   r1   ro   rp   rq   r   	new_valuer4   rY   rZ   rX   r[   releaser]   )rC   r   rZ   Znew_max_streamsr   r   r   r     s    

z4AsyncHTTP2Connection._receive_remote_settings_change)rF   r   c              
      s   | j  I d H  | j|= | j4 I d H n | jrD| jsD|  I d H  nL| jtjkr| jstj	| _| j
d k	r|t }|| j
 | _| jr|  I d H  W 5 Q I d H R X d S N)r[   r   r?   r9   r@   rW   r5   r    r%   r&   r0   time	monotonicr6   r=   )rC   rF   nowr   r   r   rd     s    
z%AsyncHTTP2Connection._response_closedr   c                    s&   | j   tj| _| j I d H  d S r   )r4   Zclose_connectionr    r'   r5   r/   rW   rC   r   r   r   rW     s    
zAsyncHTTP2Connection.aclosec              
      s   |j di }|dd }| jd k	r*| jz*| j| j|I d H }|dkrRtdW n2 tk
r } z|| _d| _|W 5 d }~X Y nX | j	
|}|S )Ntimeoutread    zServer disconnectedT)rO   r   rA   r/   r   READ_NUM_BYTESr   	Exceptionr>   r4   receive_data)rC   r   timeoutsr   r   rh   r   r   r   r   r     s    
	z(AsyncHTTP2Connection._read_incoming_datac                    s   |j di }|dd }| j4 I d H l | j }| jd k	rD| jz| j||I d H  W n2 tk
r } z|| _d| _	|W 5 d }~X Y nX W 5 Q I d H R X d S )Nr   writeT)
rO   r   r;   r4   data_to_sendrB   r/   r   r   r>   )rC   r   r   r   r   rh   r   r   r   rs     s    

	z)AsyncHTTP2Connection._write_outgoing_datac                    sZ   | j |}| j j}t||}|dkrV| |I dH  | j |}| j j}t||}q|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)r4   Zlocal_flow_control_windowZmax_outbound_frame_sizer   r   )rC   r   rF   Z
local_flowZmax_frame_sizeflowr   r   r   r     s    
z,AsyncHTTP2Connection._wait_for_outgoing_flow)r*   r   c                 C   s
   || j kS r   )r.   rC   r*   r   r   r   rQ     s    z'AsyncHTTP2Connection.can_handle_requestc                 C   s2   | j tjko0| j o0| j o0| jjjtj	j
jk S r   )r5   r    r'   r>   r=   r4   Zstate_machinestater1   r2   ConnectionStater   r   r   r   is_available  s    z!AsyncHTTP2Connection.is_availablec                 C   s   t  }| jd k	o|| jkS r   )r   r   r6   )rC   r   r   r   r   has_expired  s    z AsyncHTTP2Connection.has_expiredc                 C   s   | j tjkS r   )r5   r    r&   r   r   r   r   is_idle  s    zAsyncHTTP2Connection.is_idlec                 C   s   | j tjkS r   )r5   r    r'   r   r   r   r   	is_closed  s    zAsyncHTTP2Connection.is_closedc                 C   s$   t | j}|d| jj d| j S )Nz
, HTTP/2, , Request Count: )strr.   r5   namer7   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   r.   r5   r   r7   )rC   
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	exc_value	tracebackr   c                    s   |   I d H  d S r   )rW   )rC   r   r   r   r   r   r   	__aexit__&  s    zAsyncHTTP2Connection.__aexit__)N)N)NNN):r"   r#   r$   r   r1   r-   ZH2Configurationr3   r   r   r{   OptionalfloatrD   r   r	   rk   rU   r   r_   r`   bytesr~   r   TupleListra   AsyncIteratorr   Unionr   r   r   r   r   r   Eventr   rd   rW   r   rs   r   boolrQ   r   r   r   r   r   r   r   r   TyperV   typesTracebackTyper   r   r   r   r   r(   (   s~    )f!  
     0
   
r(   c                   @   sB   e Zd ZeeeddddZeje	 dddZ
dddd	ZdS )
rc   N)r2   r   rF   r   c                 C   s   || _ || _|| _d| _d S )NF)_connection_request
_stream_id_closed)rC   r2   r   rF   r   r   r   rD   0  s    z"HTTP2ConnectionByteStream.__init__r   c                 C  s   | j | jd}zXtdt| j |4 I d H 0 | jj| j | jd2 z3 d H W }|V  q>6 W 5 Q I d H R X W nF tk
r } z(t  |  I d H  W 5 Q R X |W 5 d }~X Y nX d S )NrE   receive_response_body)	r   r   r   rT   r   r   rV   r   rW   )rC   rg   r   rh   r   r   r   	__aiter__8  s     z#HTTP2ConnectionByteStream.__aiter__c              
      sZ   | j sVd| _ d| ji}tdt| j|4 I d H  | jj| jdI d H  W 5 Q I d H R X d S )NTrF   rP   rJ   )r   r   r   rT   r   r   rd   )rC   rg   r   r   r   rW   H  s
    
z HTTP2ConnectionByteStream.aclose)r"   r#   r$   r(   r   r   rD   r{   r   r   r   rW   r   r   r   r   rc   /  s     rc   )%enumloggingr   r   r{   Z	h2.configr1   Zh2.connectionZ	h2.eventsZh2.exceptionsZh2.settings_backends.baser   _exceptionsr   r   r   _modelsr   r   r	   _synchronizationr
   r   r   _tracer   
interfacesr   	getLoggerrT   r   r   IntEnumr    r(   rc   r   r   r   r   <module>   s0   
    