binhost: http auth for python3 (bug #413983)
authorZac Medico <zmedico@gentoo.org>
Mon, 14 May 2012 05:01:51 +0000 (22:01 -0700)
committerZac Medico <zmedico@gentoo.org>
Mon, 14 May 2012 05:01:51 +0000 (22:01 -0700)
This uses the code from commit 58a8cd1bb943522bc53d02c008ee8eff798bfaaa
as a fallback for python3 when the default urlopen function fails. This
has been tested and is known to work with thttpd password
authentication (it works unencrypted and also when encrypted with
stunnel).

pym/portage/dbapi/bintree.py
pym/portage/util/_urlopen.py [new file with mode: 0644]

index 4ac48c9dfc73740274f4392d60012f6d7f381c9a..08fdad02bc74a3a0a9200dbd0cec38d9f4019c9f 100644 (file)
@@ -16,6 +16,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.util:atomic_ofstream,ensure_dirs,normalize_path,' + \
                'writemsg,writemsg_stdout',
        'portage.util.listdir:listdir',
+       'portage.util._urlopen:urlopen@_urlopen',
        'portage.versions:best,catpkgsplit,catsplit,_pkg_str',
 )
 
@@ -45,10 +46,8 @@ import warnings
 from itertools import chain
 try:
        from urllib.parse import urlparse
-       from urllib.request import urlopen as urllib_request_urlopen
 except ImportError:
        from urlparse import urlparse
-       from urllib import urlopen as urllib_request_urlopen
 
 if sys.hexversion >= 0x3000000:
        basestring = str
@@ -845,7 +844,7 @@ class binarytree(object):
                                # slash, so join manually...
                                url = base_url.rstrip("/") + "/Packages"
                                try:
-                                       f = urllib_request_urlopen(url)
+                                       f = _urlopen(url)
                                except IOError:
                                        path = parsed_url.path.rstrip("/") + "/Packages"
 
diff --git a/pym/portage/util/_urlopen.py b/pym/portage/util/_urlopen.py
new file mode 100644 (file)
index 0000000..307624b
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright 2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import sys
+
+try:
+       from urllib.request import urlopen as _urlopen
+       import urllib.parse as urllib_parse
+       import urllib.request as urllib_request
+       from urllib.parse import splituser as urllib_parse_splituser
+except ImportError:
+       from urllib import urlopen as _urlopen
+       import urlparse as urllib_parse
+       import urllib2 as urllib_request
+       from urllib import splituser as urllib_parse_splituser
+
+def urlopen(url):
+       try:
+               return _urlopen(url)
+       except SystemExit:
+               raise
+       except Exception:
+               if sys.hexversion < 0x3000000:
+                       raise
+               parse_result = urllib_parse.urlparse(url)
+               if parse_result.scheme not in ("http", "https") or \
+                       not parse_result.username:
+                       raise
+
+       return _new_urlopen(url)
+
+def _new_urlopen(url):
+       # This is experimental code for bug #413983.
+       parse_result = urllib_parse.urlparse(url)
+       netloc = urllib_parse_splituser(parse_result.netloc)[1]
+       url = urllib_parse.urlunparse((parse_result.scheme, netloc, parse_result.path, parse_result.params, parse_result.query, parse_result.fragment))
+       password_manager = urllib_request.HTTPPasswordMgrWithDefaultRealm()
+       if parse_result.username is not None:
+               password_manager.add_password(None, url, parse_result.username, parse_result.password)
+       auth_handler = urllib_request.HTTPBasicAuthHandler(password_manager)
+       opener = urllib_request.build_opener(auth_handler)
+       return opener.open(url)