diff options
Diffstat (limited to 'Lib/urllib2.py')
-rw-r--r-- | Lib/urllib2.py | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/Lib/urllib2.py b/Lib/urllib2.py index cdb3a22..227311c 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -297,6 +297,10 @@ class OpenerDirector: def add_handler(self, handler): added = False for meth in dir(handler): + if meth in ["redirect_request", "do_open", "proxy_open"]: + # oops, coincidental match + continue + i = meth.find("_") protocol = meth[:i] condition = meth[i+1:] @@ -695,32 +699,45 @@ class HTTPPasswordMgr: # uri could be a single URI or a sequence if isinstance(uri, basestring): uri = [uri] - uri = tuple(map(self.reduce_uri, uri)) if not realm in self.passwd: self.passwd[realm] = {} - self.passwd[realm][uri] = (user, passwd) + for default_port in True, False: + reduced_uri = tuple( + [self.reduce_uri(u, default_port) for u in uri]) + self.passwd[realm][reduced_uri] = (user, passwd) def find_user_password(self, realm, authuri): domains = self.passwd.get(realm, {}) - authuri = self.reduce_uri(authuri) - for uris, authinfo in domains.iteritems(): - for uri in uris: - if self.is_suburi(uri, authuri): - return authinfo + for default_port in True, False: + reduced_authuri = self.reduce_uri(authuri, default_port) + for uris, authinfo in domains.iteritems(): + for uri in uris: + if self.is_suburi(uri, reduced_authuri): + return authinfo return None, None - def reduce_uri(self, uri): - """Accept netloc or URI and extract only the netloc and path""" + def reduce_uri(self, uri, default_port=True): + """Accept authority or URI and extract only the authority and path.""" + # note HTTP URLs do not have a userinfo component parts = urlparse.urlsplit(uri) if parts[1]: # URI - return parts[1], parts[2] or '/' - elif parts[0]: - # host:port - return uri, '/' + scheme = parts[0] + authority = parts[1] + path = parts[2] or '/' else: - # host - return parts[2], '/' + # host or host:port + scheme = None + authority = uri + path = '/' + host, port = splitport(authority) + if default_port and port is None and scheme is not None: + dport = {"http": 80, + "https": 443, + }.get(scheme) + if dport is not None: + authority = "%s:%d" % (host, dport) + return authority, path def is_suburi(self, base, test): """Check if test is below base in a URI tree @@ -755,6 +772,10 @@ class AbstractBasicAuthHandler: # www-authenticate header. should probably be a lot more careful # in parsing them to extract multiple alternatives + # XXX could pre-emptively send auth info already accepted (RFC 2617, + # end of section 2, and section 1.2 immediately after "credentials" + # production). + def __init__(self, password_mgr=None): if password_mgr is None: password_mgr = HTTPPasswordMgr() @@ -964,6 +985,7 @@ class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): """ auth_header = 'Authorization' + handler_order = 490 # before Basic auth def http_error_401(self, req, fp, code, msg, headers): host = urlparse.urlparse(req.get_full_url())[1] @@ -976,6 +998,7 @@ class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): auth_header = 'Proxy-Authorization' + handler_order = 490 # before Basic auth def http_error_407(self, req, fp, code, msg, headers): host = req.get_host() |