B Ý�ç[ÕAã@sddlmZddlZddlZddlZddlmZddlmZm Z ddlm Z ddl m Z m Z mZddlmZdd lmZdd lmZdd lmZd d dgZe e¡ZdZdZe de¡Zdd„Ze  ee¡e  ee¡dœZ!ee dœZ"Gdd „d eƒZ#Gdd „d e#ƒZ$dd„Z%dS)é)Úabsolute_importNé)ÚRecentlyUsedContainer)ÚHTTPConnectionPoolÚHTTPSConnectionPool)Úport_by_scheme)ÚLocationValueErrorÚ MaxRetryErrorÚProxySchemeUnknown)Ú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)Z key_schemeZkey_hostZkey_portZ key_timeoutZ key_retriesZ key_strictZ key_blockZkey_source_addressZ key_key_fileZ 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<x4dD],}||kr.||dk r.t|| ¡ƒ||<q.W| d¡}|dk r|t|ƒ|d<x&t| ¡ƒD]}| |¡|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_headersZ_socks_optionsNÚsocket_optionsZkey_) ÚcopyÚlowerÚ frozensetÚitemsÚgetÚtupleÚlistÚkeysÚpopÚ_fields)Z key_classÚrequest_contextÚcontextÚkeyZ socket_optsÚfield©r-úT/Users/kashii/Desktop/Projects/Workshops/worker-safety/lambda/urllib3/poolmanager.pyÚ_default_key_normalizer:s     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.Úœsz&PoolManager.__init__..)Ú dispose_func)r Ú__init__Úconnection_pool_kwrÚpoolsÚpool_classes_by_schemeÚkey_fn_by_schemer)ÚselfÚ num_poolsrr8r-r-r.r7˜s  zPoolManager.__init__cCs|S)Nr-)r<r-r-r.Ú __enter__£szPoolManager.__enter__cCs | ¡dS)NF)Úclear)r<Úexc_typeÚexc_valÚexc_tbr-r-r.Ú__exit__¦szPoolManager.__exit__cCsf|j|}|dkr|j ¡}xdD]}| |d¡q"W|dkrXxtD]}| |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. N)rrÚportr0)r:r8rr'Ú SSL_KEYWORDS)r<rrrDr)Úpool_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)r9r?)r<r-r-r.r?ÆszPoolManager.clearr0cCsT|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.r0réPrDr)rÚ_merge_pool_kwargsrr#r Úconnection_from_context)r<rrDrÚ 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))r r;Úconnection_from_pool_key)r<r)rZpool_key_constructorÚpool_keyr-r-r.rKæs  z#PoolManager.connection_from_contextc Cs`|jj�N|j |¡}|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. rrrD)r)N)r9Úlockr#rH)r<rOr)ÚpoolrrrDr-r-r.rNó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. )rDrrL)r rMrrDr)r<ÚurlrLÚur-r-r.Úconnection_from_url s zPoolManager.connection_from_urlc CsZ|j ¡}|rVxF| ¡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)r8rr"ÚKeyError)r<ÚoverrideZbase_pool_kwargsr+Úvaluer-r-r.rJs   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 �} | jrú| |¡súx| jD]} |d | d¡qâWy| j||||d �} Wn tk �r0| j�r,‚|SX| |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. )rDrFÚassert_same_hostÚredirectrNr0i/ÚGETÚretries)rY)ÚresponseÚ_poolzRedirecting %s -> %s)r rMrrDrrrÚproxyÚurlopenÚ request_uriÚget_redirect_locationr Ústatusr#Ú isinstancerÚfrom_intÚremove_headers_on_redirectÚ is_same_hostr'Ú incrementr Úraise_on_redirectÚlogÚinfo) r<ÚmethodrRrYrGrSÚconnr\Úredirect_locationr[Úheaderr-r-r.r_.s@        zPoolManager.urlopen)r2N)N)Nr0N)N)N)T)Ú__name__Ú __module__Ú __qualname__Ú__doc__r^r7r>rCrHr?rMrKrNrTrJr_r-r-r-r.rzs     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 r2Nc 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:%irI)rD)r0r1Ú_proxyr)rcrrrrDr rr#Ú_replacer r^Ú proxy_headersÚsuperrr7)r<Ú proxy_urlr=rrur8r^rD)Ú __class__r-r.r7…s          zProxyManager.__init__r0csD|dkr tt|ƒj||||d�Stt|ƒj|jj|jj|jj|d�S)Nr1)rL)rvrrMr^rrDr)r<rrDrrL)rxr-r.rMœ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. ÚAcceptz*/*ÚHost)r ÚnetlocÚupdate)r<rRrÚheaders_r{r-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.r0rrY)r rr#rr~rvrr_)r<rkrRrYrGrSr)rxr-r.r_³s  zProxyManager.urlopen)r2NN)Nr0N)N)T) rorprqrrr7rMr~r_Ú __classcell__r-r-)rxr.rjs  cKstfd|i|—ŽS)Nrw)r)rRrGr-r-r.rÁs)&Ú __future__rÚ collectionsÚ functoolsÚloggingÚ _collectionsrÚconnectionpoolrrrÚ exceptionsrr r Zpackages.six.moves.urllib.parser Úrequestr Úutil.urlr Ú util.retryrÚ__all__Ú getLoggerrorirEZ _key_fieldsÚ namedtuplerr/Úpartialr;r:rrrr-r-r-r.Ús2          6 qW