From 9e03ca2bf52c2093560905bbe2c4dfcdede29297 Mon Sep 17 00:00:00 2001 From: Jesse Shapiro Date: Sat, 11 Jun 2016 17:24:14 -0400 Subject: Implementing SessionManager; documenting; testing; moving redirect logic to RequestMethods --- urllib3/request.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) (limited to 'urllib3/request.py') diff --git a/urllib3/request.py b/urllib3/request.py index c0fddff0..4708c059 100644 --- a/urllib3/request.py +++ b/urllib3/request.py @@ -1,10 +1,50 @@ from __future__ import absolute_import +import logging from .filepost import encode_multipart_formdata +from .exceptions import MaxRetryError + +from .packages.six.moves.urllib.request import Request as _Request from .packages.six.moves.urllib.parse import urlencode +from .packages.six.moves.urllib.parse import urljoin +__all__ = ['RequestMethods', 'Request'] -__all__ = ['RequestMethods'] +log = logging.getLogger(__name__) + + +class Request(_Request): + """ + Currently used as a shim to allow us to work with the stdlib cookie + handling, which expects a `urllib.request.Request`-like object. + """ + def __init__(self, *args, **kwargs): + kwargs.pop('method', None) + # Request is an old-style class in Python 2 + _Request.__init__(self, *args, **kwargs) + self._cookies = [] + # If there's an existing Cookie header, let's split it up + # so we can handle it similarly to those we get from a jar. + if self.has_header('Cookie'): + self._cookies = self.get_header('Cookie').split('; ') + + def add_cookies(self, *cookies): + """ + We keep track of individual cookies so that we can keep them from + duplicating, and re-render the Cookie header when we get new ones. + """ + for each in cookies: + if each not in self._cookies: + self._cookies.append(each) + self.add_header('Cookie', '; '.join(self._cookies)) + + def get_all_headers(self): + """ + Returns a complete set of all headers + """ + headers = self.unredirected_hdrs.copy() + headers.update(self.headers) + return headers class RequestMethods(object): @@ -146,3 +186,24 @@ class RequestMethods(object): extra_kw.update(urlopen_kw) return self.urlopen(method, url, **extra_kw) + + def redirect(self, response, method, retries, **kwargs): + """ + Abstracts the redirect process to be used from any :class:`RequestMethods` object + """ + url = kwargs.pop('url', '') + redirect_location = urljoin(url, response.get_redirect_location()) + method = retries.redirect_method(method, response.status) + try: + pool = kwargs.pop('pool', self) + retries = retries.increment(method, url, response=response, _pool=pool) + except MaxRetryError: + if retries.raise_on_redirect: + # Release the connection for this response, since we're not + # returning it to be released manually. + response.release_conn() + raise + return response + + log.info("Redirecting %s -> %s", url, redirect_location) + return self.urlopen(method=method, url=redirect_location, retries=retries, **kwargs) -- cgit v1.2.1 From 3d01b133d82fc8b5cd4c995e1bb4cbfc40334de3 Mon Sep 17 00:00:00 2001 From: Jesse Shapiro Date: Mon, 11 Jul 2016 10:11:49 -0400 Subject: Addressing review comments --- urllib3/request.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'urllib3/request.py') diff --git a/urllib3/request.py b/urllib3/request.py index 4708c059..f1171498 100644 --- a/urllib3/request.py +++ b/urllib3/request.py @@ -19,7 +19,7 @@ class Request(_Request): handling, which expects a `urllib.request.Request`-like object. """ def __init__(self, *args, **kwargs): - kwargs.pop('method', None) + del kwargs['method'] # Request is an old-style class in Python 2 _Request.__init__(self, *args, **kwargs) self._cookies = [] @@ -194,8 +194,8 @@ class RequestMethods(object): url = kwargs.pop('url', '') redirect_location = urljoin(url, response.get_redirect_location()) method = retries.redirect_method(method, response.status) + pool = kwargs.pop('pool', self) try: - pool = kwargs.pop('pool', self) retries = retries.increment(method, url, response=response, _pool=pool) except MaxRetryError: if retries.raise_on_redirect: -- cgit v1.2.1