# HG changeset patch # User Patrick Mezard # Date 1312571141 -7200 # Node ID 0593e8f81c712eb29ee3593c22d8b777a6d6f076 # Parent 0f1311e829c950b9327d09069f391039eee724dc http: pass user to readauthforuri() (fix 4a43e23b8c55) urllib2 never handles URIs with credentials, we have to extract them and store them in the password manager before handing the stripped URI. Half of the changes deducing the username from the URI in 4a43e23b8c55 were incorrect. Instead, we retrieve the username from the password manager before passing to readauthforuri(). test-hgweb-auth.py was passing because the test itself was flawed: it was passing URIs with credentials to find_password(), which never happens. diff -r 0f1311e829c9 -r 0593e8f81c71 mercurial/httpconnection.py --- a/mercurial/httpconnection.py Fri Aug 05 21:05:40 2011 +0200 +++ b/mercurial/httpconnection.py Fri Aug 05 21:05:41 2011 +0200 @@ -58,7 +58,7 @@ return self._len # moved here from url.py to avoid a cycle -def readauthforuri(ui, uri): +def readauthforuri(ui, uri, user): # Read configuration config = dict() for key, val in ui.configitems('auth'): @@ -72,10 +72,6 @@ gdict[setting] = val # Find the best match - uri = util.url(uri) - user = uri.user - uri.user = uri.password = None - uri = str(uri) scheme, hostpath = uri.split('://', 1) bestuser = None bestlen = 0 @@ -238,7 +234,11 @@ return self.do_open(HTTPConnection, req, False) def https_open(self, req): - res = readauthforuri(self.ui, req.get_full_url()) + # req.get_full_url() does not contain credentials and we may + # need them to match the certificates. + url = req.get_full_url() + user, password = self.pwmgr.find_stored_password(url) + res = readauthforuri(self.ui, url, user) if res: group, auth = res self.auth = auth diff -r 0f1311e829c9 -r 0593e8f81c71 mercurial/url.py --- a/mercurial/url.py Fri Aug 05 21:05:40 2011 +0200 +++ b/mercurial/url.py Fri Aug 05 21:05:41 2011 +0200 @@ -26,7 +26,7 @@ return (user, passwd) if not user or not passwd: - res = httpconnectionmod.readauthforuri(self.ui, authuri) + res = httpconnectionmod.readauthforuri(self.ui, authuri, user) if res: group, auth = res user, passwd = auth.get('username'), auth.get('password') @@ -53,6 +53,10 @@ msg = _('http auth: user %s, password %s\n') self.ui.debug(msg % (user, passwd and '*' * len(passwd) or 'not set')) + def find_stored_password(self, authuri): + return urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password( + self, None, authuri) + class proxyhandler(urllib2.ProxyHandler): def __init__(self, ui): proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy') @@ -342,7 +346,11 @@ return keepalive.KeepAliveHandler._start_transaction(self, h, req) def https_open(self, req): - res = httpconnectionmod.readauthforuri(self.ui, req.get_full_url()) + # req.get_full_url() does not contain credentials and we may + # need them to match the certificates. + url = req.get_full_url() + user, password = self.pwmgr.find_stored_password(url) + res = httpconnectionmod.readauthforuri(self.ui, url, user) if res: group, auth = res self.auth = auth diff -r 0f1311e829c9 -r 0593e8f81c71 tests/test-hgweb-auth.py --- a/tests/test-hgweb-auth.py Fri Aug 05 21:05:40 2011 +0200 +++ b/tests/test-hgweb-auth.py Fri Aug 05 21:05:41 2011 +0200 @@ -37,10 +37,10 @@ print 'URI:', uri try: pm = url.passwordmgr(ui) - authinfo = util.url(uri).authinfo()[1] + u, authinfo = util.url(uri).authinfo() if authinfo is not None: pm.add_password(*authinfo) - print ' ', pm.find_user_password('test', uri) + print ' ', pm.find_user_password('test', u) except Abort, e: print 'abort'