a
    Of1[                     @   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   M/var/www/ai-form-bot/venv/lib/python3.9/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F | jtjtj	fv r`|  j
d7  _
d | _tj| _nt W d    n1 sz0    Y  | j | jszzJd|i}tdt||  | jf i | W d    n1 s0    Y  W nZ ty8 } z@t  |   W d    n1 s0    Y  |W Y d }~n
d }~0 0 d| _d| _| jjj}t|| _t|| j D ]}| j  qhW d    n1 s0    Y  | j  z| j }g | j|< W n2 tj j!y   d| _"|  j
d8  _
t Y n0 z||d}tdt|| | j#||d W d    n1 s00    Y  td	t|| | j$||d W d    n1 sn0    Y  td
t||,}| j%||d\}}	||	f|_&W d    n1 s0    Y  t'||	t(| ||dd| j)|ddW S  ty } zt T d|i}tdt|| | j*|d W d    n1 s<0    Y  W d    n1 s\0    Y  t+|tj j,r| j-rt.| j-t/||W Y d }~n
d }~0 0 d S )NzAttempted to send request to z on connection to r   r   Zsend_connection_initTr   	stream_idZsend_request_headersZsend_request_bodyZreceive_response_headersrF   s   HTTP/2)http_versionZ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   tracerI   r   r   r   r   handle_requestU   s    
$2(
.


..
*
L

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   rU   ZENABLE_CONNECT_PROTOCOLZinitiate_connectionincrement_flow_control_window_write_outgoing_data)rC   r   r   r   r   rQ      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>       z9HTTP2Connection._send_request_headers.<locals>.<listcomp>r   s   :methods
   :authoritys   :schemes   :pathc                 S   s(   g | ] \}}|  d vr|  |fqS ))rp   r   r   r   r   r   r   rq      s
   )
end_streamrj   rG   N)
r   r   methodrN   schemetargetr4   send_headersrn   ro   )rC   r   rF   rs   	authorityr   r   r   r   r[      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   ra   r+   typingIterable_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   Z	send_dataro   )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   rs   ro   )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_eventra   r1   eventsResponseReceivedr   intdecode
startswithappend)rC   r   rF   eventstatus_coder   r   r   r   r   r   r]     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   ra   r1   r   DataReceivedZflow_controlled_lengthr4   Zacknowledge_received_dataro   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popra   r1   r   StreamResetr   )rC   r   rF   r   r   r   r   r   B  s    
z%HTTP2Connection._receive_stream_eventc              
   C   sH  | j   | jdurJ| jj}|r@|r@||kr@|  jd8  _t t| j|du s`| j|s| |}|D ]}t	|t
jjrtdt| }| | ||_W d   n1 s0    Y  qnt	|t
jjt
jjt
jjt
jjfr|j| jv r| j|j | qnt	|t
jjrn|| _qnW d   n1 s00    Y  | | 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_datara   r1   r   ZRemoteSettingsChangedr   rP   _receive_remote_settings_changer^   r   r   r   r   rF   r   ZConnectionTerminatedro   )rC   r   rF   r   r   r   rf   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   rk   rl   rm   r   	new_valuer4   rU   rV   rT   rW   releaserY   )rC   r   rV   Znew_max_streamsr   r   r   r     s    



z/HTTP2Connection._receive_remote_settings_change)rF   r   c                 C   s   | j   | j|= | jl | jr0| js0|   nF| jtjkrv| jsvtj	| _| j
d urht }|| j
 | _| jrv|   W d    n1 s0    Y  d S N)rW   r   r?   r9   r@   rS   r5   r    r%   r&   r0   time	monotonicr6   r=   )rC   rF   nowr   r   r   r`     s    


z HTTP2Connection._response_closedr   c                 C   s    | j   tj| _| j  d S r   )r4   Zclose_connectionr    r'   r5   r/   rS   rC   r   r   r   rS     s    
zHTTP2Connection.closec              
   C   s   |j di }|dd }| jd ur*| jz$| j| j|}|dkrLtdW n4 ty } z|| _d| _|W Y d }~n
d }~0 0 | j	
|}|S )Ntimeoutreadrr   zServer disconnectedT)rK   r   rA   r/   r   READ_NUM_BYTESr   	Exceptionr>   r4   Zreceive_data)rC   r   timeoutsr   r}   rd   r   r   r   r   r     s    
	z#HTTP2Connection._read_incoming_datac                 C   s   |j di }|dd }| jr | j }| jd ur<| jz| j|| W n4 ty } z|| _d| _	|W Y d }~n
d }~0 0 W d    n1 s0    Y  d S )Nr   writeT)
rK   r   r;   r4   data_to_sendrB   r/   r   r   r>   )rC   r   r   r   r   rd   r   r   r   ro     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_sizeZ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   rM     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   ZConnectionStater   r   r   r   is_available  s    zHTTP2Connection.is_availablec                 C   s   t  }| jd u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   )rS   )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   ry   OptionalfloatrD   r   r	   rg   rQ   r   r[   r\   bytesr{   r|   TupleListr]   Iteratorr   Unionr   r   r   r   r   r   Eventr   r`   rS   r   ro   r~   boolrM   r   r   r   r   r   r   r   r   TyperR   typesTracebackTyper   r   r   r   r   r(   (   sr    )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 )
r_   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}zTtdt| j |0 | jj| j | jdD ]
}|V  q6W d    n1 sV0    Y  W nV ty } z>t  |   W d    n1 s0    Y  |W Y d }~n
d }~0 0 d S )NrE   Zreceive_response_body)	r   r   r   rP   r   r   rR   r   rS   )rC   rc   r   rd   r   r   r   __iter__8  s    
*&z"HTTP2ConnectionByteStream.__iter__c                 C   sZ   | j sVd| _ d| ji}tdt| j|  | jj| jd W d    n1 sL0    Y  d S )NTrF   rL   rG   )r   r   r   rP   r   r   r`   )rC   rc   r   r   r   rS   H  s
    
zHTTP2ConnectionByteStream.close)r"   r#   r$   r(   r   r   rD   ry   r   r   r   rS   r   r   r   r   r_   /  s
   r_   )%enumloggingr   r   ry   Z	h2.configr1   Zh2.connectionZ	h2.eventsZh2.exceptionsZh2.settingsZ_backends.baser   _exceptionsr   r   r   Z_modelsr   r   r	   Z_synchronizationr
   r   r   Z_tracer   Z
interfacesr   	getLoggerrP   r   r   IntEnumr    r(   r_   r   r   r   r   <module>   s0   
    