changeset: 100161:a8aa7944c5a8 branch: 2.7 parent: 100154:c8e43e55f2ce user: Martin Panter date: Thu Feb 04 06:01:35 2016 +0000 files: Lib/test/test_urllib.py Lib/urllib.py Misc/ACKS Misc/NEWS description: Issue #12923: Reset FancyURLopener's redirect counter even on exception Based on patches by Brian Brazil and Daniel Rocco. diff -r c8e43e55f2ce -r a8aa7944c5a8 Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py Wed Feb 03 22:05:46 2016 -0600 +++ b/Lib/test/test_urllib.py Thu Feb 04 06:01:35 2016 +0000 @@ -209,10 +209,26 @@ Content-Type: text/html; charset=iso-8859-1 """) try: - self.assertRaises(IOError, urllib.urlopen, "http://python.org/") + msg = "Redirection to url 'file:" + with self.assertRaisesRegexp(IOError, msg): + urllib.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(urllib.FancyURLopener().maxtries): + self.fakehttp(b'''HTTP/1.1 302 Found +Location: file://guidocomputer.athome.com:/python/license +Connection: close +''') + try: + self.assertRaises(IOError, urllib.urlopen, + "http://something") + finally: + self.unfakehttp() + def test_empty_socket(self): # urlopen() raises IOError if the underlying socket does not send any # data. (#1680230) diff -r c8e43e55f2ce -r a8aa7944c5a8 Lib/urllib.py --- a/Lib/urllib.py Wed Feb 03 22:05:46 2016 -0600 +++ b/Lib/urllib.py Thu Feb 04 06:01:35 2016 +0000 @@ -629,18 +629,20 @@ 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: diff -r c8e43e55f2ce -r a8aa7944c5a8 Misc/ACKS --- a/Misc/ACKS Wed Feb 03 22:05:46 2016 -0600 +++ b/Misc/ACKS Thu Feb 04 06:01:35 2016 +0000 @@ -1154,6 +1154,7 @@ Mark Roberts Andy Robinson Jim Robinson +Daniel Rocco Mark Roddy Kevin Rodgers Sean Rodman diff -r c8e43e55f2ce -r a8aa7944c5a8 Misc/NEWS --- a/Misc/NEWS Wed Feb 03 22:05:46 2016 -0600 +++ b/Misc/NEWS Thu Feb 04 06:01:35 2016 +0000 @@ -48,6 +48,9 @@ Library ------- +- Issue #12923: Reset FancyURLopener's redirect counter even if there is an + exception. Based on patches by Brian Brazil and Daniel Rocco. + - Issue #25945: Fixed a crash when unpickle the functools.partial object with wrong state. Fixed a leak in failed functools.partial constructor. "args" and "keywords" attributes of functools.partial have now always types