[PATCH 1 of 1 STABLE] http digest auth: reset redirect counter on new requests (issue2255)

Wagner Bruna wagner.bruna+mercurial at gmail.com
Sat Jun 26 19:25:10 CDT 2010


# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1277586058 -7200
# Branch stable
# Node ID f19b6d8ae201d91396a4e32157c1c1698efb45ed
# Parent  b9a46acdfe1f8f5c5c0ff63bf759b590e6780c81
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.

diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -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:


More information about the Mercurial-devel mailing list