comparison 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
comparison
equal deleted inserted replaced
552:9612cfc6455a 553:cc6f3dbe3048
1 import re
2 import os.path
3 import hashlib
4 import logging
5 import datetime
6 from werkzeug.wrappers import Response
7 from werkzeug.wsgi import wrap_file
8
9
10 logger = logging.getLogger(__name__)
11
12
13 def load_mimetype_map():
14 mimetype_map = {}
15 sep_re = re.compile(r'\s+')
16 path = os.path.join(os.path.dirname(__file__), 'mime.types')
17 with open(path, 'r') as f:
18 for line in f:
19 tokens = sep_re.split(line)
20 if len(tokens) > 1:
21 for t in tokens[1:]:
22 mimetype_map[t] = tokens[0]
23 return mimetype_map
24
25
26 def make_wrapped_file_response(environ, request, path):
27 logger.debug("Serving %s" % path)
28
29 # Check if we can return a 304 status code.
30 mtime = os.path.getmtime(path)
31 etag_str = '%s$$%s' % (path, mtime)
32 etag = hashlib.md5(etag_str.encode('utf8')).hexdigest()
33 if etag in request.if_none_match:
34 response = Response()
35 response.status_code = 304
36 return response
37
38 wrapper = wrap_file(environ, open(path, 'rb'))
39 response = Response(wrapper)
40 _, ext = os.path.splitext(path)
41 response.set_etag(etag)
42 response.last_modified = datetime.datetime.fromtimestamp(mtime)
43 response.mimetype = mimetype_map.get(
44 ext.lstrip('.'), 'text/plain')
45 response.direct_passthrough = True
46 return response
47
48
49 mimetype_map = load_mimetype_map()
50 content_type_map = {
51 'html': 'text/html',
52 'xml': 'text/xml',
53 'txt': 'text/plain',
54 'text': 'text/plain',
55 'css': 'text/css',
56 'xhtml': 'application/xhtml+xml',
57 'atom': 'application/atom+xml', # or 'text/xml'?
58 'rss': 'application/rss+xml', # or 'text/xml'?
59 'json': 'application/json'}
60