Just for the hell of it, here's my version of the static directory
publisher. It looks a lot like Hamish's, except that (1) it has an ugly
hack allowing the presentation of static files with all the LWN frobbery
around it, and (2) I don't let people sneak upward with "..". You can
still export the world (or a good chunk thereof) by mistake with a symbolic
link, though.
jon
Jonathan Corbet
Executive editor, LWN.net
corbet@lwn.net
#
# Publish a static directory.
#
# $Id: StaticPublisher.py,v 1.2 2002/05/23 16:36:16 corbet Exp $
#
import mimetypes, os.path
from quixote import errors
import presentation
from utils import *
class StaticPublisher:
_q_exports = [ ]
def __init__ (self, request, dir):
self.dir = dir
#
# We don't list the directory, just send them away.
#
def _q_index (self, request):
return request.response.redirect (GetRootPage ())
#
# Most stuff will go through here, where we move downward.
#
def _q_getname (self, request, component):
#
# No tricky stuff.
#
if component == '..' or component == '.':
raise errors.TraversalError ('Resource not found',
'None of that silliness')
#
# If this is a directory, we move down into it.
#
fullpath = self.dir + '/' + component
if os.path.isdir (fullpath):
return StaticPublisher (request, fullpath)
#
# If it's a file we publish it.
#
if os.path.isfile (fullpath):
return StaticFilePublisher (request, fullpath)
#
# Anything else we refuse to deal with.
#
raise errors.TraversalError ('Resource not found',
'Trying to publish something weird')
#
# Publish an individual file.
#
class StaticFilePublisher:
_q_exports = [ ]
def __init__ (self, request, fname):
self.file = open (fname, 'r')
self.mtype = mimetypes.guess_type (fname)[0]
self.lwn_content = None
if self.mtype is None:
if fname[-4:] == '.lwn':
self.lwn_content = 1
else:
self.mtype = 'text/plain'
def _q_index (self, request):
#
# If this is meant to be published in the full LWN frame,
# make it so.
#
if self.lwn_content:
return self.publish_lwn (request)
#
# Otherwise send it out direct.
#
request.response.set_header ('content-type', self.mtype)
return self.file.read ()
#
# Publish a file with all the LWN trappings. Since we're not
# a template file (not sure why) we need to do it the hard way.
#
def publish_lwn (self, request):
title = self.file.readline ()[:-1]
page = presentation.StandardPage (request)
ret = page.Header (title)
ret += self.file.read ()
return ret + page.Trailer ()