diff options
Diffstat (limited to 'Lib/urllib/request.py')
-rw-r--r-- | Lib/urllib/request.py | 86 |
1 files changed, 56 insertions, 30 deletions
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 0d1b594..f22dc56 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1646,36 +1646,62 @@ class DataHandler(BaseHandler): # Code move from the old urllib module -# Helper for non-unix systems -if os.name == 'nt': - from nturl2path import url2pathname, pathname2url -else: - def url2pathname(pathname): - """OS-specific conversion from a relative URL of the 'file' scheme - to a file system path; not recommended for general use.""" - if pathname[:3] == '///': - # URL has an empty authority section, so the path begins on the - # third character. - pathname = pathname[2:] - elif pathname[:12] == '//localhost/': - # Skip past 'localhost' authority. - pathname = pathname[11:] - encoding = sys.getfilesystemencoding() - errors = sys.getfilesystemencodeerrors() - return unquote(pathname, encoding=encoding, errors=errors) - - def pathname2url(pathname): - """OS-specific conversion from a file system path to a relative URL - of the 'file' scheme; not recommended for general use.""" - if pathname[:1] == '/': - # Add explicitly empty authority to absolute path. If the path - # starts with exactly one slash then this change is mostly - # cosmetic, but if it begins with two or more slashes then this - # avoids interpreting the path as a URL authority. - pathname = '//' + pathname - encoding = sys.getfilesystemencoding() - errors = sys.getfilesystemencodeerrors() - return quote(pathname, encoding=encoding, errors=errors) +def url2pathname(url): + """OS-specific conversion from a relative URL of the 'file' scheme + to a file system path; not recommended for general use.""" + if url[:3] == '///': + # Empty authority section, so the path begins on the third character. + url = url[2:] + elif url[:12] == '//localhost/': + # Skip past 'localhost' authority. + url = url[11:] + + if os.name == 'nt': + if url[:3] == '///': + # Skip past extra slash before UNC drive in URL path. + url = url[1:] + else: + if url[:1] == '/' and url[2:3] in (':', '|'): + # Skip past extra slash before DOS drive in URL path. + url = url[1:] + if url[1:2] == '|': + # Older URLs use a pipe after a drive letter + url = url[:1] + ':' + url[2:] + url = url.replace('/', '\\') + encoding = sys.getfilesystemencoding() + errors = sys.getfilesystemencodeerrors() + return unquote(url, encoding=encoding, errors=errors) + + +def pathname2url(pathname): + """OS-specific conversion from a file system path to a relative URL + of the 'file' scheme; not recommended for general use.""" + if os.name == 'nt': + pathname = pathname.replace('\\', '/') + encoding = sys.getfilesystemencoding() + errors = sys.getfilesystemencodeerrors() + drive, root, tail = os.path.splitroot(pathname) + if drive: + # First, clean up some special forms. We are going to sacrifice the + # additional information anyway + if drive[:4] == '//?/': + drive = drive[4:] + if drive[:4].upper() == 'UNC/': + drive = '//' + drive[4:] + if drive[1:] == ':': + # DOS drive specified. Add three slashes to the start, producing + # an authority section with a zero-length authority, and a path + # section starting with a single slash. + drive = '///' + drive + drive = quote(drive, encoding=encoding, errors=errors, safe='/:') + elif root: + # Add explicitly empty authority to absolute path. If the path + # starts with exactly one slash then this change is mostly + # cosmetic, but if it begins with two or more slashes then this + # avoids interpreting the path as a URL authority. + root = '//' + root + tail = quote(tail, encoding=encoding, errors=errors) + return drive + root + tail # Utility functions |