U ��.e�B�@sddlmZddlZddlZddlZddlmZddlmZm Z ddlm Z ddl m Z m Z mZddlmZdd lmZdd lmZdd lmZdd lmZd ddgZe�e�ZdZdZe�de�Z dd�Z!e�"e!e �e�"e!e �d�Z#ee d�Z$Gdd �d e�Z%Gdd�de%�Z&dd�Z'dS)�)�absolute_importN�)�RecentlyUsedContainer)�HTTPConnectionPool�HTTPSConnectionPool)�port_by_scheme)�LocationValueError� MaxRetryError�ProxySchemeUnknown)�six)�urljoin)�RequestMethods)� parse_url)�Retry� PoolManager� ProxyManager�proxy_from_url)Zkey_fileZ cert_fileZ cert_reqsZca_certsZ ssl_versionZ ca_cert_dirZ ssl_contextZ key_password)Z key_schemeZkey_hostZkey_portZ key_timeoutZ key_retriesZ key_strictZ key_blockZkey_source_addressZ key_key_fileZkey_key_passwordZ key_cert_fileZ key_cert_reqsZ key_ca_certsZkey_ssl_versionZkey_ca_cert_dirZkey_ssl_contextZ key_maxsizeZ key_headersZ key__proxyZkey__proxy_headersZkey_socket_optionsZkey__socks_optionsZkey_assert_hostnameZkey_assert_fingerprintZkey_server_hostname�PoolKeycCs�|��}|d��|d<|d��|d<dD],}||kr,||dk r,t||���||<q,|�d�}|dk rxt|�|d<t|���D]}|�|�|d|<q�|j D]}||kr�d||<q�|f|�S)a� Create a pool key out of a request context dictionary. According to RFC 3986, both the scheme and host are case-insensitive. Therefore, this function normalizes both before constructing the pool key for an HTTPS request. If you wish to change this behaviour, provide alternate callables to ``key_fn_by_scheme``. :param key_class: The class to use when constructing the key. This should be a namedtuple with the ``scheme`` and ``host`` keys at a minimum. :type key_class: namedtuple :param request_context: A dictionary-like object that contain the context for a request. :type request_context: dict :return: A namedtuple that can be used as a connection pool key. :rtype: PoolKey �scheme�host)�headers�_proxy_headersZ_socks_optionsNZsocket_optionsZkey_) �copy�lower� frozenset�items�get�tuple�list�keys�pop�_fields)Z key_class�request_context�context�keyZ socket_optsZfield�r%�C/usr/lib/python3.8/site-packages/pip/_vendor/urllib3/poolmanager.py�_default_key_normalizerDs    r'��http�httpsc@sxeZdZdZdZddd�Zdd�Zdd �Zdd d �Zd d �Z ddd�Z dd�Z ddd�Z d dd�Z dd�Zd!dd�ZdS)"ra$ Allows for arbitrary 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.connectionpool.ConnectionPool` instances. Example:: >>> manager = PoolManager(num_pools=2) >>> r = manager.request('GET', 'http://google.com/') >>> r = manager.request('GET', 'http://google.com/mail') >>> r = manager.request('GET', 'http://yahoo.com/') >>> len(manager.pools) 2 N� cKs8t�||�||_t|dd�d�|_t|_t��|_dS)NcSs|��S�N)�close)�pr%r%r&���z&PoolManager.__init__..)Z dispose_func)r �__init__�connection_pool_kwr�pools�pool_classes_by_scheme�key_fn_by_schemer)�self� num_poolsrr2r%r%r&r1�s  zPoolManager.__init__cCs|Sr,r%�r6r%r%r&� __enter__�szPoolManager.__enter__cCs |��dS)NF)�clear)r6�exc_typeZexc_valZexc_tbr%r%r&�__exit__�szPoolManager.__exit__cCs^|j|}|dkr|j��}dD]}|�|d�q |dkrPtD]}|�|d�q>|||f|�S)a� Create a new :class:`ConnectionPool` 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)rr�portr))r4r2rr � SSL_KEYWORDS)r6rrr=r"Zpool_clsr$�kwr%r%r&� _new_pool�s  zPoolManager._new_poolcCs|j��dS)z� Empty our store of pools and direct them all to close. This will not affect in-flight connections, but they will not be re-used after completion. N)r3r:r8r%r%r&r:�szPoolManager.clearr)cCsT|s td��|�|�}|pd|d<|s:t�|d��d�}||d<||d<|�|�S)a� Get a :class:`ConnectionPool` 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. zNo host specified.r)r�Pr=r)r�_merge_pool_kwargsrrr�connection_from_context)r6rr=r� pool_kwargsr"r%r%r&�connection_from_host�s   z PoolManager.connection_from_hostcCs,|d��}|j|}||�}|j||d�S)z� Get a :class:`ConnectionPool` 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. r�r")rr5�connection_from_pool_key)r6r"rZpool_key_constructor�pool_keyr%r%r&rC�s  z#PoolManager.connection_from_contextc Csl|jj�Z|j�|�}|r*|W5QR�S|d}|d}|d}|j||||d�}||j|<W5QRX|S)z� Get a :class:`ConnectionPool` 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. rrr=rF)r3�lockrr@)r6rHr"Zpoolrrr=r%r%r&rG�s  z$PoolManager.connection_from_pool_keycCs t|�}|j|j|j|j|d�S)a� Similar to :func:`urllib3.connectionpool.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. )r=rrD)rrErr=r)r6�urlrD�ur%r%r&�connection_from_urls �zPoolManager.connection_from_urlc CsV|j��}|rR|��D]:\}}|dkrHz ||=WqPtk rDYqPXq|||<q|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. N)r2rr�KeyError)r6�overrideZbase_pool_kwargsr$�valuer%r%r&rB!s   zPoolManager._merge_pool_kwargsTc Ks�t|�}|j|j|j|jd�}d|d<d|d<d|krD|j��|d<|jdk rj|jdkrj|j||f|�}n|j||j f|�}|o�|� �}|s�|St ||�}|j dkr�d }|� d �} t| t�s�tj| |d �} | j�r|�|��stt�|d��} | D]"} | ��| jkr�|d�| d�q�z| j||||d �} Wn$tk �rR| j�rJ�|YSX| |d <||d<t�d ||�|j||f|�S)a] Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.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.connectionpool.ConnectionPool` can be chosen for it. )r=rFZassert_same_host�redirectrNr)i/ZGET�retries)rP)�responseZ_poolzRedirecting %s -> %s)rrErr=rrr�proxy�urlopenZ request_uriZget_redirect_locationr Zstatusr� isinstancerZfrom_intZremove_headers_on_redirectZ is_same_hostrr Ziterkeysrr Z incrementr Zraise_on_redirect�log�info) r6�methodrJrPr?rKZconnrRZredirect_locationrQr�headerr%r%r&rT5sF       � zPoolManager.urlopen)r+N)N)Nr)N)N)N)T)�__name__� __module__� __qualname__�__doc__rSr1r9r<r@r:rErCrGrLrBrTr%r%r%r&r�s     csHeZdZdZd�fdd� Zd�fdd� Zdd d �Zd�fd d � Z�ZS)rax 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. Example: >>> proxy = urllib3.ProxyManager('http://localhost:3128/') >>> r1 = proxy.request('GET', 'http://google.com/') >>> r2 = proxy.request('GET', 'http://httpbin.org/') >>> len(proxy.pools) 1 >>> r3 = proxy.request('GET', 'https://httpbin.org/') >>> r4 = proxy.request('GET', 'https://twitter.com/') >>> len(proxy.pools) 3 r+Nc s�t|t�rd|j|j|jf}t|�}|jsFt�|jd�}|j|d�}|jdkrZt |j��||_ |pfi|_ |j |d<|j |d<t t |�j||f|�dS)Nz %s://%s:%irA)r=r(�_proxyr)rUrrrr=rrr�_replacer rS� proxy_headers�superrr1)r6� proxy_urlr7rr`r2rSr=�� __class__r%r&r1�s" �      zProxyManager.__init__r)csD|dkr tt|�j||||d�Stt|�j|jj|jj|jj|d�S)Nr*)rD)rarrErSrr=r)r6rr=rrDrcr%r&rE�s � �z!ProxyManager.connection_from_hostcCs0ddi}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. ZAcceptz*/*ZHost)r�netloc�update)r6rJrZheaders_rer%r%r&�_set_proxy_headers�s  zProxyManager._set_proxy_headersTc sNt|�}|jdkr0|�d|j�}|�||�|d<tt|�j||fd|i|��S)z@Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute.r)rrP)rrrrrgrarrT)r6rXrJrPr?rKrrcr%r&rT�s  zProxyManager.urlopen)r+NN)Nr)N)N)T) rZr[r\r]r1rErgrT� __classcell__r%r%rcr&rts� cKstfd|i|��S)Nrb)r)rJr?r%r%r&r�s)(Z __future__r� collections� functoolsZlogging� _collectionsrZconnectionpoolrrr� exceptionsrr r Zpackagesr Zpackages.six.moves.urllib.parser Zrequestr Zutil.urlrZ util.retryr�__all__Z getLoggerrZrVr>Z _key_fields� namedtuplerr'�partialr5r4rrrr%r%r%r&�s4            6  � ta