U
    	f/[                     @   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   )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   W/var/www/html/apigroqsegura/apigroq/lib/python3.8/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                   @   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HTTP2Connection   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HTTP2Connection.__init__r   c           
      C   s  |  |jjs(td|jj d| j | j< | jtjtj	fkr`|  j
d7  _
d | _tj| _nt W 5 Q R X | j | js4z2d|i}tdt|| | jf | W 5 Q R X W n@ tk
r } z"t  |   W 5 Q R X |W 5 d }~X Y nX d| _d| _| jjj}t|| _t|| j D ]}| j  q"W 5 Q R X | j  z| j }g | j|< W n4 tj j!k
r   d| _"|  j
d8  _
t Y nX z||d}tdt|| | j#||d W 5 Q R X td	t|| | j$||d W 5 Q R X td
t||"}| j%||d\}}	||	f|_&W 5 Q R X t'||	t(| ||dd| j)|ddW S  tk
r } zrt 4 d|i}tdt|| | j*|d W 5 Q R X W 5 Q R X t+|tj j,r| j-rt.| 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   close_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_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)   )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%HTTP2Connection._send_connection_init)r   rF   r   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 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%HTTP2Connection._send_request_headersc                 C   sH   t |sdS t|jtjst|jD ]}| ||| q$| || dS )zP
        Iterate over the request body sending it to a given stream ID.
        N)r   re   r+   typingIterableAssertionError_send_stream_data_send_end_stream)rC   r   rF   datar   r   r   r`      s    
z"HTTP2Connection._send_request_body)r   rF   r   r   c                 C   sV   |rR|  ||}tt||}|d| ||d  }}| j|| | | 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!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)r4   rv   rs   )rC   r   rF   r   r   r   r     s    z HTTP2Connection._send_end_streamc                 C   sr   |  ||}t|tjjr qq d}g }|jD ]<\}}|dkrPt|jddd}q,|ds,|	||f q,||fS )zT
        Return the response status code and headers for a given stream ID.
           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!HTTP2Connection._receive_responsec                 c   sX   |  ||}t|tjjrB|j}| j|| | | |j	V  q t|tjj
r qTq 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&HTTP2Connection._receive_response_bodyc                 C   sD   | j |s| || q | 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popre   r1   r   StreamResetr   )rC   r   rF   r   r   r   r   r   B  s    
z%HTTP2Connection._receive_stream_eventc                 C   s  | j  | jdk	rH| jj}|r>|r>||kr>|  jd8  _t t| j|dks\| j|s| |}|D ]}t	|t
jjrtdt|}| | ||_W 5 Q R X qjt	|t
jjt
jjt
jjt
jjfr|j| jkr| j|j | qjt	|t
jjrj|| _qjW 5 Q R X | | 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HTTP2Connection._receive_events)r   r   c                 C   s   |j tjjj}|r~t|j| jj	j
}|r~|| jkr~|| jkrZ| j  |  jd7  _q6|| jk r~| j  |  jd8  _qZd 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    



z/HTTP2Connection._receive_remote_settings_change)rF   r   c              	   C   s   | j   | j|= | jb | jr0| js0|   nF| jtjkrv| jsvtj	| _| j
d k	rht }|| j
 | _| jrv|   W 5 Q 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 HTTP2Connection._response_closedr   c                 C   s    | j   tj| _| j  d S r   )r4   Zclose_connectionr    r'   r5   r/   rW   rC   r   r   r   rW     s    
zHTTP2Connection.closec              
   C   s   |j di }|dd }| jd k	r*| jz$| j| j|}|dkrLt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#HTTP2Connection._read_incoming_datac                 C   s   |j di }|dd }| jf | j }| jd k	r<| jz| j|| W n2 tk
r } z|| _d| _	|W 5 d }~X Y nX W 5 Q 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$HTTP2Connection._write_outgoing_datac                 C   sT   | j |}| j j}t||}|dkrP| | | 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   )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'HTTP2Connection._wait_for_outgoing_flow)r*   r   c                 C   s
   || j kS r   )r.   rC   r*   r   r   r   rQ     s    z"HTTP2Connection.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HTTP2Connection.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HTTP2Connection.has_expiredc                 C   s   | j tjkS r   )r5   r    r&   r   r   r   r   is_idle  s    zHTTP2Connection.is_idlec                 C   s   | j tjkS r   )r5   r    r'   r   r   r   r   	is_closed  s    zHTTP2Connection.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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.   r5   r   r7   )rC   
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	tracebackr   c                 C   s   |    d S r   )rW   )rC   r   r   r   r   r   r   __exit__&  s    zHTTP2Connection.__exit__)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   Iteratorr   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}z@tdt| j |& | jj| j | jdD ]
}|V  q6W 5 Q R X W n@ tk
r } z"t  |   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   __iter__8  s     
z"HTTP2ConnectionByteStream.__iter__c              	   C   sF   | j sBd| _ d| ji}tdt| j| | jj| jd W 5 Q R X d S )NTrF   rP   rJ   )r   r   r   rT   r   r   rd   )rC   rg   r   r   r   rW   H  s
    
zHTTP2ConnectionByteStream.close)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   
    