U
    —ù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   ú</tmp/pip-unpacked-wheel-z24cd2a5/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                   sV   |   ¡ | _d | _g | _d|ks&d|kr.tdƒ‚tƒ j||f|Ž | jd k	rRtdƒ‚d S )NÚproxyZ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   r6   e   s    zHTTP2Connection._new_h2_connc              	     s@   t ƒ  ¡  | j�&}| ¡  | ¡  }r2| j |¡ W 5 Q R X d S r   )r;   Úconnectr7   Zinitiate_connectionÚdata_to_sendÚsockÚsendall)r   ÚconnrC   r=   r   r   rB   i   s
    
zHTTP2Connection.connect)ÚmethodÚurlr4   r   c              	   K  sÖ   d|krt dƒ‚d|kr t dƒ‚|p&d| _|  |¡ d| jkrXd| j› d| jpPd	› �}n| j› d| jphd	› �}| j d
¡ | j d| ¡ f¡ | j d| ¡ f¡ | j d| ¡ f¡ | j�}| 	¡ | _
W 5 Q R X 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   r9   ÚappendÚencoder7   Zget_next_available_stream_idr8   )r   rG   rH   r4   Ú	authorityrF   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   rQ   Úlowerr   Ú
ValueErrorr   r9   rP   )r   rT   rU   r   r   r   r   Ú	putheader�   s    zHTTP2Connection.putheader)Úmessage_bodyr   c              	   C  s^   | j d krtdƒ‚| j�6}|j| j | j|d kd� | ¡  }rJ| j |¡ W 5 Q R X g | _d S )NúMust call `putrequest` first.)Ú	stream_idÚheadersÚ
end_stream)r8   r   r7   Úsend_headersr9   rC   rD   rE   )r   rZ   rF   rC   r   r   r   Ú
endheadersœ   s    
ýzHTTP2Connection.endheaders)Údatar   c              	   C  sj  | j dkrtdƒ‚| j��F}| ¡  }r4| j |¡ t|dƒr¨| | j¡}|sPqŽt	|t
ƒrb| ¡ }|j| j |dd� | ¡  }r>| j |¡ q>| | j ¡ W 5 Q R £ 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k
�rZ   tdt|ƒ ƒ‚Y nX W 5 Q R X 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)r8   r   r7   rC   rD   rE   Úhasattrrb   Ú	blocksizerV   r1   rQ   Z	send_datar^   r   Ú	TypeErrorÚtype)r   ra   rF   rC   Ú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]   rj   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 5 Q R X |d k	sþt‚t||| jt|ƒd�S )NFiÿÿ  s   :statusÚasciiT)Ústatusr]   Úrequest_urlra   )Ú	bytearrayr7   rD   ÚrecvZreceive_datarV   r@   ÚeventsZResponseReceivedr   r]   ÚintÚdecodeÚaddZDataReceivedra   Zacknowledge_received_dataZflow_controlled_lengthr\   ZStreamEndedrC   rE   ÚAssertionErrorrl   rN   r   )r   rn   ra   rF   r^   Zreceived_datarr   Úeventr]   rT   r   rC   r   r   r   Úgetresponseâ   sD    
 ÿ
 ÿüzHTTP2Connection.getresponseT)Úpreload_contentÚdecode_contentÚenforce_content_lengthz_TYPE_BODY | Noner   )	rG   rH   Úbodyr]   ry   rz   r{   r4   r   c                K  s®   d|kr| j dk	r | j  | j¡ |  ||¡ |p2i }| ¡ D ],\}	}
|	 ¡ dkr\|
dkr\q<q<|  |	|
¡ q<dt| jƒkr†|  dt	ƒ ¡ |r¢| j
|d� |  |¡ n|  
¡  dS )zSend an HTTP/2 requestÚchunkedNztransfer-encodings
   user-agent)rZ   )rD   Ú
settimeoutÚtimeoutrS   ÚitemsrW   rY   Údictr9   r   r`   rh   )r   rG   rH   r|   r]   ry   rz   r{   r4   ÚkÚvr   r   r   Úrequest  s    
zHTTP2Connection.requestc              	     sp   | j �@}z$| ¡  | ¡  }r*| j |¡ W n tk
r@   Y nX W 5 Q R X |  ¡ | _ d | _g | _t	ƒ  
¡  d S r   )r7   Zclose_connectionrC   rD   rE   Ú	Exceptionr6   r8   r9   r;   Úclose)r   rF   ra   r=   r   r   r†   3  s    
zHTTP2Connection.close)N)N)NNri   )NN)r+   r,   r-   r    r6   rB   rS   rY   r`   rh   rk   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 )rl   Frs   r   r1   r   r   r%   )rn   r]   ro   ra   rz   r   c              	     s*   t ƒ j||ddd ||d� || _d| _d S )Né   zHTTP/2)rn   r]   ÚversionÚversion_stringÚreasonrz   ro   r   )r;   r    Ú_dataÚlength_remaining)r   rn   r]   ro   ra   rz   r=   r   r   r    F  s    ÷zHTTP2Response.__init__r!   c                 C  s   | j S r   )rŒ   r#   r   r   r   ra   \  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    Úpropertyra   rŽ   r†   r‡   r   r   r=   r   rl   D  s    úrl   )%Ú
__future__r   ÚloggingÚrer   ÚtypesÚtypingZ	h2.configr@   Zh2.connectionZ	h2.eventsZ_base_connectionr   Ú_collectionsr   rA   r   r   Ú
exceptionsr   Úresponser	   Zorig_HTTPSConnectionÚTypeVarr
   Ú	getLoggerr+   ÚlogÚcompiler   r   r   r   ÚGenericr   r0   rl   r   r   r   r   Ú<module>   s0   




 p