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