o
    .j                     @  s  d dl m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
 ddlmZ ddlmZ dd	lmZ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 ddlmZmZmZ ddl m!Z!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, ddl-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4m5Z5m6Z6 ddlm7Z7m8Z8 ddl9m:Z: ej;rd dl<Z<d dl=m>Z> g dZ?e@eAZBeCdZDe7e8dZEG dd deZFG dd  d eFZGd(d&d'ZHdS ))    )annotationsN)TracebackType)urljoin   )HTTPHeaderDict)DEFAULT_BLOCKSIZE)AsyncRequestMethods)
_TYPE_BODY_TYPE_BODY_POSITION_TYPE_TIMEOUTProxyConfig)HttpVersionQuicPreemptiveCacheTypeResponsePromise)port_by_scheme)ProtocolResolver)AsyncBaseResolverAsyncManyResolverAsyncResolverDescription)LocationValueErrorMaxRetryErrorProxySchemeUnknownURLSchemeUnknown)SSL_KEYWORDSPoolKeykey_fn_by_scheme)AsyncTrafficPolice)connection_requires_http_tunnel)NOT_FORWARDABLE_HEADERS)Retry)UnavailableTraffic)Urlparse_extension	parse_url   )AsyncHTTPConnectionPoolAsyncHTTPSConnectionPool)AsyncHTTPResponse)Literal)AsyncPoolManagerAsyncProxyManagerproxy_from_url_SelfThttphttpsc                      s  e Zd ZU dZdZded< dZded< 				d]d^ fddZd_ddZd`d!d"Z		dadbd*d+Z
dcd,d-Z		.	ddded2d3Zdfd5d6Zdgd9d:Z	dadhd<d=Zdid?d@ZdjdDdEZddFdkdJdKZej	LdldMdNdmdTdUZej	LdldndXdUZ	LdldodZdUZdpd[d\Z  ZS )qr)   a  
    Allows for arbitrary async requests while transparently keeping track of
    necessary connection pools for you.

    :param num_pools:
        Number of connection pools to cache before discarding the least
        recently used pool.

    :param headers:
        Headers to include with all requests, unless other headers are given
        explicitly.

    :param \**connection_pool_kw:
        Additional parameters are used to create fresh
        :class:`urllib3._async.connectionpool.AsyncConnectionPool` instances.

    Example:

    .. code-block:: python

        import urllib3

        http = urllib3.AsyncPoolManager(num_pools=2)

        resp1 = await http.request("GET", "https://google.com/")
        resp2 = await http.request("GET", "https://google.com/mail")
        resp3 = await http.request("GET", "https://yahoo.com/")

        print(len(http.pools))
        # 2

    Nz
Url | NoneproxyzProxyConfig | Noneproxy_config
   	num_poolsintheaderstyping.Mapping[str, str] | Nonepreemptive_quic_cacheQuicPreemptiveCacheType | NoneresolverfAsyncResolverDescription | list[AsyncResolverDescription] | str | list[str] | AsyncBaseResolver | Noneconnection_pool_kw
typing.AnyreturnNonec           
        s  t  | d|v r |d }t|ts t|}| }||d< || _|| _d|vr,dn|d | _t	|d| j d| _
t| _t | _|| _t|t | _|d u rXttjg}nt|trdt|g}nt|trl|g}g | _t|tsd}|D ]-}t|tr| jt| | jd jtjkrd}qx| j| | jd jtjkrd}qx|s| jtd | jD ],}	d|v rd|	vr|d |	d< d	|v rd	|	vr|d	 |	d	< d
|v rd
|	vr|d
 |	d
< qt|tstdd | jD  | _d S || _d S )NretriesblockFT)concurrencystrict_maxsizez system://default?hosts=localhostca_cert_dataca_cert_dirca_certsc                 S  s   g | ]}|  qS  )new).0rrG   rG   V/home/thesage/.local/lib/python3.10/site-packages/urllib3_future/_async/poolmanager.py
<listcomp>   s    z-AsyncPoolManager.__init__.<locals>.<listcomp>)super__init__
isinstancer   from_intcopyr;   
_num_poolsr@   r   poolspool_classes_by_schemer   _preemptive_quic_cacher   _own_resolverr   r   SYSTEMstrfrom_url
_resolversappendprotocolr   	_resolver)
selfr3   r5   r7   r9   r;   r?   can_resolve_localhostresolver_descriptionrd	__class__rG   rK   rN   \   s~   








zAsyncPoolManager.__init__r^   r,   c                   s   | S NrG   r^   rG   rG   rK   
__aenter__   s   zAsyncPoolManager.__aenter__exc_typetype[BaseException] | Noneexc_valBaseException | Noneexc_tbTracebackType | NoneLiteral[False]c                   s   |   I d H  dS )NF)clear)r^   rg   ri   rk   rG   rG   rK   	__aexit__   s   zAsyncPoolManager.__aexit__schemerX   hostportrequest_contextdict[str, typing.Any] | Noner%   c                 C  s   | j | }|du r| j }|ddu rt|d< dD ]}||d q|dkr3tD ]}||d q*| j|d< | j	 sC| j
 | _| j|d< d|vrQ| j|d< |||fi |S )a  
        Create a new :class:`urllib3._async.connectionpool.AsyncConnectionPool` based on host, port, scheme, and
        any additional pool keyword arguments.

        If ``request_context`` is provided, it is provided as keyword arguments
        to the pool class used. This method is used to actually create the
        connection pools handed out by :meth:`connection_from_url` and
        companion methods. It is intended to be overridden for customization.
        N	blocksize)rp   rq   rr   r.   r7   r9   maxsize)rT   r;   rQ   getr   popr   rU   r]   is_availablerecyclerR   )r^   rp   rq   rr   rs   pool_clskeykwrG   rG   rK   	_new_pool   s"   





zAsyncPoolManager._new_poolc                   s>   | j  I dH  | jr| j r| j I dH  dS dS dS )z
        Empty our store of pools and direct them all to close.

        This will not affect in-flight connections, but they will not be
        reused after completion.
        N)rS   rn   rV   r]   ry   closere   rG   rG   rK   rn     s
   zAsyncPoolManager.clearr.   
str | None
int | Nonepool_kwargsc                   sZ   |st d| |}|pd|d< |st|d  }||d< ||d< | |I dH S )a  
        Get a :class:`urllib3._async.connectionpool.AsyncConnectionPool` based on the host, port, and scheme.

        If ``port`` isn't given, it will be derived from the ``scheme`` using
        ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
        provided, it is merged with the instance's ``connection_pool_kw``
        variable and used to create the new connection pool, if one is
        needed.
        zNo host specified.r.   rp   rr   rq   N)r   _merge_pool_kwargsr   rw   lowerconnection_from_context)r^   rq   rr   rp   r   rs   rG   rG   rK   connection_from_host  s   
z%AsyncPoolManager.connection_from_hostdict[str, typing.Any]c                   sb  d|v r
| d |d  }| j|}|du rt|\}}ddlm} z|||}W n	 ty6   Y n]w ||}| j|}||d< d|vsN|d sYt	|d  |d< |
 }d|v re|d nt }	t|dkrtj|vry|	tj tj|vr|	tj tj|vr|	tj |	|d< |st|||}
| jdur| j|d	< | j|
|d
I dH S )a  
        Get a :class:`urllib3._async.connectionpool.AsyncConnectionPool` based on the request context.

        ``request_context`` must at least contain the ``scheme`` key and its
        value must be a key in ``key_fn_by_scheme`` instance variable.
        strictrp   Nr   load_extensionrr   disabled_svn   r7   rs   )rx   r   r   rw   r"   contrib.webextensions._asyncr   ImportErrorscheme_to_http_schemer   supported_svnsetlenr   h11addh2h3r   rU   connection_from_pool_key)r^   rs   rp   pool_key_constructortarget_schemetarget_implementationr   	extensionr   r   pool_keyrG   rG   rK   r   .  sR   	







z(AsyncPoolManager.connection_from_contextr   r   c              	     s   | j jr
| j   | j j|dd4 I dH /}t|ds9|d }|d }|d }| j||||d}||I dH  n|}W d  I dH  n1 I dH sKw   Y  |jdusWJ | j |j_|S )	a  
        Get a :class:`urllib3._async.connectionpool.AsyncConnectionPool` based on the provided pool key.

        ``pool_key`` should be a namedtuple that only contains immutable
        objects. At a minimum it must have the ``scheme``, ``host``, and
        ``port`` fields.
        T)r@   Nis_idlerp   rq   rr   r   )rS   busyreleaselocate_or_holdhasattrr~   poolparent)r^   r   rs   swapper_or_poolrp   rq   rr   r   rG   rG   rK   r   q  s*   

(
z)AsyncPoolManager.connection_from_pool_keyurlc                   s(   t |}| j|j|j|j|dI dH S )a  
        Similar to :func:`urllib3.async_connection_from_url`.

        If ``pool_kwargs`` is not provided and a new pool needs to be
        constructed, ``self.connection_pool_kw`` is used to initialize
        the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs``
        is provided, it is used instead. Note that if a new pool does not
        need to be created for the request, the provided ``pool_kwargs`` are
        not used.
        rr   rp   r   N)r#   r   rq   rr   rp   )r^   r   r   urG   rG   rK   connection_from_url  s
   z$AsyncPoolManager.connection_from_urloverridec                   s@   | j  } r|dd   D   fdd| D S |S )a  
        Merge a dictionary of override values for self.connection_pool_kw.

        This does not modify self.connection_pool_kw and returns a new dict.
        Any keys in the override dictionary with a value of ``None`` are
        removed from the merged dictionary.
        c                 S  s   i | ]\}}|d ur||qS rd   rG   rI   kvrG   rG   rK   
<dictcomp>  s    z7AsyncPoolManager._merge_pool_kwargs.<locals>.<dictcomp>c                   s*   i | ]\}}| vs | d ur||qS rd   rG   r   r   rG   rK   r     s
    )r;   rQ   updateitems)r^   r   base_pool_kwargsrG   r   rK   r     s   


z#AsyncPoolManager._merge_pool_kwargs
parsed_urlr!   boolc                 C  s"   | j du rdS t| j | j|j S )z
        Indicates if the proxy requires the complete destination URL in the
        request.  Normally this is only needed when not using an HTTP CONNECT
        tunnel.
        NF)r0   r   r1   rp   )r^   r   rG   rG   rK   !_proxy_requires_url_absolute_form  s
   
z2AsyncPoolManager._proxy_requires_url_absolute_formpromiser   ResponsePromise | NoneAsyncHTTPResponse | Nonec                  s  |durt |tstdt| dz0| jj|ptddd4 I dH }|j|dI dH }W d  I dH  n1 I dH s>w   Y  W n
 tyN   Y dS w |dur[|du r[td|du radS d}|rh|}n|j	ryt
|j	d	ry|j	jry|j	j}|du rtd
| j| tt|d}tt|d}|r| rtt|d}ttjtdf |d}ttjtdf |d}	tt|d}
tt|d}ttjtdf |d}tt|d}|d}ttjttjf |d}tt|d}tt|d}tt|d}| }t |ts*J |jdkrCd}d}t|	}	tD ]}|	| q:z|j||||jd}W n t yg   |j!rc|" I dH   | Y S w |" I dH  |#|I dH  t$%d|| | j&|t'||df||	||||d|||
|dd|I dH }| j|r|nddI dH S t|j()d}tt|d}|*||j|rtt|d}ttjtdf |d}ttjtdf |d}	tt|d}
tt|d}ttjtdf |d}tt|d}|d}ttjttjf |d}tt|d}tt|d}z|j||||jd}W n t y\   |j+rX|" I dH   | Y S w |" I dH  |,|I dH  t$%d| | j&||df||	||||d|||
|dd|I dH }| j|r|nddI dH S |d }|dur|j-du r|jd!ksd"|j  krd#k rn |S |d$kr|.|I dH  |S )%z
        Retrieve the first response available in the pools.
        This method should be called after issuing at least one request with ``multiplexed=True``.
        If none available, return None.
        Nz7get_response only support ResponsePromise but received z] instead. This may occur if you expected the remote peer to support multiplexing but did not.FT)r@   not_idle_onlyr   zPInvoked get_response with promise=... that no connections across pools recognizefrom_promisezPInternal: Unable to identify originating ResponsePromise from a LowLevelResponsemethodpm_redirectpm_urlbodyr5   preload_contentdecode_contenttimeoutassert_same_hostpool_timeoutresponse_kwchunkedbody_posr?   /  GETresponse_poolRedirecting %s -> %s)r   r5   r?   r   r   r   release_connr   r   r   r   multiplexedzRetry-Afterz	Retry: %sr   e      i,  CONNECT)/rO   r   	TypeErrortyperS   borrowget_responser    
ValueError_fpr   r   forgettypingcastrX   get_parameterr   get_redirect_locationUnionr	   r   r   MutableMappingAnyr
   r   statusr   discard	incrementr   r   raise_on_redirect
drain_connasync_sleep_for_retrylogdebugurlopenr   r5   rw   is_retryraise_on_statusasync_sleepr   start_extension)r^   r   r   r   r   r   redirectr   r   r5   r   r   r   r   r   r   r   r   r?   redirect_locationshould_be_removed_headernew_promisehas_retry_afterr   rG   rG   rK   r     sx  (
















zAsyncPoolManager.get_responseT.r   r   r   r   r}   r'   c                     d S rd   rG   r^   r   r   r   r   r}   rG   rG   rK   r        	zAsyncPoolManager.urlopenLiteral[True]r   c                  r   rd   rG   r   rG   rG   rK   r     r   #AsyncHTTPResponse | ResponsePromisec                   s*  t |}|jdu rtjdtdd d}|d}|durQt }i }| }	t|	dkrMt	j
|	vr7|t	j
 t	j|	vrB|t	j t	j|	vrM|t	j ||d< | j|j|j|j|dI dH }
|jdur|j d	vrdd
lm} |t|j }| |d< ||d j d|d< d|d< d|vr| j|d< | |r|
j||fi |I dH }n|
j||jfi |I dH }| j  |drt|tr|d| |d| |S d|d< t|t sJ |o|! }|s|S t"||}|j#dkrd}d|d< t$|d |d< t%D ]
}|d &| q|d|j'}t|t(s$t(j)||d}|j*rN|
+|sN|d , }|d D ]}| |j*v rH|-|d q8||d< z|j.||||
d}W n t/yq   |j0rm|1 I dH   | Y S w ||d< ||d< t23d|| |1 I dH  | j||fi |I dH S )a_  
        Same as :meth:`urllib3.AsyncHTTPConnectionPool.urlopen`
        with custom cross-host redirect logic and only sends the request-uri
        portion of the ``url``.

        The given ``url`` parameter must be absolute, such that an appropriate
        :class:`urllib3._async.connectionpool.AsyncConnectionPool` can be chosen for it.
        Na	  URLs without a scheme (ie 'https://') are deprecated and will raise an error in a future version of urllib3. To avoid this DeprecationWarning ensure all URLs start with 'https://' or 'http://'. Read more in this issue: https://github.com/urllib3/urllib3/issues/2920r   )category
stacklevelr   r   r   r   r-   r   Fr   r   r5   r   r   r   r   r   r   r?   )r   r   r   )4r#   rp   warningswarnDeprecationWarningrw   r   r   r   r   r   r   r   r   r   rq   rr   r   r   r   r"   r   urlopen_kwargsr5   r   r   request_urirS   r   rO   r   set_parameterr'   r   r   r   r   r   r   r?   r   rP   remove_headers_on_redirectis_same_hostrQ   rx   r   r   r   r   r   info)r^   r   r   r   r}   r   r   r   r   	supportedconnr   r   r   r   r?   new_headersheaderrG   rG   rK   r     s   











c                 C  s:   d dd | jj D }|r|d7 }d| | j dS )N; c                 s      | ]}t |V  qd S rd   reprrI   prG   rG   rK   	<genexpr>5      z,AsyncPoolManager.__repr__.<locals>.<genexpr> z<AsyncPoolManager >)joinrS   	_registryvaluesr^   
inner_reprrG   rG   rK   __repr__4  s   zAsyncPoolManager.__repr__)r2   NNN)r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   )r^   r,   r=   r,   )rg   rh   ri   rj   rk   rl   r=   rm   rd   )
rp   rX   rq   rX   rr   r4   rs   rt   r=   r%   )r=   r>   Nr.   N
rq   r   rr   r   rp   r   r   rt   r=   r%   )rs   r   r=   r%   )r   r   rs   r   r=   r%   )r   rX   r   rt   r=   r%   )r   rt   r=   r   )r   r!   r=   r   )r   r   r=   r   Tr   rX   r   rX   r   r   r   rm   r}   r<   r=   r'   r   rX   r   rX   r   r   r   r   r}   r<   r=   r   
r   rX   r   rX   r   r   r}   r<   r=   r   r=   rX   )__name__
__module____qualname____doc__r0   __annotations__r1   rN   rf   ro   r~   rn   r   r   r   r   r   r   r   r   overloadr   r  __classcell__rG   rG   rb   rK   r)   7   sL   
 !
k

1

C&

 U
r)   c                      s   e Zd ZdZ							d:d; fddZ			d<d= fd"d#Z	d>d?d&d'Zej	(d@d)d*dAd1d2Z	ej	(d@dBd5d2Z		(d@dC fd7d2Z	dDd8d9Z
  ZS )Er*   a[  
    Behaves just like :class:`PoolManager`, but sends all requests through
    the defined proxy, using the CONNECT method for HTTPS URLs.

    :param proxy_url:
        The URL of the proxy to be used.

    :param proxy_headers:
        A dictionary containing headers that will be sent to the proxy. In case
        of HTTP they are being sent with each request, while in the
        HTTPS/CONNECT case they are sent only once. Could be used for proxy
        authentication.

    :param proxy_ssl_context:
        The proxy SSL context is used to establish the TLS connection to the
        proxy when using HTTPS proxies.

    :param use_forwarding_for_https:
        (Defaults to False) If set to True will forward requests to the HTTPS
        proxy to be made on behalf of the client instead of creating a TLS
        tunnel via the CONNECT method. **Enabling this flag means that request
        and response headers and content will be visible from the HTTPS proxy**
        whereas tunneling keeps request and response headers and content
        private.  IP address, target hostname, SNI, and port are always visible
        to an HTTPS proxy even when this flag is disabled.

    :param proxy_assert_hostname:
        The hostname of the certificate to verify against.

    :param proxy_assert_fingerprint:
        The fingerprint of the certificate to verify against.

    Example:

    .. code-block:: python

        import urllib3

        proxy = urllib3.AsyncProxyManager("https://localhost:3128/")

        resp1 = await proxy.request("GET", "https://google.com/")
        resp2 = await proxy.request("GET", "https://httpbin.org/")

        print(len(proxy.pools))
        # 1

        resp3 = await proxy.request("GET", "https://httpbin.org/")
        resp4 = await proxy.request("GET", "https://twitter.com/")

        print(len(proxy.pools))
        # 3

    r2   NF	proxy_urlrX   r3   r4   r5   r6   proxy_headersproxy_ssl_contextssl.SSLContext | Noneuse_forwarding_for_httpsr   proxy_assert_hostnameNone | str | Literal[False]proxy_assert_fingerprintr   r;   r<   r=   r>   c	                   s   t |tr|j d|j d|j }
n|}
t|
}|jdvr#t|j|js3t|jd}|j	|d}|| _
|p9i | _|| _t||||| _| j
|	d< | j|	d< | j|	d< t j||fi |	 d S )	Nz://:r-   P   )rr   _proxy_proxy_headers_proxy_config)rO   r%   rp   rq   rr   r#   r   r   rw   _replacer0   r'  r(  r   r1   rM   rN   )r^   r&  r3   r5   r'  r(  r*  r+  r-  r;   str_proxy_urlr0   rr   rb   rG   rK   rN   t  s,   






zAsyncProxyManager.__init__r.   rq   rr   r   rp   r   rt   r%   c                   sX   |dv rt  j||||dI d H S | jd usJ t  j| jj| jj| jj|dI d H S )N>   ssewssr/   )r   )rM   r   r0   rq   rr   rp   )r^   rq   rr   rp   r   rb   rG   rK   r     s   z&AsyncProxyManager.connection_from_hostr   typing.Mapping[str, str]c                 C  s0   ddi}t |j}|r||d< |r|| |S )z
        Sets headers needed by proxies: specifically, the Accept and Host
        headers. Only sets headers not provided by the user.
        Acceptz*/*Host)r#   netlocr   )r^   r   r5   headers_r:  rG   rG   rK   _set_proxy_headers  s   

z$AsyncProxyManager._set_proxy_headersT.r   r   r   r   rm   r}   r'   c                  r   rd   rG   r   rG   rG   rK   r     r   zAsyncProxyManager.urlopenr   r   c                  r   rd   rG   r   rG   rG   rK   r     r   r   c                   sZ   t |}t| j| j|js|d| j}| |||d< t j	||fd|i|I dH S )z@Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute.r5   r   N)
r#   r   r0   r1   rp   rw   r5   r<  rM   r   )r^   r   r   r   r}   r   r5   rb   rG   rK   r     s    c                 C  sB   d dd | jj D }|r|d7 }d| j d| | j dS )Nr  c                 s  r	  rd   r
  r  rG   rG   rK   r    r  z-AsyncProxyManager.__repr__.<locals>.<genexpr>r  z<AsyncProxyManager r  )r  rS   r  r  r0   r  rG   rG   rK   r    s   zAsyncProxyManager.__repr__)r2   NNNFNN)r&  rX   r3   r4   r5   r6   r'  r6   r(  r)  r*  r   r+  r,  r-  r   r;   r<   r=   r>   r  r  rd   )r   rX   r5   r6   r=   r7  r  r  r  r  r  )r  r   r!  r"  rN   r   r<  r   r$  r   r  r%  rG   rG   rb   rK   r*   =  s6    9,
r*   r   rX   r}   r<   r=   c                 K  s   t dd| i|S )Nr&  rG   )r*   )r   r}   rG   rG   rK   r+     s   r+   )r   rX   r}   r<   r=   r*   )I
__future__r   loggingr   r   typesr   urllib.parser   _collectionsr   	_constantr   _request_methodsr   _typingr	   r
   r   r   backendr   r   r   connectionpoolr   contrib.resolverr   contrib.resolver._asyncr   r   r   
exceptionsr   r   r   r   poolmanagerr   r   r   util._async.traffic_policer   
util.proxyr   util.requestr   
util.retryr   util.traffic_policer    util.urlr!   r"   r#   r%   r&   r   r'   TYPE_CHECKINGssltyping_extensionsr(   __all__	getLoggerr  r   TypeVarr,   rT   r)   r*   r+   rG   rG   rG   rK   <module>   sV    

       8