U .eB@sddlmZddlZddlZddlZddlmZddlmZm Z ddlm Z ddl m Z m Z mZddlmZdd lmZdd lmZdd lmZdd lmZd ddgZeeZdZdZedeZ ddZ!e"e!e e"e!e dZ#ee dZ$Gdd d eZ%Gddde%Z&ddZ'dS))absolute_importN)RecentlyUsedContainer)HTTPConnectionPoolHTTPSConnectionPool)port_by_scheme)LocationValueError MaxRetryErrorProxySchemeUnknown)six)urljoin)RequestMethods) parse_url)Retry PoolManager ProxyManagerproxy_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_hostnamePoolKeycCs|}|d|d<|d|d<dD],}||kr,||dk r,t||||<q,|d}|dk rxt||d<t|D]}|||d|<q|j D]}||krd||<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 schemehost)headers_proxy_headersZ_socks_optionsNZsocket_optionsZkey_) copylower frozensetitemsgettuplelistkeyspop_fields)Z key_classrequest_contextcontextkeyZ socket_optsZfieldr%C/usr/lib/python3.8/site-packages/pip/_vendor/urllib3/poolmanager.py_default_key_normalizerDs    r'httphttpsc@sxeZdZdZdZdddZddZdd Zdd d Zd d Z dddZ ddZ dddZ d ddZ ddZd!ddZdS)"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|ddd|_t|_t|_dS)NcSs|SN)close)pr%r%r&z&PoolManager.__init__..)Z dispose_func)r __init__connection_pool_kwrpoolspool_classes_by_schemekey_fn_by_schemer)self num_poolsrr2r%r%r&r1s  zPoolManager.__init__cCs|Sr,r%r6r%r%r& __enter__szPoolManager.__enter__cCs |dS)NF)clear)r6exc_typeZexc_valZexc_tbr%r%r&__exit__szPoolManager.__exit__cCs^|j|}|dkr|j}dD]}||dq |dkrPtD]}||dq>|||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)rrportr))r4r2rr SSL_KEYWORDS)r6rrr=r"Zpool_clsr$kwr%r%r& _new_pools  zPoolManager._new_poolcCs|jdS)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|dd}||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)rPr=r)r_merge_pool_kwargsrrrconnection_from_context)r6rr=r pool_kwargsr"r%r%r&connection_from_hosts   z PoolManager.connection_from_hostcCs,|d}|j|}||}|j||dS)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. rr")rr5connection_from_pool_key)r6r"rZpool_key_constructorpool_keyr%r%r&rCs  z#PoolManager.connection_from_contextc Csl|jjZ|j|}|r*|W5QRS|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)r3lockrr@)r6rHr"Zpoolrrr=r%r%r&rGs  z$PoolManager.connection_from_pool_keycCs t|}|j|j|j|j|dS)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)r6urlrDur%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)r2rrKeyError)r6overrideZbase_pool_kwargsr$valuer%r%r&rB!s   zPoolManager._merge_pool_kwargsTc Kst|}|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 dkrd }| d } t| tstj| |d } | jr||stt|d} | D]"} | | jkr|d| dqz| j||||d } Wn$tk rR| jrJ|YSX| |d <||d<td |||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_hostredirectrNr)i/ZGETretries)rP)responseZ_poolzRedirecting %s -> %s)rrErr=rrrproxyurlopenZ request_uriZget_redirect_locationr Zstatusr isinstancerZfrom_intZremove_headers_on_redirectZ is_same_hostrr Ziterkeysrr Z incrementr Zraise_on_redirectloginfo) r6methodrJrPr?rKZconnrRZredirect_locationrQrheaderr%r%r&rT5sF        zPoolManager.urlopen)r+N)N)Nr)N)N)N)T)__name__ __module__ __qualname____doc__rSr1r9r<r@r:rErCrGrLrBrTr%r%r%r&rs     csHeZdZdZdfdd Zdfdd Zdd d Zdfd d ZZS)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 st|trd|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_headerssuperrr1)r6 proxy_urlr7rr`r2rSr= __class__r%r&r1s"       zProxyManager.__init__r)csD|dkr tt|j||||dStt|j|jj|jj|jj|dS)Nr*)rD)rarrErSrr=r)r6rr=rrDrcr%r&rEs  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)rnetlocupdate)r6rJrZheaders_rer%r%r&_set_proxy_headerss  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&rTs  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&rs)(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