changeset 11457:2ec346160783 stable

http digest auth: reset redirect counter on new requests (issue2255) This fixes a regression introduced in a1e575b48563 when Mercurial reuses the auth handler for several requests and the redirect counter never is reset.
author Mads Kiilerich <mads@kiilerich.com>
date Sat, 26 Jun 2010 23:00:58 +0200
parents 88abbb046e66
children ec21d91c79b3
files mercurial/url.py
diffstat 1 files changed, 17 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/url.py	Mon Jun 28 11:07:27 2010 -0500
+++ b/mercurial/url.py	Sat Jun 26 23:00:58 2010 +0200
@@ -542,11 +542,25 @@
             conn.ui = self.ui
             return conn
 
-# In python < 2.5 AbstractDigestAuthHandler raises a ValueError if
-# it doesn't know about the auth type requested.  This can happen if
-# somebody is using BasicAuth and types a bad password.
 class httpdigestauthhandler(urllib2.HTTPDigestAuthHandler):
+    def __init__(self, *args, **kwargs):
+        urllib2.HTTPDigestAuthHandler.__init__(self, *args, **kwargs)
+        self.retried_req = None
+
+    def reset_retry_count(self):
+        # Python 2.6.5 will call this on 401 or 407 errors and thus loop
+        # forever. We disable reset_retry_count completely and reset in
+        # http_error_auth_reqed instead.
+        pass
+
     def http_error_auth_reqed(self, auth_header, host, req, headers):
+        # Reset the retry counter once for each request.
+        if req is not self.retried_req:
+            self.retried_req = req
+            self.retried = 0
+        # In python < 2.5 AbstractDigestAuthHandler raises a ValueError if
+        # it doesn't know about the auth type requested. This can happen if
+        # somebody is using BasicAuth and types a bad password.
         try:
             return urllib2.HTTPDigestAuthHandler.http_error_auth_reqed(
                         self, auth_header, host, req, headers)
@@ -556,13 +570,6 @@
                 return
             raise
 
-    # Python 2.6.5 will keep resetting the retry count on redirects, for
-    # example when the server returns 401 on failing auth (like google code
-    # currently does). We stop the endless recursion by not resetting the
-    # count.
-    def reset_retry_count(self):
-        pass
-
 def getauthinfo(path):
     scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
     if not urlpath: