summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorMartin Panter <vadmium+py@gmail.com>2016-02-04 06:01:35 (GMT)
committerMartin Panter <vadmium+py@gmail.com>2016-02-04 06:01:35 (GMT)
commita03702252f591e477db0576bea589d21afdfa601 (patch)
tree1aa9b9315fe934df262fa72b04865063f012a8ad /Lib
parent46f7785e28c17f33252a95a57dd3827811291394 (diff)
downloadcpython-a03702252f591e477db0576bea589d21afdfa601.zip
cpython-a03702252f591e477db0576bea589d21afdfa601.tar.gz
cpython-a03702252f591e477db0576bea589d21afdfa601.tar.bz2
Issue #12923: Reset FancyURLopener's redirect counter even on exception
Based on patches by Brian Brazil and Daniel Rocco.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_urllib.py31
-rw-r--r--Lib/urllib/request.py24
2 files changed, 38 insertions, 17 deletions
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index 57eeeaa..e197a3f 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -39,10 +39,7 @@ def urlopen(url, data=None, proxies=None):
if proxies is not None:
opener = urllib.request.FancyURLopener(proxies=proxies)
elif not _urlopener:
- with support.check_warnings(
- ('FancyURLopener style of invoking requests is deprecated.',
- DeprecationWarning)):
- opener = urllib.request.FancyURLopener()
+ opener = FancyURLopener()
_urlopener = opener
else:
opener = _urlopener
@@ -52,6 +49,13 @@ def urlopen(url, data=None, proxies=None):
return opener.open(url, data)
+def FancyURLopener():
+ with support.check_warnings(
+ ('FancyURLopener style of invoking requests is deprecated.',
+ DeprecationWarning)):
+ return urllib.request.FancyURLopener()
+
+
def fakehttp(fakedata):
class FakeSocket(io.BytesIO):
io_refs = 1
@@ -291,11 +295,26 @@ Connection: close
Content-Type: text/html; charset=iso-8859-1
''')
try:
- self.assertRaises(urllib.error.HTTPError, urlopen,
- "http://python.org/")
+ msg = "Redirection to url 'file:"
+ with self.assertRaisesRegex(urllib.error.HTTPError, msg):
+ urlopen("http://python.org/")
finally:
self.unfakehttp()
+ def test_redirect_limit_independent(self):
+ # Ticket #12923: make sure independent requests each use their
+ # own retry limit.
+ for i in range(FancyURLopener().maxtries):
+ self.fakehttp(b'''HTTP/1.1 302 Found
+Location: file://guidocomputer.athome.com:/python/license
+Connection: close
+''')
+ try:
+ self.assertRaises(urllib.error.HTTPError, urlopen,
+ "http://something")
+ finally:
+ self.unfakehttp()
+
def test_empty_socket(self):
# urlopen() raises OSError if the underlying socket does not send any
# data. (#1680230)
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
index a7fd017..4c16518 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -2050,18 +2050,20 @@ class FancyURLopener(URLopener):
def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
"""Error 302 -- relocated (temporarily)."""
self.tries += 1
- if self.maxtries and self.tries >= self.maxtries:
- if hasattr(self, "http_error_500"):
- meth = self.http_error_500
- else:
- meth = self.http_error_default
+ try:
+ if self.maxtries and self.tries >= self.maxtries:
+ if hasattr(self, "http_error_500"):
+ meth = self.http_error_500
+ else:
+ meth = self.http_error_default
+ return meth(url, fp, 500,
+ "Internal Server Error: Redirect Recursion",
+ headers)
+ result = self.redirect_internal(url, fp, errcode, errmsg,
+ headers, data)
+ return result
+ finally:
self.tries = 0
- return meth(url, fp, 500,
- "Internal Server Error: Redirect Recursion", headers)
- result = self.redirect_internal(url, fp, errcode, errmsg, headers,
- data)
- self.tries = 0
- return result
def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
if 'location' in headers: