[Yum-devel] Bug in urlgrabber _parse_url
Jim Cain
jecain at gmail.com
Fri Jul 7 21:24:29 UTC 2006
On python 2.4.3 with yum 2.4.1 and urlgrabber 2.9.6 ond Fedora Core 4,
I was getting a 401 error with a repository that uses authorization
and a non-standard port. Previous versions were working okay. In this
case, yum was not passing along the auth info to the server, resulting
in the 401.
After some digging, I discovered the error is in the way that
urlgrabber uses urllib2. In the add_password call, an url is expected
as the second parameter, but urlgrabber passes the hostname. It looks
like this became a problem when urllib2 recently made a change to the
parameters it uses internally.
In any case, here is a quick and dirty fix to grabber.py. The
urlunparse call is repeated a few lines later, so it would probably be
better to rearrange the logic. add_password() wants an url as the
second parameter, without auth info, so that's why I reassemble the
url there. I was too lazy to come up with new logic. :)
*** grabber.py.orig 2005-03-02 19:54:23.000000000 -0500
--- grabber.py 2006-07-07 16:51:42.000000000 -0400
***************
*** 687,693 ****
except ValueError, e:
raise URLGrabError(1, _('Bad URL: %s') % url)
if DEBUG: print 'adding HTTP auth: %s, %s' % (user, password)
! auth_handler.add_password(None, host, user, password)
parts = (scheme, host, path, parm, query, frag)
url = urlparse.urlunparse(parts)
return url, parts
--- 687,693 ----
except ValueError, e:
raise URLGrabError(1, _('Bad URL: %s') % url)
if DEBUG: print 'adding HTTP auth: %s, %s' % (user, password)
! auth_handler.add_password(None,
urlparse.urlunparse((scheme, host, path, parm, query, frag)), user,
password)
parts = (scheme, host, path, parm, query, frag)
url = urlparse.urlunparse(parts)
return url, parts
If anyone cares, here is the relevant chunk of a diff between
urllib2.py in 2.4.1 and 2.4.3:
***************
*** 720,726 ****
return self.retry_http_basic_auth(host, req, realm)
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.encodestring(raw).strip()
--- 720,726 ----
return self.retry_http_basic_auth(host, req, realm)
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.encodestring(raw).strip()
You can see that it now passes the url to find_user_password() instead
of the host. This is probably what broke urlgrabber's use of host in
add_password().
More information about the Yum-devel
mailing list