diff options
author | Marcel Hellkamp <marc@gsites.de> | 2021-10-14 11:51:21 +0200 |
---|---|---|
committer | Marcel Hellkamp <marc@gsites.de> | 2021-10-14 11:51:21 +0200 |
commit | 1d47a75995a23358bbd54bb75638810d7050fe37 (patch) | |
tree | 90907e1f1d29d66de98e6d0fee622c427bfe0e7d | |
parent | 71bb933649ba009cd537c2e973519d6e024c02a2 (diff) | |
download | bottle-defnull-1350.tar.gz |
Fix #1350: Serve compresed files as is in static_file()defnull-1350
Do not instruct browsers to transparently uncompress gzipped files.
-rwxr-xr-x | bottle.py | 31 | ||||
-rwxr-xr-x | docs/changelog.rst | 2 |
2 files changed, 17 insertions, 16 deletions
@@ -2874,12 +2874,12 @@ def static_file(filename, root, ``If-None-Match``) are answered with ``304 Not Modified`` whenever possible. ``HEAD`` and ``Range`` requests (used by download managers to check or continue partial downloads) are also handled automatically. - """ root = os.path.join(os.path.abspath(root), '') filename = os.path.abspath(os.path.join(root, filename.strip('/\\'))) headers = headers.copy() if headers else {} + getenv = request.environ.get if not filename.startswith(root): return HTTPError(403, "Access denied.") @@ -2889,31 +2889,32 @@ def static_file(filename, root, return HTTPError(403, "You do not have permission to access this file.") if mimetype is True: - if download and download is not True: - mimetype, encoding = mimetypes.guess_type(download) - else: - mimetype, encoding = mimetypes.guess_type(filename) - if encoding: - headers['Content-Encoding'] = encoding + name = download if isinstance(download, str) else filename + mimetype, encoding = mimetypes.guess_type(fname) + if encoding == 'gzip': + mimetype = 'application/gzip' + elif encoding: # e.g. bzip2 -> application/x-bzip2 + mimetype = 'application/x-' + encoding + + if charset and mimetype and 'charset=' not in mimetype \ + and (mimetype[:5] == 'text/' or mimetype == 'application/javascript'): + mimetype += '; charset=%s' % charset if mimetype: - if (mimetype[:5] == 'text/' or mimetype == 'application/javascript')\ - and charset and 'charset' not in mimetype: - mimetype += '; charset=%s' % charset headers['Content-Type'] = mimetype + if download is True: + download = os.path.basename(filename) + if download: - download = os.path.basename(filename if download is True else download) + download = download.replace('"','') headers['Content-Disposition'] = 'attachment; filename="%s"' % download stats = os.stat(filename) headers['Content-Length'] = clen = stats.st_size - headers['Last-Modified'] = email.utils.formatdate(stats.st_mtime, - usegmt=True) + headers['Last-Modified'] = email.utils.formatdate(stats.st_mtime, usegmt=True) headers['Date'] = email.utils.formatdate(time.time(), usegmt=True) - getenv = request.environ.get - if etag is None: etag = '%d:%d:%d:%d:%s' % (stats.st_dev, stats.st_ino, stats.st_mtime, clen, filename) diff --git a/docs/changelog.rst b/docs/changelog.rst index 634de80..e0b3810 100755 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -73,11 +73,11 @@ These changes might require special care when updating. * :meth:`Bottle.mount` now recognizes instances of :class:`Bottle` and mounts them with significantly less overhead than other WSGI applications. * The :attr:`Request.json` property now accepts ``application/json-rpc`` requests. * :func:`static_file` gained support for ``ETag`` headers. It will generate ETags and recognizes ``If-None-Match`` headers. +* :func:`static_file` will now guess the mime type of ``*.gz`` and other compressed files correctly (e.g. ``application/gzip``) and NOT set the ``Content-Encoding`` header. * Jinja2 templates will produce better error messages than before. - Release 0.12 ============== |