This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients hamzaavvan, paul.moore, steve.dower, tim.golden, vstinner, zach.ware
Date 2021-02-17.22:26:32
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
I can only reproduce the issue if the current directory (directory used by the HTTP server, see --directory command line option) contains a .ssh/ subdirectory.

The problem is that the HTTP Header Location starts with "//domain/" and such URL is interpreted as an absolute URL of a new domain name ("domain"), rather than a relative path of the same domain ("localhost").

Maybe we should simply strip all additional leading slashes to only keep one. Replace "//path" or  "/////path" with "/path" for example.


By the way, http.server uses urllib.parse.urlsplit() on the request URL without passing its own domain, and urllib.parse.urlsplit() interprets "//" as if is a host with no scheme:

>>> urllib.parse.urlsplit('//')
SplitResult(scheme='', netloc='', path='/path', query='', fragment='')

Maybe parse_qs() should be used instead? Or we should reinject the server domain and port number? I am not sure that it's an issue in practice.

SimpleHTTPRequestHandler.translate_path('//') returns os.path.join(, ".ssh"). I don't think that it's an issue, it sounds like the expected behavior. We don't attempt to reject ".." in URL.


To reproduce the issue, I used two terminals.

Terminal 1:

$ python3.8 -V
Python 3.8.7
$ python3.8 -m http.server
Serving HTTP on port 8000 ( ... - - [15/Feb/2021 09:18:20] "GET
// HTTP/1.1" 301 -

Terminal 2:

$ wget ''
HTTP request sent, awaiting response... 301 Moved Permanently
Location: // [following]

--2021-02-15 09:18:20--
Resolving (
Connecting to (||:80... connected.


wget is redirected and connects to

The HTTP redirection comes from Lib/http/

    def send_head(self):
        path = self.translate_path(self.path)
        f = None
        if os.path.isdir(path):
            parts = urllib.parse.urlsplit(self.path)
            if not parts.path.endswith('/'):
                # redirect browser - doing basically what apache does
                new_parts = (parts[0], parts[1], parts[2] + '/',
                             parts[3], parts[4])
                new_url = urllib.parse.urlunsplit(new_parts)
                self.send_header("Location", new_url)
                return None

The problem is that the "Location" header starts with "//".
Date User Action Args
2021-02-17 22:26:33vstinnersetrecipients: + vstinner, paul.moore, tim.golden, zach.ware, steve.dower, hamzaavvan
2021-02-17 22:26:33vstinnersetmessageid: <>
2021-02-17 22:26:33vstinnerlinkissue43223 messages
2021-02-17 22:26:32vstinnercreate