a
    Aù’i"1  ã                   @  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mZ ddlmZ ddlmZmZ ddlmZ ddlmZ eZe d	¡Ze e¡Ze d
¡Ze d¡Zdddœdd„Zdddœdd„Z G dd„ dej!e ƒZ"G dd„ deƒZ#G dd„ deƒZ$dS )é    )ÚannotationsNé   )Ú
_TYPE_BODY)ÚHTTPHeaderDict)ÚHTTPSConnectionÚ_get_default_user_agent)ÚConnectionError)ÚBaseHTTPResponseÚTs   ^[!#$%&'*+\-.^_`|~0-9a-z]+$s*   [\0\x00\x0a\x0d\r\n]|^[ \r\n\t]|[ \r\n\t]$ÚbytesÚbool)ÚnameÚreturnc                 C  s   t t | ¡ƒS )a5  
    "An implementation that validates fields according to the definitions in Sections
    5.1 and 5.5 of [HTTP] only needs an additional check that field names do not
    include uppercase characters." (https://httpwg.org/specs/rfc9113.html#n-field-validity)

    `http.client._is_legal_header_name` does not validate the field name according to the
    HTTP 1.1 spec, so we do that here, in addition to checking for uppercase characters.

    This does not allow for the `:` character in the header name, so should not
    be used to validate pseudo-headers.
    )r   ÚRE_IS_LEGAL_HEADER_NAMEÚmatch)r   © r   úU/home/httpd/docs/test/DocsMgr/lib/python3.9/site-packages/urllib3/http2/connection.pyÚ_is_legal_header_name   s    r   )Úvaluer   c                 C  s   t t | ¡ƒS )aK  
    "A field value MUST NOT contain the zero value (ASCII NUL, 0x00), line feed
    (ASCII LF, 0x0a), or carriage return (ASCII CR, 0x0d) at any position. A field
    value MUST NOT start or end with an ASCII whitespace character (ASCII SP or HTAB,
    0x20 or 0x09)." (https://httpwg.org/specs/rfc9113.html#n-field-validity)
    )r   ÚRE_IS_ILLEGAL_HEADER_VALUEÚsearch)r   r   r   r   Ú_is_illegal_header_value,   s    r   c                   @  sD   e Zd ZdZdZddœdd„Zddœdd	„Zd
ddddœdd„ZdS )Ú_LockedObjectaX  
    A wrapper class that hides a specific object behind a lock.
    The goal here is to provide a simple way to protect access to an object
    that cannot safely be simultaneously accessed from multiple threads. The
    intended use of this class is simple: take hold of it with a context
    manager, which returns the protected object.
    )ÚlockÚ_objr
   )Úobjc                 C  s   t  ¡ | _|| _d S ©N)Ú	threadingÚRLockr   r   )Úselfr   r   r   r   Ú__init__D   s    
z_LockedObject.__init__©r   c                 C  s   | j  ¡  | jS r   )r   Úacquirer   ©r   r   r   r   Ú	__enter__H   s    
z_LockedObject.__enter__ztype[BaseException] | NonezBaseException | Noneztypes.TracebackType | NoneÚNone)Úexc_typeÚexc_valÚexc_tbr   c                 C  s   | j  ¡  d S r   )r   Úrelease)r   r&   r'   r(   r   r   r   Ú__exit__L   s    z_LockedObject.__exit__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r    r$   r*   r   r   r   r   r   6   s
   r   c                      sô   e Zd Zd-dddddœ‡ fdd„Zd	d
œdd„Zdd
œ‡ fdd„Zdddddœdd„Zddddœdd„Zd.dddœdd„Zdddœdd„Z	d/ddddddœdd „Z
d!d
œd"d#„Zd0d$d$d$d%œddd&dd'd'd'ddd(œ	d)d*„Zdd
œ‡ fd+d,„Z‡  ZS )1ÚHTTP2ConnectionNÚstrz
int | Nonez
typing.Anyr%   )ÚhostÚportÚkwargsr   c                   sZ   |   ¡ | _d | _g | _d|v s&d|v r.tdƒ‚tƒ j||fi |¤Ž | jd urVtdƒ‚d S )NÚproxyÚproxy_configz$Proxies aren't supported with HTTP/2z%Tunneling isn't supported with HTTP/2)Ú_new_h2_connÚ_h2_connÚ
_h2_streamÚ_headersÚNotImplementedErrorÚsuperr    Ú_tunnel_host)r   r2   r3   r4   ©Ú	__class__r   r   r    V   s    

zHTTP2Connection.__init__z)_LockedObject[h2.connection.H2Connection]r!   c                 C  s    t jjdd�}tt jj|d�ƒS )NT)Zclient_side)Úconfig)Úh2r@   ZH2Configurationr   Ú
connectionZH2Connection)r   r@   r   r   r   r7   e   s    zHTTP2Connection._new_h2_connc                   sT   t ƒ  ¡  | j�0}| ¡  | ¡  }r2| j |¡ W d   ƒ n1 sF0    Y  d S r   )r<   Úconnectr8   Zinitiate_connectionÚdata_to_sendÚsockÚsendall)r   ÚconnrD   r>   r   r   rC   i   s
    
zHTTP2Connection.connect)ÚmethodÚurlr4   r   c                 K  sê   d|v rt dƒ‚d|v r t dƒ‚|p&d| _|  |¡ d| jv rXd| j› d| jpPd	› �}n| j› d| jphd	› �}| j d
¡ | j d| ¡ f¡ | j d| ¡ f¡ | j d| ¡ f¡ | j�}| 	¡ | _
W d  ƒ n1 sÜ0    Y  dS )z®putrequest
        This deviates from the HTTPConnection method signature since we never need to override
        sending accept-encoding headers or the host header.
        Ú	skip_hostz`skip_host` isn't supportedÚskip_accept_encodingz&`skip_accept_encoding` isn't supportedú/ú:ú[z]:i»  )s   :schemes   httpss   :methods
   :authoritys   :pathN)r;   Ú_request_urlÚ_validate_pathr2   r3   r:   ÚappendÚencoder8   Zget_next_available_stream_idr9   )r   rH   rI   r4   Ú	authorityrG   r   r   r   Ú
putrequestp   s    



zHTTP2Connection.putrequestzstr | bytes)ÚheaderÚvaluesr   c                 G  s†   t |tƒr| ¡ n|}| ¡ }t|ƒs8tdt|ƒ› �ƒ‚|D ]D}t |tƒrR| ¡ n|}t|ƒrptdt|ƒ› �ƒ‚| j ||f¡ q<d S )NzIllegal header name zIllegal header value )	Ú
isinstancer1   rR   Úlowerr   Ú
ValueErrorr   r:   rQ   )r   rU   rV   r   r   r   r   Ú	putheader�   s    zHTTP2Connection.putheader)Úmessage_bodyr   c                 C  sr   | j d u rtdƒ‚| j�@}|j| j | j|d u d� | ¡  }rJ| j |¡ W d   ƒ n1 s^0    Y  g | _d S )NúMust call `putrequest` first.)Ú	stream_idÚheadersÚ
end_stream)r9   r   r8   Úsend_headersr:   rD   rE   rF   )r   r[   rG   rD   r   r   r   Ú
endheadersœ   s    
ý*zHTTP2Connection.endheaders)Údatar   c              	   C  s€  | j du rtdƒ‚| j��P}| ¡  }r4| j |¡ t|dƒrª| | j¡}|sPqŽt	|t
ƒrb| ¡ }|j| j |dd� | ¡  }r>| j |¡ q>| | j ¡ W d  ƒ dS t	|t
ƒr¼| ¡ }zzt	|tƒrô|j| j |dd� | ¡  }rò| j |¡ n@|D ].}|j| j |dd� | ¡  }rø| j |¡ qø| | j ¡ W n$ t�yZ   tdt|ƒ ƒ‚Y n0 W d  ƒ n1 �sr0    Y  dS )z‘Send data to the server.
        `data` can be: `str`, `bytes`, an iterable, or file-like objects
        that support a .read() method.
        Nr\   ÚreadF)r_   Tz6`data` should be str, bytes, iterable, or file. got %r)r9   r   r8   rD   rE   rF   Úhasattrrc   Ú	blocksizerW   r1   rR   Z	send_datar_   r   Ú	TypeErrorÚtype)r   rb   rG   rD   Úchunkr   r   r   Úsendª   sD    





ÿÿzHTTP2Connection.sendÚhttpztyping.Mapping[str, str] | None)r2   r3   r^   Úschemer   c                 C  s   t dƒ‚d S )Nz;HTTP/2 does not support setting up a tunnel through a proxy)r;   )r   r2   r3   r^   rk   r   r   r   Ú
set_tunnel×   s    ÿzHTTP2Connection.set_tunnelÚHTTP2Responsec              	   C  s*  d }t ƒ }| j�æ}d}|sè| j d¡ }rÎ| |¡}|D ]”}t|tjjƒr�t	ƒ }|j
D ]6\}	}
|	dkrtt|
 ¡ ƒ}qV| |	 d¡|
 d¡¡ qVq8t|tjjƒrº||j7 }| |j|j¡ q8t|tjjƒr8d}q8| ¡  }r| j |¡ qW d   ƒ n1 sü0    Y  |d u�sJ ‚t||| jt|ƒd�S )NFiÿÿ  s   :statusÚasciiT)Ústatusr^   Úrequest_urlrb   )Ú	bytearrayr8   rE   ÚrecvZreceive_datarW   rA   ÚeventsZResponseReceivedr   r^   ÚintÚdecodeÚaddZDataReceivedrb   Zacknowledge_received_dataZflow_controlled_lengthr]   ZStreamEndedrD   rF   rm   rO   r   )r   ro   rb   rG   r_   Zreceived_datars   Úeventr^   rU   r   rD   r   r   r   Úgetresponseâ   s@    
ÿ
ÿ,üzHTTP2Connection.getresponseT)Úpreload_contentÚdecode_contentÚenforce_content_lengthz_TYPE_BODY | Noner   )	rH   rI   Úbodyr^   ry   rz   r{   r4   r   c                K  s®   d|v r| j dur | j  | j¡ |  ||¡ |p2i }| ¡ D ],\}	}
|	 ¡ dkr\|
dkr\q<q<|  |	|
¡ q<dt| jƒvr†|  dt	ƒ ¡ |r¢| j
|d� |  |¡ n|  
¡  dS )zSend an HTTP/2 requestÚchunkedNztransfer-encodings
   user-agent)r[   )rE   Ú
settimeoutÚtimeoutrT   ÚitemsrX   rZ   Údictr:   r   ra   ri   )r   rH   rI   r|   r^   ry   rz   r{   r4   ÚkÚvr   r   r   Úrequest  s    
zHTTP2Connection.requestc              	     s‚   | j �H}z$| ¡  | ¡  }r*| j |¡ W n ty>   Y n0 W d   ƒ n1 sT0    Y  |  ¡ | _ d | _g | _t	ƒ  
¡  d S r   )r8   Zclose_connectionrD   rE   rF   Ú	Exceptionr7   r9   r:   r<   Úclose)r   rG   rb   r>   r   r   r†   3  s    $
zHTTP2Connection.close)N)N)NNrj   )NN)r+   r,   r-   r    r7   rC   rT   rZ   ra   ri   rl   rx   r„   r†   Ú__classcell__r   r   r>   r   r0   U   s*    ÿ0   û.  û÷"'r0   c                      s\   e Zd Zddddddddœ‡ fd	d
„Zeddœdd„ƒZddœdd„Zddœdd„Z‡  ZS )rm   Frt   r   r1   r   r   r%   )ro   r^   rp   rb   rz   r   c              	     s*   t ƒ j||ddd ||d� || _d| _d S )Né   zHTTP/2)ro   r^   ÚversionÚversion_stringÚreasonrz   rp   r   )r<   r    Ú_dataÚlength_remaining)r   ro   r^   rp   rb   rz   r>   r   r   r    F  s    ÷zHTTP2Response.__init__r!   c                 C  s   | j S r   )rŒ   r#   r   r   r   rb   \  s    zHTTP2Response.datac                 C  s   d S r   r   r#   r   r   r   Úget_redirect_location`  s    z#HTTP2Response.get_redirect_locationc                 C  s   d S r   r   r#   r   r   r   r†   c  s    zHTTP2Response.close)F)	r+   r,   r-   r    Úpropertyrb   rŽ   r†   r‡   r   r   r>   r   rm   D  s    úrm   )%Ú
__future__r   ÚloggingÚrer   ÚtypesÚtypingZ	h2.configrA   Zh2.connectionZ	h2.eventsZ_base_connectionr   Ú_collectionsr   rB   r   r   Ú
exceptionsr   Úresponser	   Zorig_HTTPSConnectionÚTypeVarr
   Ú	getLoggerr+   ÚlogÚcompiler   r   r   r   ÚGenericr   r0   rm   r   r   r   r   Ú<module>   s0   




 p