summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Glick <david@glicksoftware.com>2016-11-09 23:31:24 -0800
committerDavid Glick <david@glicksoftware.com>2016-11-09 23:31:24 -0800
commited06c68b7b622cf43dc09b0e475ad6c978ec3de4 (patch)
treea1d6243990f0f8b1bd6dc0af6bc3cd853a30d4f5
parent568ce319ef097f1e909398f9a5ec890e4de91601 (diff)
downloadpyramid-ed06c68b7b622cf43dc09b0e475ad6c978ec3de4.tar.gz
pyramid-ed06c68b7b622cf43dc09b0e475ad6c978ec3de4.tar.bz2
pyramid-ed06c68b7b622cf43dc09b0e475ad6c978ec3de4.zip
Avoid setting Content-Encoding header for static view responses.
This was causing clients to decode the content of gzipped files when downloading them. We discussed this on IRC and @mmerickel pointed out that it may be a goal in some cases to serve gzipped precompiled assets (i.e. CSS/Javascript) with this header. But that's a new feature that would require thought about how to specify which files to serve that way. And it can already be implemented for a project using a tween. This just aims to fix the existing use case of serving files for download.
-rw-r--r--CHANGES.txt5
-rw-r--r--pyramid/response.py25
-rw-r--r--pyramid/static.py12
-rw-r--r--pyramid/tests/test_static.py4
4 files changed, 32 insertions, 14 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 434557f89..e6a015736 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -97,6 +97,11 @@ Bug Fixes
from previous orders have executed.
See https://github.com/Pylons/pyramid/pull/2757
+- Fix static view to avoid setting the ``Content-Encoding`` response header
+ to an encoding guessed using Python's ``mimetypes`` module.
+ This was causing clients to decode the content of gzipped files
+ when downloading them.
+
Deprecations
------------
diff --git a/pyramid/response.py b/pyramid/response.py
index 892e5dfff..1d9daae7d 100644
--- a/pyramid/response.py
+++ b/pyramid/response.py
@@ -54,16 +54,7 @@ class FileResponse(Response):
def __init__(self, path, request=None, cache_max_age=None,
content_type=None, content_encoding=None):
if content_type is None:
- content_type, content_encoding = mimetypes.guess_type(
- path,
- strict=False
- )
- if content_type is None:
- content_type = 'application/octet-stream'
- # str-ifying content_type is a workaround for a bug in Python 2.7.7
- # on Windows where mimetypes.guess_type returns unicode for the
- # content_type.
- content_type = str(content_type)
+ content_type, content_encoding = _guess_type(path)
super(FileResponse, self).__init__(
conditional_response=True,
content_type=content_type,
@@ -180,3 +171,17 @@ def _get_response_factory(registry):
)
return response_factory
+
+
+def _guess_type(path):
+ content_type, content_encoding = mimetypes.guess_type(
+ path,
+ strict=False
+ )
+ if content_type is None:
+ content_type = 'application/octet-stream'
+ # str-ifying content_type is a workaround for a bug in Python 2.7.7
+ # on Windows where mimetypes.guess_type returns unicode for the
+ # content_type.
+ content_type = str(content_type)
+ return content_type, content_encoding
diff --git a/pyramid/static.py b/pyramid/static.py
index 0965be95c..31e500e70 100644
--- a/pyramid/static.py
+++ b/pyramid/static.py
@@ -32,7 +32,12 @@ from pyramid.httpexceptions import (
)
from pyramid.path import caller_package
-from pyramid.response import FileResponse
+
+from pyramid.response import (
+ _guess_type,
+ FileResponse,
+)
+
from pyramid.traversal import traversal_path_info
slash = text_('/')
@@ -134,7 +139,10 @@ class static_view(object):
if not exists(filepath):
raise HTTPNotFound(request.url)
- return FileResponse(filepath, request, self.cache_max_age)
+ content_type, content_encoding = _guess_type(filepath)
+ return FileResponse(
+ filepath, request, self.cache_max_age,
+ content_type, content_encoding=None)
def add_slash_redirect(self, request):
url = request.path_url + '/'
diff --git a/pyramid/tests/test_static.py b/pyramid/tests/test_static.py
index 2ca86bc44..2b200d72b 100644
--- a/pyramid/tests/test_static.py
+++ b/pyramid/tests/test_static.py
@@ -186,14 +186,14 @@ class Test_static_view_use_subpath_False(unittest.TestCase):
from pyramid.httpexceptions import HTTPNotFound
self.assertRaises(HTTPNotFound, inst, context, request)
- def test_resource_with_content_encoding(self):
+ def test_gz_resource_no_content_encoding(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest({'PATH_INFO':'/arcs.svg.tgz'})
context = DummyContext()
response = inst(context, request)
self.assertEqual(response.status, '200 OK')
self.assertEqual(response.content_type, 'application/x-tar')
- self.assertEqual(response.content_encoding, 'gzip')
+ self.assertEqual(response.content_encoding, None)
response.app_iter.close()
def test_resource_no_content_encoding(self):