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

Augie Fackler raf at durin42.com
Fri Dec 13 11:48:35 CST 2013


On Tue, Dec 10, 2013 at 04:22:39PM -0500, Augie Fackler wrote:
> On Mon, Nov 25, 2013 at 05:22:10PM +0100, Stéphane Klein wrote:
> > # HG changeset patch
> > # User Stéphane Klein <contact at stephane-klein.info>
> > # Date 1385396292 -3600
> > #      Mon Nov 25 17:18:12 2013 +0100
> > # Node ID ec1afe2354a840eb47a2286308fb5a5eeed91eba
> > # Parent  1c46b18b0e1c47fa4cecf21b78c083a54ae9903f
> > Keep authentication information after the first fail HTTP access (issue3567)
>
> Hearing no objections after a couple of weeks, I'm queueing this. It
> seems reasonable.

(but, I should mention, with some tweaks to the log message to make it
more compliant with our format and a minor English tweak)

>
> >
> > 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 1c46b18b0e1c -r ec1afe2354a8 mercurial/url.py
> > --- a/mercurial/url.py    Fri Nov 22 17:26:58 2013 -0600
> > +++ b/mercurial/url.py    Mon Nov 25 17:18:12 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, host)
> > +        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_unredirected_header(self.auth_header, auth)
> > +            return self.parent.open(req, timeout=req.timeout)
> > +        else:
> > +            return None
> > +
> >  handlerfuncs = []
> >
> >  def opener(ui, authinfo=None):
> >
> > --
> > Stéphane Klein <sklein at bearstech.com>
> > GSM : 06 61 48 76 04
> >
> > _______________________________________________
> > Mercurial-devel mailing list
> > Mercurial-devel at selenic.com
> > http://selenic.com/mailman/listinfo/mercurial-devel
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list