Mercurial > hg > FileServer
comparison fileserver/web.py @ 0:8d31e36f084e
initial stubbing
| author | Jeff Hammel <jhammel@mozilla.com> |
|---|---|
| date | Wed, 29 Feb 2012 13:09:11 -0800 |
| parents | |
| children | 89d4f742ed1a |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:8d31e36f084e |
|---|---|
| 1 #!/usr/bin/env python | |
| 2 | |
| 3 """ | |
| 4 WSGI app for FileServer | |
| 5 | |
| 6 Reference: | |
| 7 - http://docs.webob.org/en/latest/file-example.html | |
| 8 """ | |
| 9 | |
| 10 import mimetypes | |
| 11 import os | |
| 12 from webob import Request, Response, exc | |
| 13 | |
| 14 def get_mimetype(filename): | |
| 15 type, encoding = mimetypes.guess_type(filename) | |
| 16 # We'll ignore encoding, even though we shouldn't really | |
| 17 return type or 'application/octet-stream' | |
| 18 | |
| 19 def file_response(filename): | |
| 20 res = Response(content_type=get_mimetype(filename)) | |
| 21 res.body = open(filename, 'rb').read() | |
| 22 return res | |
| 23 | |
| 24 class FileApp(object): | |
| 25 """ | |
| 26 serve static files | |
| 27 """ | |
| 28 | |
| 29 def __init__(self, filename): | |
| 30 self.filename = filename | |
| 31 | |
| 32 def __call__(self, environ, start_response): | |
| 33 res = file_response(self.filename) | |
| 34 return res(environ, start_response) | |
| 35 | |
| 36 class DirectoryServer(object): | |
| 37 | |
| 38 def __init__(self, directory): | |
| 39 assert os.path.exists(directory), "'%s' does not exist" % directory | |
| 40 assert os.path.isdir(directory), "'%s' is not a directory" % directory | |
| 41 self.directory = directory | |
| 42 | |
| 43 @staticmethod | |
| 44 def normpath(path): | |
| 45 return os.path.normcase(os.path.abspath(path)) | |
| 46 | |
| 47 def __call__(self, environ, start_response): | |
| 48 request = Request(environ) | |
| 49 # TODO method_not_allowed: Allow: GET, HEAD | |
| 50 path_info = request.path_info | |
| 51 if not path_info: | |
| 52 pass # self.add slash | |
| 53 full = self.normpath(os.path.join(self.directory, path_info.strip('/'))) | |
| 54 if not full.startswith(self.directory): | |
| 55 # Out of bounds | |
| 56 return exc.HTTPNotFound()(environ, start_response) | |
| 57 if not os.path.exists(full): | |
| 58 return exc.HTTPNotFound()(environ, start_response) | |
| 59 | |
| 60 if os.path.isdir(full): | |
| 61 # serve directory index | |
| 62 if not path_info.endswith('/'): | |
| 63 return self.add_slash(environ, start_response) | |
| 64 index = self.index(full) | |
| 65 response_headers = [('Content-Type', 'text/html'), | |
| 66 ('Content-Length', str(len(index)))] | |
| 67 response = Response(index, content_type='text/html') | |
| 68 return response(environ, start_response) | |
| 69 | |
| 70 # serve file | |
| 71 if path_info.endswith('/'): | |
| 72 # we create the `full` filename above by stripping off | |
| 73 # '/' from both sides; so we correct here | |
| 74 return exc.HTTPNotFound()(environ, start_response) | |
| 75 response = file_response(full) | |
| 76 return response(environ, start_response) | |
| 77 | |
| 78 if __name__ == '__main__': | |
| 79 from wsgiref import simple_server | |
| 80 app = Handler() | |
| 81 server = simple_server.make_server(host='0.0.0.0', port=8080, app=app) | |
| 82 server.serve_forever() |
