[PATCH] Keep authentication information after the first fail HTTP access (issue3567)

Augie Fackler raf at durin42.com
Wed Jan 1 17:20:27 CST 2014


On Mon, Dec 30, 2013 at 03:27:09PM +0100, Stéphane Klein wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> # HG changeset patch
> # User Stéphane Klein <contact at stephane-klein.info>
> # Date 1388413356 -3600
> #      Mon Dec 30 15:22:36 2013 +0100
> # Node ID 9063db5432d6c6c75491e759861a373bc493822a
> # Parent  4274eda143cb1025be1130ffdaaf62370a2a6961
> Keep authentication information after the first fail HTTP access (issue3567)
>

Looks reasonable here. Can someone run the testsuite for this on 2.4
and 2.7 and verify it works? I don't have ready access to anything
with Python 2.4 anymore.

>
> Context : mercurial access to repository server with http access, and this
> server is protected by basic auth.
>
> Before patch :
>
> * mercurial try an anonymous access to server, server return 401 response and
>   mercurial resend request with login / password information
>
> After patch :
>
> * mercurial try an anonymous access to server, server return
>   401 response. For all next requests, mercurial keep in memory this
>   information (this server need basic auth information).
>
> This patch reduce the number of http access against mercurial server.
>
> Example, before patch :
>
> 10.10.168.170 - - [25/Oct/2013:15:44:51 +0200] "GET /hg/testagt?cmd=capabilities
> HTTP/1.1" 401 260 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:44:52 +0200] "GET /hg/testagt?cmd=capabilities
> HTTP/1.1" 200 147 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:00 +0200] "GET /hg/testagt?cmd=capabilities
> HTTP/1.1" 401 260 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:01 +0200] "GET /hg/testagt?cmd=capabilities
> HTTP/1.1" 200 147 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:03 +0200] "GET /hg/testagt?cmd=batch
> HTTP/1.1" 401 260 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:04 +0200] "GET /hg/testagt?cmd=batch
> HTTP/1.1" 200 42 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:06 +0200] "GET /hg/testagt?cmd=getbundle
> HTTP/1.1" 401 260 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:07 +0200] "GET /hg/testagt?cmd=getbundle
> HTTP/1.1" 200 61184 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:09 +0200] "GET /hg/testagt?cmd=listkeys
> HTTP/1.1" 401 260 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:10 +0200] "GET /hg/testagt?cmd=listkeys
> HTTP/1.1" 200 15 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:12 +0200] "GET /hg/testagt?cmd=listkeys
> HTTP/1.1" 401 260 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [25/Oct/2013:15:45:12 +0200] "GET /hg/testagt?cmd=listkeys
> HTTP/1.1" 200 - "-" "mercurial/proto-1.0"
>
> Example after patch :
>
> 10.10.168.170 - - [28/Oct/2013:11:49:14 +0100] "GET /hg/testagt?cmd=capabilities
> HTTP/1.1" 401 260 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [28/Oct/2013:11:49:15 +0100] "GET /hg/testagt?cmd=capabilities
> HTTP/1.1" 200 147 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [28/Oct/2013:11:49:17 +0100] "GET /hg/testagt?cmd=batch
> HTTP/1.1" 200 42 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [28/Oct/2013:11:49:19 +0100] "GET /hg/testagt?cmd=getbundle
> HTTP/1.1" 200 61184 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [28/Oct/2013:11:49:22 +0100] "GET /hg/testagt?cmd=listkeys
> HTTP/1.1" 200 15 "-" "mercurial/proto-1.0"
> 10.10.168.170 - - [28/Oct/2013:11:49:24 +0100] "GET /hg/testagt?cmd=listkeys
> HTTP/1.1" 200 - "-" "mercurial/proto-1.0"
>
> In this last example, you can see only one 401 response.
>
> diff -r 4274eda143cb -r 9063db5432d6 mercurial/url.py
> - --- a/mercurial/url.py	Mon Sep 16 01:08:29 2013 -0700
> +++ b/mercurial/url.py	Mon Dec 30 15:22:36 2013 +0100
> @@ -8,6 +8,7 @@
>  # GNU General Public License version 2 or any later version.
>
>  import urllib, urllib2, httplib, os, socket, cStringIO
> +import base64
>  from i18n import _
>  import keepalive, util, sslutil
>  import httpconnection as httpconnectionmod
> @@ -418,9 +419,22 @@
>
>  class httpbasicauthhandler(urllib2.HTTPBasicAuthHandler):
>      def __init__(self, *args, **kwargs):
> +        self.auth = None
>          urllib2.HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
>          self.retried_req = None
>
> +    def http_request(self, request):
> +        if self.auth:
> +            request.add_unredirected_header(self.auth_header, self.auth)
> +
> +        return request
> +
> +    def https_request(self, request):
> +        if self.auth:
> +            request.add_unredirected_header(self.auth_header, self.auth)
> +
> +        return request
> +
>      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
> @@ -435,6 +449,19 @@
>          return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(
>                          self, auth_header, host, req, headers)
>
> +    def retry_http_basic_auth(self, host, req, realm):
> +        user, pw = self.passwd.find_user_password(realm, req.get_full_url())
> +        if pw is not None:
> +            raw = "%s:%s" % (user, pw)
> +            auth = 'Basic %s' % base64.b64encode(raw).strip()
> +            if req.headers.get(self.auth_header, None) == auth:
> +                return None
> +            self.auth = auth
> +            req.add_header(self.auth_header, auth)
> +            return self.parent.open(req)
> +        else:
> +            return None
> +
>  handlerfuncs = []
>
>  def opener(ui, authinfo=None):
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.12 (Darwin)
> Comment: GPGTools - http://gpgtools.org
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
>
> iF4EAREIAAYFAlLBgr0ACgkQU9O4HJsr4YyHrgD8D53D5ch3lXNMBY6u06MMCUL3
> Di2nnU+ozINRP4hS56UA/RKm7kf4eUzcXBkUaI/wxYB0SL4Z5h3tNrEsYSk9SQyZ
> =AFUv
> -----END PGP SIGNATURE-----
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list