SVN: r20964 - trunk/quixote
Andrew Kuchling <akuchlin-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Wed, 05 Mar 2003 13:36:46 -0500
| Newsgroups | gmane.comp.web.quixote.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: akuchlin
Date: 2003-03-05 13:36:45 -0500 (Wed, 05 Mar 2003)
New Revision: 20964
Modified:
trunk/quixote/util.py
Log:
Improve docstrings
Add mime_type argument to StaticFile constructor
Use htmltext() to avoid XSS in directory listing
Modified: trunk/quixote/util.py
==============================================================================
--- trunk/quixote/util.py (original)
+++ trunk/quixote/util.py 2003-03-05 13:36:46.000000000 -0500
@@ -17,7 +17,8 @@
__revision__ = "$Id$"
import sys, xmlrpclib
-import quixote, os, mimetypes, cgi, email, urllib
+import os, mimetypes, cgi, email, urllib
+from quixote import errors, html
from cStringIO import StringIO
def xmlrpc (request, func):
@@ -61,35 +62,40 @@
"""
Wrapper for a static file on the filesystem.
-
- An instance is initialized with the absolute path to the file and
- optionally flags indicating whether the file's content should be cached
- and whether a symbolic link should be followed. The instance can then
- be called with a request object, so behaving like any Quixote object
- that models a resource.
"""
- def __init__(self, path, use_cache=0, follow_symlinks=0):
-
- # Check that the supplied path is absolute and (if a symbolic link) may
+ def __init__(self, path, use_cache=0, follow_symlinks=0,
+ mime_type=None):
+ """StaticFile(path:string, use_cache:bool, follow_symlinks:bool)
+
+ Initialize instance with the absolute path to the file.
+ If 'use_cache' is true, the file's contents will be cached in memory.
+ 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.
+ """
+
+ # Check that the supplied path is absolute and (if a symbolic link) may
# be followed
self.path = path
- assert os.path.isabs(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 quixote.errors.TraversalError
+ raise errors.TraversalError(private_msg="Path %r is a symlink"
+ % path)
self.use_cache = use_cache
self.cache = None
# Decide the Content-Type of the file
- self.mimetype = \
+ self.mime_type = mime_type or \
mimetypes.guess_type(os.path.basename(path), strict=0)[0] \
or 'text/plain'
def __call__(self, request):
# Set the Content-Type for the response and return the file's contents;
# use caching if enabled.
- request.response.set_header('Content-Type', self.mimetype)
+ request.response.set_header('Content-Type', self.mime_type)
if self.cache:
contents = self.cache
else:
@@ -105,19 +111,24 @@
"""
Wrap a filesystem folder containing static files as a Quixote namespace.
-
- An instance is initialized with the absolute path to the folder and
- optionally flags indicating whether items within the folder should be
- cached and whether symbolic links should be followed.
"""
_q_exports = []
def __init__(self, path, use_cache=0, list_folder=0, follow_symlinks=0):
+ """StaticFilesFolder(path:string, use_cache:bool,
+ list_folder:bool, follow_symlinks:bool)
+
+ Initialize instance with the absolute path to the file.
+ If 'use_cache' is true, the file's content will be cached in memory.
+ If 'list_folder' is true, users can request a directory listing.
+ If 'follow_symlinks' is true, symbolic links will be followed.
+ """
# Check that the supplied path is absolute
self.path = path
- assert os.path.isabs(path)
+ if not os.path.isabs(path):
+ raise ValueError, "Path %r is not absolute" % path
self.use_cache = use_cache
self.cache = {}
@@ -132,8 +143,9 @@
"""
out = StringIO()
if self.list_folder:
- template = '<a href="%s">%s</a>%s'
- print >>out, "<h1>%s</h1>" % request.environ['REQUEST_URI']
+ template = html.htmltext('<a href="%s">%s</a>%s')
+ print >>out, (html.htmltext("<h1>%s</h1>")
+ % request.environ['REQUEST_URI'])
print >>out, "<pre>"
print >>out, template % ('..', '..', '')
for filename in os.listdir(self.path):
@@ -154,7 +166,7 @@
or StaticFilesFolder wrapper of it; use caching if that is in use.
"""
if name in ('.', '..'):
- raise quixote.errors.TraversalError
+ raise errors.TraversalError(private_msg="Attempt to use '.', '..'")
if self.cache.has_key(name):
# Get item from cache
item = self.cache[name]
@@ -162,7 +174,7 @@
# Get item from filesystem; cache it if caching is in use.
item_filepath = os.path.join(self.path, name)
if os.path.islink(item_filepath) and not self.follow_symlinks:
- raise quixote.errors.TraversalError
+ raise errors.TraversalError
if os.path.isdir(item_filepath):
item = StaticFilesFolder(item_filepath, self.use_cache,
self.list_folder, self.follow_symlinks)
@@ -170,7 +182,7 @@
item = StaticFile(item_filepath, self.use_cache,
self.follow_symlinks)
else:
- raise quixote.errors.TraversalError
+ raise errors.TraversalError
if self.use_cache:
self.cache[name] = item
if isinstance(item, StaticFilesFolder):
@@ -227,7 +239,7 @@
assert not os.path.islink(self.filepath) or self.follow_symlinks
scriptfile = open(self.filepath)
except AssertionError, IOError:
- raise quixote.errors.TraversalError
+ raise errors.TraversalError
code = compile(scriptfile.read(), self.filepath, 'exec')
scriptfile.close()
if self.use_cache: