durusmail: quixote-users: StaticFile mime type and encoding
StaticFile mime type and encoding
2003-03-12
2003-03-12
StaticFile mime type and encoding
Jim Dukarm
2003-03-12
Hi -

Thanks for including StaticFile and StaticDirectory in Quixote 0.6. I
was already doing something similar (for retrieving the stylesheet,
images, and help pages), but it will be handy to have that capability
as a standard part of Quixote for all of us using the Medusa server.

I was wondering whether the StaticFile should perhaps have an
additional constructor argument "encoding=None", and also not throw
away the encoding component of what mimetypes.guess_type() returns. My
understanding is that, if the pages are gzipped or compressed, the
client needs to have the "encoding" information (i.e., the name of
the program that compressed the page).

I note also that StaticFile.__call__() uses this:

   request.response.set_header('Content-Type', self.mime_type)

instead of this:

   request.response.set_content_type(self.mime_type)

If encoding is taken into consideration, the call to
set_content_type() should be followed by:

   if self.encoding:
       request.response.set_header("Content-Encoding", self.encoding)

The patched StaticFile is given below.

Jim Dukarm
DELTA-X RESEARCH
Victoria BC Canada

------- Revised StaticFile -----------

class StaticFile:

    """
    Wrapper for a static file on the filesystem.
    """

    def __init__(self, path, follow_symlinks=0, \
                       mime_type=None, encoding=None):
        """StaticFile(path:string, follow_symlinks:bool)

        Initialize instance with the absolute path to the file.
        If 'follow_symlinks' is true, symbolic links will be followed.
        'mime_type' specifies the MIME type; if omitted, the MIME
        type will be guessed, defaulting to text/plain.
        'encoding' is None for no encoding, or the name of the program
        used to encode the page (e.g. compress or gzip). See documentation
        for mimetypes.guess_type().
        """

        # Check that the supplied path is absolute and (if a symbolic link) may
        # be followed
        self.path = path
        if not os.path.isabs(path):
            raise ValueError, "Path %r is not absolute" % path
        if os.path.islink(path) and not follow_symlinks:
            raise errors.TraversalError(private_msg="Path %r is a symlink"
                                        % path)

        # Specify the Content-Type and encoding of the file
        (mtype, enc) = mimetypes.guess_type(os.path.basename(path),strict=0)
        self.mime_type = mime_type or mtype or 'text/plain'
        self.encoding = encoding or enc or None

    def __call__(self, request):
        # Set the response headers and return the file's contents.
        request.response.set_content_type(self.mime_type)
        if self.encoding:
            request.response.set_header("Content-Encoding", self.encoding)
        fsfile = open(self.path, 'rb')
        contents = fsfile.read()
        fsfile.close()
        return contents

--------- end -------------


reply