From 6a51f6b2f8af5b3e68a9b3f2edfd4c673dadc3b1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Wed, 9 Nov 2011 15:30:33 -0800 Subject: [PATCH] add 'max_retries' configuration --- requests/defaults.py | 1 + requests/models.py | 70 ++++++++++++++------------------------------ 2 files changed, 23 insertions(+), 48 deletions(-) diff --git a/requests/defaults.py b/requests/defaults.py index 90faabee..0d53dfc9 100644 --- a/requests/defaults.py +++ b/requests/defaults.py @@ -38,3 +38,4 @@ defaults['timeout_fallback'] = True # defaults['keep_alive'] = True defaults['pool_connections'] = 10 defaults['pool_maxsize'] = 1 +defaults['max_retries'] = 0 diff --git a/requests/models.py b/requests/models.py index 5ec06a66..275486a8 100644 --- a/requests/models.py +++ b/requests/models.py @@ -14,12 +14,14 @@ from Cookie import SimpleCookie from urlparse import urlparse, urlunparse, urljoin from datetime import datetime + from .auth import dispatch as auth_dispatch from .hooks import dispatch_hook from .structures import CaseInsensitiveDict from .status_codes import codes -from .exceptions import Timeout, URLRequired, TooManyRedirects, HTTPError - +from .packages.urllib3.exceptions import MaxRetryError +from .exceptions import ( + Timeout, URLRequired, TooManyRedirects, HTTPError, ConnectionError) from .utils import ( dict_from_cookiejar, get_unicode_from_response, stream_decode_response_unicode, decode_gzip, stream_decode_gzip) @@ -129,39 +131,6 @@ class Request(object): return '' % (self.method) - # def _get_opener(self): - # """Creates appropriate opener object for urllib2.""" - - # _handlers = [] - - # if self.cookies is not None: - # _handlers.append(urllib2.HTTPCookieProcessor(self.cookies)) - - # if self.proxies: - # _handlers.append(urllib2.ProxyHandler(self.proxies)) - - # _handlers.append(HTTPRedirectHandler) - - # if not _handlers: - # return urllib2.urlopen - - # if self.data or self.files: - # _handlers.extend(get_handlers()) - - # opener = urllib2.build_opener(*_handlers) - - # if self.headers: - # # Allow default headers in the opener to be overloaded - # normal_keys = [k.capitalize() for k in self.headers] - # for key, val in opener.addheaders[:]: - # if key not in normal_keys: - # continue - # # Remove it, we have a value to take its place - # opener.addheaders.remove((key, val)) - - # return opener.open - - def _build_response(self, resp, is_error=False): """Build internal :class:`Response ` object from given response. @@ -219,8 +188,6 @@ class Request(object): ((r.status_code is codes.see_other) or (self.allow_redirects)) ): - # r.raw.close() - if not len(history) < self.config.get('max_redirects'): raise TooManyRedirects() @@ -402,17 +369,24 @@ class Request(object): # Attach Cookie header to request. self.headers['Cookie'] = cookie_header - # Create the connection. - r = conn.urlopen( - method=self.method, - url=url, - body=body, - headers=self.headers, - redirect=False, - assert_same_host=False, - preload_content=False, - decode_content=False - ) + try: + # Create the connection. + r = conn.urlopen( + method=self.method, + url=url, + body=body, + headers=self.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.config.get('max_retries', 0) + ) + except MaxRetryError, e: + if self.config.get('safe_mode', False): + pass + raise ConnectionError(e) + self._build_response(r)