diff options
| author | Chris McDonough <chrism@plope.com> | 2012-01-16 15:31:17 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2012-01-16 15:31:17 -0500 |
| commit | 83086463eb6f129fe7d02d90b866eb6780581da2 (patch) | |
| tree | fc56780313e929b34847ede44870194022c13887 | |
| parent | b20d68703af695c80e7844e8aae61ccf31cedaaa (diff) | |
| download | pyramid-83086463eb6f129fe7d02d90b866eb6780581da2.tar.gz pyramid-83086463eb6f129fe7d02d90b866eb6780581da2.tar.bz2 pyramid-83086463eb6f129fe7d02d90b866eb6780581da2.zip | |
- Responses generated by Pyramid's ``static_view`` now use
a ``wsgi.file_wrapper`` (see
http://www.python.org/dev/peps/pep-0333/#optional-platform-specific-file-handling)
when one is provided by the web server.
| -rw-r--r-- | CHANGES.txt | 5 | ||||
| -rw-r--r-- | pyramid/static.py | 34 | ||||
| -rw-r--r-- | pyramid/tests/test_static.py | 16 |
3 files changed, 35 insertions, 20 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index a755f6418..fc7fc1cab 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,11 @@ Features This method provides conflict detection and is the suggested way to add properties to a request. +- Responses generated by Pyramid's ``static_view`` now use + a ``wsgi.file_wrapper`` (see + http://www.python.org/dev/peps/pep-0333/#optional-platform-specific-file-handling) + when one is provided by the web server. + 1.3a5 (2012-01-09) ================== diff --git a/pyramid/static.py b/pyramid/static.py index 61ee67573..b82bc1bc4 100644 --- a/pyramid/static.py +++ b/pyramid/static.py @@ -47,11 +47,13 @@ def init_mimetypes(mimetypes): # has been applied on the Python 2 trunk). init_mimetypes(mimetypes) +_BLOCK_SIZE = 4096 * 64 # 256K + class _FileResponse(Response): """ Serves a static filelike object. """ - def __init__(self, path, cache_max_age): + def __init__(self, path, cache_max_age, request): super(_FileResponse, self).__init__(conditional_response=True) self.last_modified = getmtime(path) content_type, content_encoding = mimetypes.guess_type(path, @@ -61,34 +63,26 @@ class _FileResponse(Response): self.content_type = content_type self.content_encoding = content_encoding content_length = getsize(path) - self.app_iter = _FileIter(open(path, 'rb'), content_length) + f = open(path, 'rb') + environ = request.environ + if 'wsgi.file_wrapper' in environ: + app_iter = environ['wsgi.file_wrapper'](f, _BLOCK_SIZE) + else: + app_iter = _FileIter(open(path, 'rb')) + self.app_iter = app_iter # assignment of content_length must come after assignment of app_iter self.content_length = content_length if cache_max_age is not None: self.cache_expires = cache_max_age class _FileIter(object): - block_size = 4096 * 64 # (256K) + block_size = _BLOCK_SIZE - def __init__(self, file, size=None): + def __init__(self, file): self.file = file - self.size = size def __iter__(self): - return self - - def next(self): - chunk_size = self.block_size - if self.size is not None: - if chunk_size > self.size: - chunk_size = self.size - self.size -= chunk_size - data = self.file.read(chunk_size) - if not data: - raise StopIteration - return data - - __next__ = next # py3 + return iter(lambda: self.file.read(self.block_size), b'') def close(self): self.file.close() @@ -186,7 +180,7 @@ class static_view(object): if not exists(filepath): return HTTPNotFound(request.url) - return _FileResponse(filepath ,self.cache_max_age) + return _FileResponse(filepath ,self.cache_max_age, request) 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 bd2c2adef..4edd2728e 100644 --- a/pyramid/tests/test_static.py +++ b/pyramid/tests/test_static.py @@ -112,6 +112,22 @@ class Test_static_view_use_subpath_False(unittest.TestCase): response = inst(context, request) self.assertTrue(b'<html>static</html>' in response.body) + def test_resource_is_file_with_wsgi_file_wrapper(self): + from pyramid.static import _BLOCK_SIZE + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/index.html'}) + class _Wrapper(object): + def __init__(self, file, block_size=None): + self.file = file + self.block_size = block_size + request.environ['wsgi.file_wrapper'] = _Wrapper + context = DummyContext() + response = inst(context, request) + app_iter = response.app_iter + self.assertTrue(isinstance(app_iter, _Wrapper)) + self.assertTrue(b'<html>static</html>' in app_iter.file.read()) + self.assertEqual(app_iter.block_size, _BLOCK_SIZE) + def test_resource_is_file_with_cache_max_age(self): inst = self._makeOne('pyramid.tests:fixtures/static', cache_max_age=600) request = self._makeRequest({'PATH_INFO':'/index.html'}) |
