Merge branch 'fix/wrongEtagForDownloads' into devel
This commit is contained in:
commit
b458759159
2 changed files with 31 additions and 8 deletions
|
|
@ -332,13 +332,29 @@ class Server(object):
|
|||
|
||||
upload_suffixes = dict(name=s.get(["server", "uploads", "nameSuffix"]), path=s.get(["server", "uploads", "pathSuffix"]))
|
||||
|
||||
download_handler_kwargs = dict(
|
||||
as_attachment=True,
|
||||
allow_client_caching=False
|
||||
)
|
||||
admin_validator = dict(access_validation=util.tornado.access_validation_factory(app, loginManager, util.flask.user_validator))
|
||||
no_hidden_files_validator = dict(path_validation=util.tornado.path_validation_factory(lambda path: not os.path.basename(path).startswith("."), status_code=404))
|
||||
|
||||
def joined_dict(*dicts):
|
||||
if not len(dicts):
|
||||
return dict()
|
||||
|
||||
joined = dict()
|
||||
for d in dicts:
|
||||
joined.update(d)
|
||||
return joined
|
||||
|
||||
server_routes = self._router.urls + [
|
||||
# various downloads
|
||||
(r"/downloads/timelapse/([^/]*\.mpg)", util.tornado.LargeResponseHandler, dict(path=s.getBaseFolder("timelapse"), as_attachment=True)),
|
||||
(r"/downloads/files/local/(.*)", util.tornado.LargeResponseHandler, dict(path=s.getBaseFolder("uploads"), as_attachment=True, path_validation=util.tornado.path_validation_factory(lambda path: not os.path.basename(path).startswith("."), status_code=404))),
|
||||
(r"/downloads/logs/([^/]*)", util.tornado.LargeResponseHandler, dict(path=s.getBaseFolder("logs"), as_attachment=True, access_validation=util.tornado.access_validation_factory(app, loginManager, util.flask.admin_validator))),
|
||||
(r"/downloads/timelapse/([^/]*\.mpg)", util.tornado.LargeResponseHandler, joined_dict(dict(path=s.getBaseFolder("timelapse")), download_handler_kwargs, no_hidden_files_validator)),
|
||||
(r"/downloads/files/local/(.*)", util.tornado.LargeResponseHandler, joined_dict(dict(path=s.getBaseFolder("uploads")), download_handler_kwargs, no_hidden_files_validator)),
|
||||
(r"/downloads/logs/([^/]*)", util.tornado.LargeResponseHandler, joined_dict(dict(path=s.getBaseFolder("logs")), download_handler_kwargs, admin_validator)),
|
||||
# camera snapshot
|
||||
(r"/downloads/camera/current", util.tornado.UrlForwardHandler, dict(url=s.get(["webcam", "snapshot"]), as_attachment=True, access_validation=util.tornado.access_validation_factory(app, loginManager, util.flask.user_validator))),
|
||||
(r"/downloads/camera/current", util.tornado.UrlProxyHandler, dict(url=s.get(["webcam", "snapshot"]), as_attachment=True, access_validation=util.tornado.access_validation_factory(app, loginManager, util.flask.user_validator))),
|
||||
# generated webassets
|
||||
(r"/static/webassets/(.*)", util.tornado.LargeResponseHandler, dict(path=os.path.join(s.getBaseFolder("generated"), "webassets")))
|
||||
]
|
||||
|
|
|
|||
|
|
@ -768,6 +768,8 @@ class LargeResponseHandler(tornado.web.StaticFileHandler):
|
|||
:class:``~tornado.web.StaticFileHandler`` as the ``default_filename`` keyword parameter). Defaults to ``None``.
|
||||
as_attachment (bool): Whether to serve requested files with ``Content-Disposition: attachment`` header (``True``)
|
||||
or not. Defaults to ``False``.
|
||||
allow_client_caching (bool): Whether to allow the client to cache (by not setting any ``Cache-Control`` or
|
||||
``Expires`` headers on the response) or not.
|
||||
access_validation (function): Callback to call in the ``get`` method to validate access to the resource. Will
|
||||
be called with ``self.request`` as parameter which contains the full tornado request object. Should raise
|
||||
a ``tornado.web.HTTPError`` if access is not allowed in which case the request will not be further processed.
|
||||
|
|
@ -782,10 +784,11 @@ class LargeResponseHandler(tornado.web.StaticFileHandler):
|
|||
by ``get_content_version``.
|
||||
"""
|
||||
|
||||
def initialize(self, path, default_filename=None, as_attachment=False,
|
||||
def initialize(self, path, default_filename=None, as_attachment=False, allow_client_caching=True,
|
||||
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._allow_client_caching = allow_client_caching
|
||||
self._access_validation = access_validation
|
||||
self._path_validation = path_validation
|
||||
self._etag_generator = etag_generator
|
||||
|
|
@ -802,6 +805,10 @@ class LargeResponseHandler(tornado.web.StaticFileHandler):
|
|||
if self._as_attachment:
|
||||
self.set_header("Content-Disposition", "attachment")
|
||||
|
||||
if not self._allow_client_caching:
|
||||
self.set_header("Cache-Control", "max-age=0, must-revalidate, private")
|
||||
self.set_header("Expires", "-1")
|
||||
|
||||
def compute_etag(self):
|
||||
if self._etag_generator is not None:
|
||||
return self._etag_generator(self)
|
||||
|
|
@ -817,7 +824,7 @@ class LargeResponseHandler(tornado.web.StaticFileHandler):
|
|||
##~~ URL Forward Handler for forwarding requests to a preconfigured static URL
|
||||
|
||||
|
||||
class UrlForwardHandler(tornado.web.RequestHandler):
|
||||
class UrlProxyHandler(tornado.web.RequestHandler):
|
||||
"""
|
||||
`tornado.web.RequestHandler <http://tornado.readthedocs.org/en/branch4.0/web.html#request-handlers>`_ that proxies
|
||||
requests to a preconfigured url and returns the response. Allows delivery of the requested content as attachment
|
||||
|
|
@ -827,7 +834,7 @@ class UrlForwardHandler(tornado.web.RequestHandler):
|
|||
for making the request to the configured endpoint and return the body of the client response with the status code
|
||||
from the client response and the following headers:
|
||||
|
||||
* ``Date``, ``Cache-Control``, ``Server``, ``Content-Type`` and ``Location`` will be copied over.
|
||||
* ``Date``, ``Cache-Control``, ``Expires``, ``ETag``, ``Server``, ``Content-Type`` and ``Location`` will be copied over.
|
||||
* If ``as_attachment`` is set to True, ``Content-Disposition`` will be set to ``attachment``. If ``basename`` is
|
||||
set including the attachement's ``filename`` attribute will be set to the base name followed by the extension
|
||||
guessed based on the MIME type from the ``Content-Type`` header of the response. If no extension can be guessed
|
||||
|
|
@ -877,7 +884,7 @@ class UrlForwardHandler(tornado.web.RequestHandler):
|
|||
filename = None
|
||||
|
||||
self.set_status(response.code)
|
||||
for name in ("Date", "Cache-Control", "Server", "Content-Type", "Location"):
|
||||
for name in ("Date", "Cache-Control", "Server", "Content-Type", "Location", "Expires", "ETag"):
|
||||
value = response.headers.get(name)
|
||||
if value:
|
||||
self.set_header(name, value)
|
||||
|
|
|
|||
Loading…
Reference in a new issue