annotate piecrust/serving/util.py @ 553:cc6f3dbe3048

serve: Extract some of the server's functionality into WSGI middlewares.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 08 Aug 2015 22:01:47 -0700
parents
children daf8df5ade7d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
553
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 import re
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
2 import os.path
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
3 import hashlib
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
4 import logging
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
5 import datetime
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
6 from werkzeug.wrappers import Response
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
7 from werkzeug.wsgi import wrap_file
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
10 logger = logging.getLogger(__name__)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
11
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
12
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
13 def load_mimetype_map():
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
14 mimetype_map = {}
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
15 sep_re = re.compile(r'\s+')
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
16 path = os.path.join(os.path.dirname(__file__), 'mime.types')
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17 with open(path, 'r') as f:
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
18 for line in f:
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
19 tokens = sep_re.split(line)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
20 if len(tokens) > 1:
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
21 for t in tokens[1:]:
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
22 mimetype_map[t] = tokens[0]
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23 return mimetype_map
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
24
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
25
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
26 def make_wrapped_file_response(environ, request, path):
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
27 logger.debug("Serving %s" % path)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
28
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
29 # Check if we can return a 304 status code.
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
30 mtime = os.path.getmtime(path)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
31 etag_str = '%s$$%s' % (path, mtime)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
32 etag = hashlib.md5(etag_str.encode('utf8')).hexdigest()
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
33 if etag in request.if_none_match:
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
34 response = Response()
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
35 response.status_code = 304
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
36 return response
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
37
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
38 wrapper = wrap_file(environ, open(path, 'rb'))
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
39 response = Response(wrapper)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
40 _, ext = os.path.splitext(path)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
41 response.set_etag(etag)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
42 response.last_modified = datetime.datetime.fromtimestamp(mtime)
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
43 response.mimetype = mimetype_map.get(
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
44 ext.lstrip('.'), 'text/plain')
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
45 response.direct_passthrough = True
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
46 return response
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
47
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
48
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
49 mimetype_map = load_mimetype_map()
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
50 content_type_map = {
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
51 'html': 'text/html',
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
52 'xml': 'text/xml',
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
53 'txt': 'text/plain',
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
54 'text': 'text/plain',
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
55 'css': 'text/css',
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
56 'xhtml': 'application/xhtml+xml',
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
57 'atom': 'application/atom+xml', # or 'text/xml'?
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
58 'rss': 'application/rss+xml', # or 'text/xml'?
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
59 'json': 'application/json'}
cc6f3dbe3048 serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
60