Index: Lib/urllib/request.py =================================================================== --- Lib/urllib/request.py (revision 65739) +++ Lib/urllib/request.py (working copy) @@ -100,7 +100,7 @@ from urllib.parse import ( urlparse, urlsplit, urljoin, unwrap, quote, unquote, splittype, splithost, splitport, splituser, splitpasswd, - splitattr, splitquery, splitvalue, to_bytes) + splitattr, splitquery, splitvalue, to_bytes, fix_broken) from urllib.response import addinfourl, addclosehook # check for SSL @@ -535,8 +535,11 @@ newurl = headers["uri"] else: return - newurl = urljoin(req.get_full_url(), newurl) + # fix the broken url and then join with req.get_full_url() + newurl = urljoin(req.get_full_url(), + fix_broken(newurl)) + # XXX Probably want to forget about the state of the current # request, although that might interact poorly with other # handlers that also use handler-specific request attributes Index: Lib/urllib/parse.py =================================================================== --- Lib/urllib/parse.py (revision 65739) +++ Lib/urllib/parse.py (working copy) @@ -41,6 +41,13 @@ """Clear the parse cache.""" _parse_cache.clear() +def fix_broken(url): + """Attempt to fix broken, non-confirming urls. Handle the way the browsers + handle it.""" + scheme, netloc, path, params, query, fragment = urlparse(url) + if not path: path = '/' + fixedurl = urlunparse((scheme, netloc, path, params, query, fragment)) + return fixedurl class ResultMixin(object): """Shared methods for the parsed result objects."""