Fix: LargeResponseHandler was wrongly caching ETag value
ETag values returned with download responses were cached internally within the LargeResponseHandler class, with the file's path as key. That let to problems once the content changed and hence the ETag value actually becoming invalid. Since the path however stayed the same, the same ETag value for the modified file was assumed and a 304 Not Modified response was generated. This patch changes the behaviour of LargeResponseHandler to use the last modified date of the file as the ETag value and alternatively allowing an etag generator function to be provided as constructor parameter as well to use for calculating (or disabling) the ETag header dependant on the situation.
This commit is contained in:
parent
45c92cb1f4
commit
637adc3095
1 changed files with 13 additions and 1 deletions
|
|
@ -776,13 +776,19 @@ class LargeResponseHandler(tornado.web.StaticFileHandler):
|
|||
with the requested path as parameter. Should raise a ``tornado.web.HTTPError`` (e.g. an 404) if the requested
|
||||
path does not pass validation in which case the request will not be further processed.
|
||||
Defaults to ``None`` and hence no path validation being performed.
|
||||
etag_generator (function): Callback to call for generating the value of the ETag response header. Will be
|
||||
called with the response handler as parameter. May return ``None`` to prevent the ETag response header
|
||||
from being set. If not provided the last modified time of the file in question will be used as returned
|
||||
by ``get_content_version``.
|
||||
"""
|
||||
|
||||
def initialize(self, path, default_filename=None, as_attachment=False, access_validation=None, path_validation=None):
|
||||
def initialize(self, path, default_filename=None, as_attachment=False,
|
||||
access_validation=None, path_validation=None, etag_generator=None):
|
||||
tornado.web.StaticFileHandler.initialize(self, os.path.abspath(path), default_filename)
|
||||
self._as_attachment = as_attachment
|
||||
self._access_validation = access_validation
|
||||
self._path_validation = path_validation
|
||||
self._etag_generator = etag_generator
|
||||
|
||||
def get(self, path, include_body=True):
|
||||
if self._access_validation is not None:
|
||||
|
|
@ -796,6 +802,12 @@ class LargeResponseHandler(tornado.web.StaticFileHandler):
|
|||
if self._as_attachment:
|
||||
self.set_header("Content-Disposition", "attachment")
|
||||
|
||||
def compute_etag(self):
|
||||
if self._etag_generator is not None:
|
||||
return self._etag_generator(self)
|
||||
else:
|
||||
return self.get_content_version(self.absolute_path)
|
||||
|
||||
@classmethod
|
||||
def get_content_version(cls, abspath):
|
||||
import os
|
||||
|
|
|
|||
Loading…
Reference in a new issue