3 »nNjGCã@s ddlmZddlZddlZddlZddlmZmZddlm Z m Z ddlm Z ddl m Z mZmZddlmZdd lmZdd lmZdd lmZdd lmZd ddgZejeƒZd6Zd7Zej d/eƒZ!d0d1„Z"ej#e"e!ƒej#e"e!ƒd2œZ$e e d2œZ%Gd3d „d eƒZ&Gd4d„de&ƒZ'd5d„Z(dS)8é)Úabsolute_importNé)ÚHTTPHeaderDictÚRecentlyUsedContainer)ÚHTTPConnectionPoolÚHTTPSConnectionPool)Úport_by_scheme)ÚLocationValueErrorÚ MaxRetryErrorÚProxySchemeUnknown)Úsix)Úurljoin)ÚRequestMethods)Ú parse_url)ÚRetryÚ PoolManagerÚ ProxyManagerÚproxy_from_urlÚkey_fileÚ cert_fileÚ cert_reqsÚca_certsÚ ssl_versionÚ ca_cert_dirÚ ssl_contextÚ key_schemeÚkey_hostÚkey_portÚ key_timeoutÚ key_retriesÚ key_strictÚ key_blockÚkey_source_addressÚ key_key_fileÚ key_cert_fileÚ key_cert_reqsÚ key_ca_certsÚkey_ssl_versionÚkey_ca_cert_dirÚkey_ssl_contextÚ key_maxsizeÚ key_headersÚ key__proxyÚkey__proxy_headersÚkey_socket_optionsÚkey__socks_optionsÚkey_assert_hostnameÚkey_assert_fingerprintÚkey_server_hostnameÚPoolKeycCsÎ|jƒ}|djƒ|d<|djƒ|d<x4d D],}||kr.||dk r.t||jƒƒ||<q.W|jdƒ}|dk r|t|ƒ|d<x&t|jƒƒD]}|j|ƒ|d|<qŠWx|j D]}||kr¬d||<q¬W|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_headersÚ_socks_optionsNZsocket_optionsZkey_)r6r7r8) ÚcopyÚlowerÚ frozensetÚitemsÚgetÚtupleÚlistÚkeysÚpopÚ_fields)Z key_classÚrequest_contextÚcontextÚkeyZ socket_optsZfield©rFú!/usr/lib/python3.6/poolmanager.pyÚ_default_key_normalizer;s     rH)Ú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é cKs8tj||ƒ||_t|dd„d�|_t|_tjƒ|_dS)NcSs|jƒS)N)Úclose)ÚprFrFrGÚ�sz&PoolManager.__init__..)Z dispose_func)rÚ__init__Úconnection_pool_kwrÚpoolsÚpool_classes_by_schemeÚkey_fn_by_schemer9)ÚselfÚ num_poolsr6rPrFrFrGrO™s  zPoolManager.__init__cCs|S)NrF)rTrFrFrGÚ __enter__¤szPoolManager.__enter__cCs |jƒdS)NF)Úclear)rTÚexc_typeZexc_valZexc_tbrFrFrGÚ__exit__§szPoolManager.__exit__cCsf|j|}|dkr|jjƒ}xdD]}|j|dƒq"W|dkrXxtD]}|j|dƒqDW|||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. Nr4r5ÚportrI)r4r5rZ)rRrPr9rAÚ SSL_KEYWORDS)rTr4r5rZrCZpool_clsrEÚkwrFrFrGÚ _new_pool¬s    zPoolManager._new_poolcCs|jjƒ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)rQrW)rTrFrFrGrWÇszPoolManager.clearrIcCsT|s tdƒ‚|j|ƒ}|pd|d<|s:tj|djƒdƒ}||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.rIr4éPrZr5)r Ú_merge_pool_kwargsrr=r:Úconnection_from_context)rTr5rZr4Ú pool_kwargsrCrFrFrGÚconnection_from_hostÐs   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. r4)rC)r:rSÚconnection_from_pool_key)rTrCr4Zpool_key_constructorÚpool_keyrFrFrGr`çs  z#PoolManager.connection_from_contextc Cs`|jj�N|jj|ƒ}|r|S|d}|d}|d}|j||||d�}||j|<WdQRX|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. r4r5rZ)rCN)rQÚlockr=r])rTrdrCZpoolr4r5rZrFrFrGrcô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. )rZr4ra)rrbr5rZr4)rTÚurlraÚurFrFrGÚconnection_from_url s zPoolManager.connection_from_urlc CsZ|jjƒ}|rVxF|jƒD]:\}}|dkrJy ||=WqRtk rFYqRXq|||<qW|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)rPr9r<ÚKeyError)rTÚoverrideZbase_pool_kwargsrEÚvaluerFrFrGr_s   zPoolManager._merge_pool_kwargsTc Ks¢t|ƒ}|j|j|j|jd�}d|d<d|d<d|krD|jjƒ|d<|jdk rj|jdkrj|j||f|Ž}n|j||j f|Ž}|o†|j ƒ}|s�|St ||ƒ}|j dkrÄd }d|d <t |dƒjƒ|d<|jd ƒ} t| tƒsætj| |d �} | joö|j|ƒ �r %s)rrbr5rZr4r6r9ÚproxyÚurlopenZ request_uriZget_redirect_locationr ZstatusrZ_prepare_for_method_changer=Ú isinstancerZfrom_intZremove_headers_on_redirectZ is_same_hostr?r Ziterkeysr:rAZ incrementr Zraise_on_redirectÚlogÚinfo) rTÚmethodrfrlr\rgZconnrnZredirect_locationrmr6ÚheaderrFrFrGrp/sH       zPoolManager.urlopen)rKN)N)NrIN)N)N)T)Ú__name__Ú __module__Ú __qualname__Ú__doc__rorOrVrYr]rWrbr`rcrhr_rprFrFrFrGr{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 rKNc s˜t|tƒrd|j|j|jf}t|ƒ}|jsFtj|jdƒ}|j|d�}|jdkrZt |jƒ‚||_ |pfi|_ |j |d<|j |d<t t |ƒj||f|ŽdS) Nz %s://%s:%ir^)rZrIrJÚ_proxyr7)rIrJ)rqrr4r5rZrrr=Ú_replacer roÚ proxy_headersÚsuperrrO)rTÚ proxy_urlrUr6r|rProrZ)Ú __class__rFrGrO‹s          zProxyManager.__init__rIcsD|dkr tt|ƒj||||d�Stt|ƒj|jj|jj|jj|d�S)NrJ)ra)r}rrbror5rZr4)rTr5rZr4ra)rrFrGrb¢s   z!ProxyManager.connection_from_hostcCs0ddi}t|ƒj}|r||d<|r,|j|ƒ|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)rTrfr6Zheaders_r€rFrFrGÚ_set_proxy_headersªs  zProxyManager._set_proxy_headersTc sNt|ƒ}|jdkr0|jd|jƒ}|j||ƒ|d<tt|ƒj||fd|i|—ŽS)z@Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute.rIr6rl)rr4r=r6r‚r}rrp)rTrtrfrlr\rgr6)rrFrGrp¹s  zProxyManager.urlopen)rKNN)NrIN)N)T) rvrwrxryrOrbr‚rpÚ __classcell__rFrF)rrGrps  cKstfd|i|—ŽS)Nr~)r)rfr\rFrFrGrÇs)rrrrrrr)rrrrrr r!r"r#r$r%r&r'r(r)r*r+r,r-r.r/r0r1r2))Z __future__rÚ collectionsÚ functoolsZloggingÚ _collectionsrrZconnectionpoolrrrÚ exceptionsr r r Zpackagesr Zpackages.six.moves.urllib.parser ZrequestrZutil.urlrZ util.retryrÚ__all__Z getLoggerrvrrr[Z _key_fieldsÚ namedtupler3rHÚpartialrSrRrrrrFrFrFrGÚsd          6 vW