]> granicus.if.org Git - python/commitdiff
Issue #12923: Reset FancyURLopener's redirect counter even on exception
authorMartin Panter <vadmium+py@gmail.com>
Thu, 4 Feb 2016 06:01:35 +0000 (06:01 +0000)
committerMartin Panter <vadmium+py@gmail.com>
Thu, 4 Feb 2016 06:01:35 +0000 (06:01 +0000)
Based on patches by Brian Brazil and Daniel Rocco.

Lib/test/test_urllib.py
Lib/urllib/request.py
Misc/ACKS
Misc/NEWS

index 57eeeaa6978c745b857509a890af096d86ecb365..e197a3f92eaf7aabf020ccd0221a7a70dbacd2be 100644 (file)
@@ -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)
index a7fd017e1065afdb83947486316e2df45789897b..4c1651861b364b8f0dc444db28aa9f5c9ad93d2d 100644 (file)
@@ -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:
index b07244a130f855b74d7642dd4f7e8c26e141904c..9fa22e103178df02bcf80b3805280d761a724db0 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1214,6 +1214,7 @@ Ben Roberts
 Mark Roberts
 Andy Robinson
 Jim Robinson
+Daniel Rocco
 Mark Roddy
 Kevin Rodgers
 Sean Rodman
index 691c53371769a1a48b46eef19b0f215219f2593a..5aa57b9233099cc1aff62d961b0c9713d9a4affa 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -73,6 +73,9 @@ Core and Builtins
 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