| OLD | NEW |
| 1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
| 2 | 2 |
| 3 """ | 3 """ |
| 4 requests.adapters | 4 requests.adapters |
| 5 ~~~~~~~~~~~~~~~~~ | 5 ~~~~~~~~~~~~~~~~~ |
| 6 | 6 |
| 7 This module contains the transport adapters that Requests uses to define | 7 This module contains the transport adapters that Requests uses to define |
| 8 and maintain connections. | 8 and maintain connections. |
| 9 """ | 9 """ |
| 10 | 10 |
| 11 import socket | 11 import socket |
| 12 | 12 |
| 13 from .models import Response | 13 from .models import Response |
| 14 from .packages.urllib3.poolmanager import PoolManager, ProxyManager | 14 from .packages.urllib3.poolmanager import PoolManager, proxy_from_url |
| 15 from .packages.urllib3.response import HTTPResponse | 15 from .packages.urllib3.response import HTTPResponse |
| 16 from .packages.urllib3.util import Timeout as TimeoutSauce |
| 16 from .compat import urlparse, basestring, urldefrag, unquote | 17 from .compat import urlparse, basestring, urldefrag, unquote |
| 17 from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers, | 18 from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers, |
| 18 prepend_scheme_if_needed, get_auth_from_url) | 19 except_on_missing_scheme, get_auth_from_url) |
| 19 from .structures import CaseInsensitiveDict | 20 from .structures import CaseInsensitiveDict |
| 20 from .packages.urllib3.exceptions import MaxRetryError | 21 from .packages.urllib3.exceptions import MaxRetryError |
| 21 from .packages.urllib3.exceptions import TimeoutError | 22 from .packages.urllib3.exceptions import TimeoutError |
| 22 from .packages.urllib3.exceptions import SSLError as _SSLError | 23 from .packages.urllib3.exceptions import SSLError as _SSLError |
| 23 from .packages.urllib3.exceptions import HTTPError as _HTTPError | 24 from .packages.urllib3.exceptions import HTTPError as _HTTPError |
| 24 from .cookies import extract_cookies_to_jar | 25 from .cookies import extract_cookies_to_jar |
| 25 from .exceptions import ConnectionError, Timeout, SSLError | 26 from .exceptions import ConnectionError, Timeout, SSLError |
| 26 from .auth import _basic_auth_str | 27 from .auth import _basic_auth_str |
| 27 | 28 |
| 28 DEFAULT_POOLBLOCK = False | 29 DEFAULT_POOLBLOCK = False |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 >>> s.mount('http://', a) | 65 >>> s.mount('http://', a) |
| 65 """ | 66 """ |
| 66 __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', | 67 __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', |
| 67 '_pool_block'] | 68 '_pool_block'] |
| 68 | 69 |
| 69 def __init__(self, pool_connections=DEFAULT_POOLSIZE, | 70 def __init__(self, pool_connections=DEFAULT_POOLSIZE, |
| 70 pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, | 71 pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, |
| 71 pool_block=DEFAULT_POOLBLOCK): | 72 pool_block=DEFAULT_POOLBLOCK): |
| 72 self.max_retries = max_retries | 73 self.max_retries = max_retries |
| 73 self.config = {} | 74 self.config = {} |
| 75 self.proxy_manager = {} |
| 74 | 76 |
| 75 super(HTTPAdapter, self).__init__() | 77 super(HTTPAdapter, self).__init__() |
| 76 | 78 |
| 77 self._pool_connections = pool_connections | 79 self._pool_connections = pool_connections |
| 78 self._pool_maxsize = pool_maxsize | 80 self._pool_maxsize = pool_maxsize |
| 79 self._pool_block = pool_block | 81 self._pool_block = pool_block |
| 80 | 82 |
| 81 self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) | 83 self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) |
| 82 | 84 |
| 83 def __getstate__(self): | 85 def __getstate__(self): |
| (...skipping 27 matching lines...) Expand all Loading... |
| 111 def cert_verify(self, conn, url, verify, cert): | 113 def cert_verify(self, conn, url, verify, cert): |
| 112 """Verify a SSL certificate. This method should not be called from user | 114 """Verify a SSL certificate. This method should not be called from user |
| 113 code, and is only exposed for use when subclassing the | 115 code, and is only exposed for use when subclassing the |
| 114 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. | 116 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
| 115 | 117 |
| 116 :param conn: The urllib3 connection object associated with the cert. | 118 :param conn: The urllib3 connection object associated with the cert. |
| 117 :param url: The requested URL. | 119 :param url: The requested URL. |
| 118 :param verify: Whether we should actually verify the certificate. | 120 :param verify: Whether we should actually verify the certificate. |
| 119 :param cert: The SSL certificate to verify. | 121 :param cert: The SSL certificate to verify. |
| 120 """ | 122 """ |
| 121 if url.startswith('https') and verify: | 123 if url.lower().startswith('https') and verify: |
| 122 | 124 |
| 123 cert_loc = None | 125 cert_loc = None |
| 124 | 126 |
| 125 # Allow self-specified cert location. | 127 # Allow self-specified cert location. |
| 126 if verify is not True: | 128 if verify is not True: |
| 127 cert_loc = verify | 129 cert_loc = verify |
| 128 | 130 |
| 129 if not cert_loc: | 131 if not cert_loc: |
| 130 cert_loc = DEFAULT_CA_BUNDLE_PATH | 132 cert_loc = DEFAULT_CA_BUNDLE_PATH |
| 131 | 133 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 | 179 |
| 178 # Give the Response some context. | 180 # Give the Response some context. |
| 179 response.request = req | 181 response.request = req |
| 180 response.connection = self | 182 response.connection = self |
| 181 | 183 |
| 182 return response | 184 return response |
| 183 | 185 |
| 184 def get_connection(self, url, proxies=None): | 186 def get_connection(self, url, proxies=None): |
| 185 """Returns a urllib3 connection for the given URL. This should not be | 187 """Returns a urllib3 connection for the given URL. This should not be |
| 186 called from user code, and is only exposed for use when subclassing the | 188 called from user code, and is only exposed for use when subclassing the |
| 187 :class:`HTTPAdapter <reqeusts.adapters.HTTPAdapter>`. | 189 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
| 188 | 190 |
| 189 :param url: The URL to connect to. | 191 :param url: The URL to connect to. |
| 190 :param proxies: (optional) A Requests-style dictionary of proxies used o
n this request. | 192 :param proxies: (optional) A Requests-style dictionary of proxies used o
n this request. |
| 191 """ | 193 """ |
| 192 proxies = proxies or {} | 194 proxies = proxies or {} |
| 193 proxy = proxies.get(urlparse(url).scheme) | 195 proxy = proxies.get(urlparse(url.lower()).scheme) |
| 194 | 196 |
| 195 if proxy: | 197 if proxy: |
| 196 proxy = prepend_scheme_if_needed(proxy, urlparse(url).scheme) | 198 except_on_missing_scheme(proxy) |
| 197 conn = ProxyManager(self.poolmanager.connection_from_url(proxy)) | 199 proxy_headers = self.proxy_headers(proxy) |
| 200 |
| 201 if not proxy in self.proxy_manager: |
| 202 self.proxy_manager[proxy] = proxy_from_url( |
| 203 proxy, |
| 204 proxy_headers=proxy_headers) |
| 205 |
| 206 conn = self.proxy_manager[proxy].connection_from_url(url) |
| 198 else: | 207 else: |
| 199 conn = self.poolmanager.connection_from_url(url) | 208 conn = self.poolmanager.connection_from_url(url.lower()) |
| 200 | 209 |
| 201 return conn | 210 return conn |
| 202 | 211 |
| 203 def close(self): | 212 def close(self): |
| 204 """Disposes of any internal state. | 213 """Disposes of any internal state. |
| 205 | 214 |
| 206 Currently, this just closes the PoolManager, which closes pooled | 215 Currently, this just closes the PoolManager, which closes pooled |
| 207 connections. | 216 connections. |
| 208 """ | 217 """ |
| 209 self.poolmanager.clear() | 218 self.poolmanager.clear() |
| 210 | 219 |
| 211 def request_url(self, request, proxies): | 220 def request_url(self, request, proxies): |
| 212 """Obtain the url to use when making the final request. | 221 """Obtain the url to use when making the final request. |
| 213 | 222 |
| 214 If the message is being sent through a proxy, the full URL has to be | 223 If the message is being sent through a proxy, the full URL has to be |
| 215 used. Otherwise, we should only use the path portion of the URL. | 224 used. Otherwise, we should only use the path portion of the URL. |
| 216 | 225 |
| 217 This shoudl not be called from user code, and is only exposed for use | 226 This should not be called from user code, and is only exposed for use |
| 218 when subclassing the | 227 when subclassing the |
| 219 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. | 228 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
| 220 | 229 |
| 221 :param request: The :class:`PreparedRequest <PreparedRequest>` being sen
t. | 230 :param request: The :class:`PreparedRequest <PreparedRequest>` being sen
t. |
| 222 :param proxies: A dictionary of schemes to proxy URLs. | 231 :param proxies: A dictionary of schemes to proxy URLs. |
| 223 """ | 232 """ |
| 224 proxies = proxies or {} | 233 proxies = proxies or {} |
| 225 proxy = proxies.get(urlparse(request.url).scheme) | 234 proxy = proxies.get(urlparse(request.url).scheme) |
| 226 | 235 |
| 227 if proxy: | 236 if proxy: |
| 228 url, _ = urldefrag(request.url) | 237 url, _ = urldefrag(request.url) |
| 229 else: | 238 else: |
| 230 url = request.path_url | 239 url = request.path_url |
| 231 | 240 |
| 232 return url | 241 return url |
| 233 | 242 |
| 234 def add_headers(self, request, **kwargs): | 243 def add_headers(self, request, **kwargs): |
| 235 """Add any headers needed by the connection. Currently this adds a | 244 """Add any headers needed by the connection. As of v2.0 this does |
| 236 Proxy-Authorization header. | 245 nothing by default, but is left for overriding by users that subclass |
| 246 the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
| 237 | 247 |
| 238 This should not be called from user code, and is only exposed for use | 248 This should not be called from user code, and is only exposed for use |
| 239 when subclassing the | 249 when subclassing the |
| 240 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. | 250 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
| 241 | 251 |
| 242 :param request: The :class:`PreparedRequest <PreparedRequest>` to add he
aders to. | 252 :param request: The :class:`PreparedRequest <PreparedRequest>` to add he
aders to. |
| 243 :param kwargs: The keyword arguments from the call to send(). | 253 :param kwargs: The keyword arguments from the call to send(). |
| 244 """ | 254 """ |
| 245 proxies = kwargs.get('proxies', {}) | 255 pass |
| 246 | 256 |
| 247 if proxies is None: | 257 def proxy_headers(self, proxy): |
| 248 proxies = {} | 258 """Returns a dictionary of the headers to add to any request sent |
| 259 through a proxy. This works with urllib3 magic to ensure that they are |
| 260 correctly sent to the proxy, rather than in a tunnelled request if |
| 261 CONNECT is being used. |
| 249 | 262 |
| 250 proxy = proxies.get(urlparse(request.url).scheme) | 263 This should not be called from user code, and is only exposed for use |
| 264 when subclassing the |
| 265 :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. |
| 266 |
| 267 :param proxies: The url of the proxy being used for this request. |
| 268 :param kwargs: Optional additional keyword arguments. |
| 269 """ |
| 270 headers = {} |
| 251 username, password = get_auth_from_url(proxy) | 271 username, password = get_auth_from_url(proxy) |
| 252 | 272 |
| 253 if username and password: | 273 if username and password: |
| 254 # Proxy auth usernames and passwords will be urlencoded, we need | 274 # Proxy auth usernames and passwords will be urlencoded, we need |
| 255 # to decode them. | 275 # to decode them. |
| 256 username = unquote(username) | 276 username = unquote(username) |
| 257 password = unquote(password) | 277 password = unquote(password) |
| 258 request.headers['Proxy-Authorization'] = _basic_auth_str(username, | 278 headers['Proxy-Authorization'] = _basic_auth_str(username, |
| 259 password) | 279 password) |
| 280 |
| 281 return headers |
| 260 | 282 |
| 261 def send(self, request, stream=False, timeout=None, verify=True, cert=None,
proxies=None): | 283 def send(self, request, stream=False, timeout=None, verify=True, cert=None,
proxies=None): |
| 262 """Sends PreparedRequest object. Returns Response object. | 284 """Sends PreparedRequest object. Returns Response object. |
| 263 | 285 |
| 264 :param request: The :class:`PreparedRequest <PreparedRequest>` being sen
t. | 286 :param request: The :class:`PreparedRequest <PreparedRequest>` being sen
t. |
| 265 :param stream: (optional) Whether to stream the request content. | 287 :param stream: (optional) Whether to stream the request content. |
| 266 :param timeout: (optional) The timeout on the request. | 288 :param timeout: (optional) The timeout on the request. |
| 267 :param verify: (optional) Whether to verify SSL certificates. | 289 :param verify: (optional) Whether to verify SSL certificates. |
| 268 :param vert: (optional) Any user-provided SSL certificate to be trusted. | 290 :param vert: (optional) Any user-provided SSL certificate to be trusted. |
| 269 :param proxies: (optional) The proxies dictionary to apply to the reques
t. | 291 :param proxies: (optional) The proxies dictionary to apply to the reques
t. |
| 270 """ | 292 """ |
| 271 | 293 |
| 272 conn = self.get_connection(request.url, proxies) | 294 conn = self.get_connection(request.url, proxies) |
| 273 | 295 |
| 274 self.cert_verify(conn, request.url, verify, cert) | 296 self.cert_verify(conn, request.url, verify, cert) |
| 275 url = self.request_url(request, proxies) | 297 url = self.request_url(request, proxies) |
| 276 self.add_headers(request, proxies=proxies) | 298 self.add_headers(request) |
| 277 | 299 |
| 278 chunked = not (request.body is None or 'Content-Length' in request.heade
rs) | 300 chunked = not (request.body is None or 'Content-Length' in request.heade
rs) |
| 279 | 301 |
| 302 if stream: |
| 303 timeout = TimeoutSauce(connect=timeout) |
| 304 else: |
| 305 timeout = TimeoutSauce(connect=timeout, read=timeout) |
| 306 |
| 280 try: | 307 try: |
| 281 if not chunked: | 308 if not chunked: |
| 282 resp = conn.urlopen( | 309 resp = conn.urlopen( |
| 283 method=request.method, | 310 method=request.method, |
| 284 url=url, | 311 url=url, |
| 285 body=request.body, | 312 body=request.body, |
| 286 headers=request.headers, | 313 headers=request.headers, |
| 287 redirect=False, | 314 redirect=False, |
| 288 assert_same_host=False, | 315 assert_same_host=False, |
| 289 preload_content=False, | 316 preload_content=False, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 raise Timeout(e) | 360 raise Timeout(e) |
| 334 else: | 361 else: |
| 335 raise | 362 raise |
| 336 | 363 |
| 337 r = self.build_response(request, resp) | 364 r = self.build_response(request, resp) |
| 338 | 365 |
| 339 if not stream: | 366 if not stream: |
| 340 r.content | 367 r.content |
| 341 | 368 |
| 342 return r | 369 return r |
| OLD | NEW |