Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: third_party/requests/packages/urllib3/poolmanager.py

Issue 24076010: Add 'requests' library to third_party. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/swarm_client
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # urllib3/poolmanager.py
2 # Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt)
3 #
4 # This module is part of urllib3 and is released under
5 # the MIT License: http://www.opensource.org/licenses/mit-license.php
6
7 import logging
8
9 from ._collections import RecentlyUsedContainer
10 from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool
11 from .connectionpool import connection_from_url, port_by_scheme
12 from .request import RequestMethods
13 from .util import parse_url
14
15
16 __all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url']
17
18
19 pool_classes_by_scheme = {
20 'http': HTTPConnectionPool,
21 'https': HTTPSConnectionPool,
22 }
23
24 log = logging.getLogger(__name__)
25
26 SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs',
27 'ssl_version')
28
29
30 class PoolManager(RequestMethods):
31 """
32 Allows for arbitrary requests while transparently keeping track of
33 necessary connection pools for you.
34
35 :param num_pools:
36 Number of connection pools to cache before discarding the least
37 recently used pool.
38
39 :param headers:
40 Headers to include with all requests, unless other headers are given
41 explicitly.
42
43 :param \**connection_pool_kw:
44 Additional parameters are used to create fresh
45 :class:`urllib3.connectionpool.ConnectionPool` instances.
46
47 Example: ::
48
49 >>> manager = PoolManager(num_pools=2)
50 >>> r = manager.request('GET', 'http://google.com/')
51 >>> r = manager.request('GET', 'http://google.com/mail')
52 >>> r = manager.request('GET', 'http://yahoo.com/')
53 >>> len(manager.pools)
54 2
55
56 """
57
58 def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
59 RequestMethods.__init__(self, headers)
60 self.connection_pool_kw = connection_pool_kw
61 self.pools = RecentlyUsedContainer(num_pools,
62 dispose_func=lambda p: p.close())
63
64 def _new_pool(self, scheme, host, port):
65 """
66 Create a new :class:`ConnectionPool` based on host, port and scheme.
67
68 This method is used to actually create the connection pools handed out
69 by :meth:`connection_from_url` and companion methods. It is intended
70 to be overridden for customization.
71 """
72 pool_cls = pool_classes_by_scheme[scheme]
73 kwargs = self.connection_pool_kw
74 if scheme == 'http':
75 kwargs = self.connection_pool_kw.copy()
76 for kw in SSL_KEYWORDS:
77 kwargs.pop(kw, None)
78
79 return pool_cls(host, port, **kwargs)
80
81 def clear(self):
82 """
83 Empty our store of pools and direct them all to close.
84
85 This will not affect in-flight connections, but they will not be
86 re-used after completion.
87 """
88 self.pools.clear()
89
90 def connection_from_host(self, host, port=None, scheme='http'):
91 """
92 Get a :class:`ConnectionPool` based on the host, port, and scheme.
93
94 If ``port`` isn't given, it will be derived from the ``scheme`` using
95 ``urllib3.connectionpool.port_by_scheme``.
96 """
97 scheme = scheme or 'http'
98 port = port or port_by_scheme.get(scheme, 80)
99
100 pool_key = (scheme, host, port)
101
102 # If the scheme, host, or port doesn't match existing open connections,
103 # open a new ConnectionPool.
104 pool = self.pools.get(pool_key)
105 if pool:
106 return pool
107
108 # Make a fresh ConnectionPool of the desired type
109 pool = self._new_pool(scheme, host, port)
110 self.pools[pool_key] = pool
111 return pool
112
113 def connection_from_url(self, url):
114 """
115 Similar to :func:`urllib3.connectionpool.connection_from_url` but
116 doesn't pass any additional parameters to the
117 :class:`urllib3.connectionpool.ConnectionPool` constructor.
118
119 Additional parameters are taken from the :class:`.PoolManager`
120 constructor.
121 """
122 u = parse_url(url)
123 return self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
124
125 def urlopen(self, method, url, redirect=True, **kw):
126 """
127 Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen`
128 with custom cross-host redirect logic and only sends the request-uri
129 portion of the ``url``.
130
131 The given ``url`` parameter must be absolute, such that an appropriate
132 :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
133 """
134 u = parse_url(url)
135 conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
136
137 kw['assert_same_host'] = False
138 kw['redirect'] = False
139 if 'headers' not in kw:
140 kw['headers'] = self.headers
141
142 response = conn.urlopen(method, u.request_uri, **kw)
143
144 redirect_location = redirect and response.get_redirect_location()
145 if not redirect_location:
146 return response
147
148 if response.status == 303:
149 method = 'GET'
150
151 log.info("Redirecting %s -> %s" % (url, redirect_location))
152 kw['retries'] = kw.get('retries', 3) - 1 # Persist retries countdown
153 kw['redirect'] = redirect
154 return self.urlopen(method, redirect_location, **kw)
155
156
157 class ProxyManager(RequestMethods):
158 """
159 Given a ConnectionPool to a proxy, the ProxyManager's ``urlopen`` method
160 will make requests to any url through the defined proxy. The ProxyManager
161 class will automatically set the 'Host' header if it is not provided.
162 """
163
164 def __init__(self, proxy_pool):
165 self.proxy_pool = proxy_pool
166
167 def _set_proxy_headers(self, url, headers=None):
168 """
169 Sets headers needed by proxies: specifically, the Accept and Host
170 headers. Only sets headers not provided by the user.
171 """
172 headers_ = {'Accept': '*/*'}
173
174 host = parse_url(url).host
175 if host:
176 headers_['Host'] = host
177
178 if headers:
179 headers_.update(headers)
180
181 return headers_
182
183 def urlopen(self, method, url, **kw):
184 "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
185 kw['assert_same_host'] = False
186 kw['headers'] = self._set_proxy_headers(url, headers=kw.get('headers'))
187 return self.proxy_pool.urlopen(method, url, **kw)
188
189
190 def proxy_from_url(url, **pool_kw):
191 proxy_pool = connection_from_url(url, **pool_kw)
192 return ProxyManager(proxy_pool)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698