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 ()