Mercurial > piecrust2
changeset 258:7ec06ec14247
serve: Use Etags and 304 responses for assets.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 22 Feb 2015 22:02:59 -0800 |
parents | e6ae65212c32 |
children | adb066ffb363 |
files | piecrust/serving.py |
diffstat | 1 files changed, 17 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/piecrust/serving.py Sun Feb 22 22:02:28 2015 -0800 +++ b/piecrust/serving.py Sun Feb 22 22:02:59 2015 -0800 @@ -8,6 +8,7 @@ import os.path import hashlib import logging +import datetime import threading from werkzeug.exceptions import ( NotFound, MethodNotAllowed, InternalServerError, HTTPException) @@ -169,7 +170,7 @@ full_path = os.path.join(mount, rel_req_path) try: response = self._make_wrapped_file_response( - environ, full_path) + environ, request, full_path) return response except OSError: pass @@ -202,7 +203,7 @@ try: response = self._make_wrapped_file_response( - environ, full_path) + environ, request, full_path) return response except OSError: pass @@ -216,7 +217,7 @@ if not os.path.isfile(full_path): return None - return self._make_wrapped_file_response(environ, full_path) + return self._make_wrapped_file_response(environ, request, full_path) def _try_serve_page(self, app, environ, request): # Try to find what matches the requested URL. @@ -352,11 +353,23 @@ return response - def _make_wrapped_file_response(self, environ, path): + def _make_wrapped_file_response(self, environ, request, path): logger.debug("Serving %s" % path) + + # Check if we can return a 304 status code. + mtime = os.path.getmtime(path) + etag_str = '%s$$%s' % (path, mtime) + etag = hashlib.md5(etag_str.encode('utf8')).hexdigest() + if etag in request.if_none_match: + response = Response() + response.status_code = 304 + return response + wrapper = wrap_file(environ, open(path, 'rb')) response = Response(wrapper) _, ext = os.path.splitext(path) + response.set_etag(etag) + response.last_modified = datetime.datetime.fromtimestamp(mtime) response.mimetype = self._mimetype_map.get( ext.lstrip('.'), 'text/plain') return response