[Python-checkins] cpython (2.7): Issue #12923: Reset FancyURLopener's redirect counter even on exception

martin.panter python-checkins at python.org
Thu Feb 4 20:22:16 EST 2016


https://hg.python.org/cpython/rev/a8aa7944c5a8
changeset:   100161:a8aa7944c5a8
branch:      2.7
parent:      100154:c8e43e55f2ce
user:        Martin Panter <vadmium+py at gmail.com>
date:        Thu Feb 04 06:01:35 2016 +0000
summary:
  Issue #12923: Reset FancyURLopener's redirect counter even on exception

Based on patches by Brian Brazil and Daniel Rocco.

files:
  Lib/test/test_urllib.py |  18 +++++++++++++++++-
  Lib/urllib.py           |  24 +++++++++++++-----------
  Misc/ACKS               |   1 +
  Misc/NEWS               |   3 +++
  4 files changed, 34 insertions(+), 12 deletions(-)


diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -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 --git a/Lib/urllib.py b/Lib/urllib.py
--- a/Lib/urllib.py
+++ b/Lib/urllib.py
@@ -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 --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1154,6 +1154,7 @@
 Mark Roberts
 Andy Robinson
 Jim Robinson
+Daniel Rocco
 Mark Roddy
 Kevin Rodgers
 Sean Rodman
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list