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.

classification
Title: Trailing slash redirection for SimpleHTTPServer
Type: enhancement Stage: test needed
Components: Library (Lib) Versions: Python 3.1, Python 2.7
process
Status: closed Resolution: duplicate
Dependencies: Superseder: SimpleHTTPServer directory-indexing "bug" fix
View: 827559
Assigned To: akuchling Nosy List: ajaksu2, akuchling, amaury.forgeotdarc, josiahcarlson
Priority: normal Keywords: easy, patch

Created on 2005-10-06 06:49 by josiahcarlson, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
send_head.py josiahcarlson, 2005-10-06 06:59 send_head method
Messages (6)
msg26523 - (view) Author: Josiah Carlson (josiahcarlson) * (Python triager) Date: 2005-10-06 06:49
As known by every serious web server developer, the
lack of a trailing slash on direcories can cause some
serious web page loading issues.  Take the following
examples...

Let us imagine that: 'http://www.foo.com/foo' points to
a directory containing 'index.html'.  A web server
could return the contents of 'index.html', but then any
relative urls would be relative to the / path of the
web server.

A better web server would instead redirect the user to
'http://www.foo.com/foo/'.  SimpleHTTPServer does not
do any such redirection, and the documentation for
forcing a client to redirect is difficult to find on
the internet.  In the comments I will post a
replacement
SimpleHTTPServer.SimpleHTTPRequestHandler.send_head
method which does automatic trailing slash redirection.
msg26524 - (view) Author: Josiah Carlson (josiahcarlson) * (Python triager) Date: 2005-10-06 06:58
Logged In: YES 
user_id=341410

    def send_head(self):
        """Common code for GET and HEAD commands.

        This sends the response code and MIME headers.

        Return value is either a file object (which has to
be copied
        to the outputfile by the caller unless the command
was HEAD,
        and must be closed by the caller under all
circumstances), or
        None, in which case the caller has nothing further
to do.

        """
        path = self.translate_path(self.path)
        f = None
        if os.path.isdir(path):
            # Redirect path urls which lack a trailing slash
            if not self.path.endswith('/'):
                self.send_response(302)
                self.send_header("Content-type", "text/html")
                self.send_header("Content-Location",
self.path + '/')
                self.end_headers()
                return StringIO('<META HTTP-EQUIV="refresh"
CONTENT="0;URL=%s/">'%self.path)
            for index in "index.html", "index.htm":
                index = os.path.join(path, index)
                if os.path.exists(index):
                    path = index
                    break
            else:
                return self.list_directory(path)
        ctype = self.guess_type(path)
        try:
            # Always read in binary mode. Opening files in
text mode may cause
            # newline translations, making the actual size
of the content
            # transmitted *less* than the content-length!
            f = open(path, 'rb')
        except IOError:
            self.send_error(404, "File not found")
            return None
        self.send_response(200)
        self.send_header("Content-type", ctype)
        self.send_header("Content-Length",
str(os.fstat(f.fileno())[6]))
        self.end_headers()
        return f
msg26525 - (view) Author: Josiah Carlson (josiahcarlson) * (Python triager) Date: 2005-10-06 07:00
Logged In: YES 
user_id=341410

I've attached a file which contains the method, which should
save everyone from having to deal with SF's line wrapping.
msg83878 - (view) Author: Daniel Diniz (ajaksu2) * (Python triager) Date: 2009-03-20 22:43
Has patch.
msg89970 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-07-01 10:17
The same problem was fixed with issue827559.
But the patch here is different:

- it returns a code 302 instead of 301

- it uses the header "Content-Location" instead of "Location" to set the
new path with the slash

- it sets "Content-type: text/html" and returns the following content:
   '<META HTTP-EQUIV="refresh" CONTENT="0;URL=%s/">'%self.path

Some HTTP expert should conclude.
msg89988 - (view) Author: Josiah Carlson (josiahcarlson) * (Python triager) Date: 2009-07-01 16:18
The other patch is more correct.  Closing.
History
Date User Action Args
2022-04-11 14:56:13adminsetgithub: 42455
2009-07-01 16:18:59josiahcarlsonsetstatus: open -> closed
resolution: duplicate
superseder: SimpleHTTPServer directory-indexing "bug" fix
messages: + msg89988
2009-07-01 10:17:45amaury.forgeotdarcsetassignee: akuchling

messages: + msg89970
nosy: + amaury.forgeotdarc, akuchling
2009-04-22 14:36:37ajaksu2setkeywords: + patch
2009-03-20 22:43:00ajaksu2setversions: + Python 3.1, Python 2.7
nosy: + ajaksu2

messages: + msg83878

keywords: + easy
stage: test needed
2005-10-06 06:49:57josiahcarlsoncreate