VY?@sddlmZddlZddlZddlZddlmZddlmZm Z ddlm Z ddl m Z m Z mZddlmZdd lmZdd lmZdd lmZd d dgZejeZd5Zd6Zejd-eZd.d/Zd0ej eed1ej eeiZ!d0ed1e iZ"Gd2d d eZ#Gd3d d e#Z$d4dZ%dS)7)absolute_importN)RecentlyUsedContainer)HTTPConnectionPoolHTTPSConnectionPool)port_by_scheme)LocationValueError MaxRetryErrorProxySchemeUnknown)urljoin)RequestMethods) parse_url)Retry PoolManager ProxyManagerproxy_from_urlkey_file cert_file cert_reqsca_certs ssl_version ca_cert_dir ssl_context key_schemekey_hostkey_port key_timeout key_retries key_strict key_blockkey_source_address key_key_file key_cert_file key_cert_reqs key_ca_certskey_ssl_versionkey_ca_cert_dirkey_ssl_context key_maxsize key_headers key__proxykey__proxy_headerskey_socket_optionskey__socks_optionskey_assert_hostnamekey_assert_fingerprintPoolKeycCs|j}|dj|d<|dj|d>> 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 cKsPtj||||_t|ddd|_t|_tj|_dS)N dispose_funccSs |jS)N)close)prFrFrGsz&PoolManager.__init__..)r __init__connection_pool_kwrpoolspool_classes_by_schemekey_fn_by_schemer7)self num_poolsr3rQrFrFrGrPs    zPoolManager.__init__cCs|S)NrF)rUrFrFrG __enter__szPoolManager.__enter__cCs|jdS)NF)clear)rUexc_typeexc_valexc_tbrFrFrG__exit__s zPoolManager.__exit__cCs|j|}|dkr(|jj}xdD]}|j|dq/W|dkrvxtD]}|j|dq\W||||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. Nr1r2portrI)zschemezhostzport)rSrQr7r? SSL_KEYWORDS)rUr1r2r]rBpool_clsrDkwrFrFrG _new_pools     zPoolManager._new_poolcCs|jjdS)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)rRrX)rUrFrFrGrXszPoolManager.clearrIcCst|std|j|}|p*d|d<|sStj|djd}||d<||d<|j|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.rIr1Pr]r2)r_merge_pool_kwargsrr;r8connection_from_context)rUr2r]r1 pool_kwargsrBrFrFrGconnection_from_hosts    z PoolManager.connection_from_hostcCs<|dj}|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. r1rB)r8rTconnection_from_pool_key)rUrBr1pool_key_constructorpool_keyrFrFrGrds  z#PoolManager.connection_from_contextc Csz|jjg|jj|}|r)|S|d}|d}|d}|j|||d|}||j| %s)r rfr2r]r1r3proxyurlopen request_uriget_redirect_locationr statusr; isinstancerfrom_int incrementr raise_on_redirectloginfo) rUmethodrlrsr`rmconnrvredirect_locationrurFrFrGry-s8 $    "     zPoolManager.urlopen)__name__ __module__ __qualname____doc__rxrPrWr\rarXrfrdrgrnrcryrFrFrFrGrys      cspeZdZdZdddfddZdddfddZdd d Zd fd d ZS)raw 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 contaning 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 rKNc st|tr+d|j|j|jf}t|}|jsgtj|jd}|jd|}|jdkrt |j||_ |pi|_ |j |d<|j |d|j||S)z Sets headers needed by proxies: specifically, the Accept and Host headers. Only sets headers not provided by the user. Acceptz*/*Host)r netlocupdate)rUrlr3headers_rrFrFrG_set_proxy_headerss   zProxyManager._set_proxy_headersTc sht|}|jdkrF|jd|j}|j|||ds^    6 W