diff options
author | ianb <devnull@localhost> | 2007-02-01 03:40:28 +0000 |
---|---|---|
committer | ianb <devnull@localhost> | 2007-02-01 03:40:28 +0000 |
commit | a5b2744a4d344d7c00d699f77974e6b9b809915e (patch) | |
tree | 0a59041e36087f4f5bf8496ddbd0f78cd45ab4d3 | |
parent | abfca84b011f8b36132b67f55cb0a19f855147ae (diff) | |
download | paste-1.2.tar.gz |
Fix for FileApp replying to non-GET requests, and giving the body for HEAD requests1.2
-rw-r--r-- | docs/news.txt | 5 | ||||
-rw-r--r-- | paste/fileapp.py | 18 | ||||
-rw-r--r-- | tests/test_fileapp.py | 12 |
3 files changed, 33 insertions, 2 deletions
diff --git a/docs/news.txt b/docs/news.txt index afd59e8..965b301 100644 --- a/docs/news.txt +++ b/docs/news.txt @@ -6,6 +6,11 @@ News svn trunk --------- +* **Backward incompatible change**: ``paste.fileapp.FileApp`` properly + supports request methods, including HEAD. If you were subclassing + ``FileApp`` or ``DataApp`` and overriding ``__call__()`` you may have + to subclass ``get()`` instead. + * paste.httpheaders now parses the HTTP Accept-Language header and returns a list of languages the browser supports in the order it prefers them. diff --git a/paste/fileapp.py b/paste/fileapp.py index 9e46b8b..1180c0f 100644 --- a/paste/fileapp.py +++ b/paste/fileapp.py @@ -89,6 +89,15 @@ class DataApp(object): return self def __call__(self, environ, start_response): + method = environ['REQUEST_METHOD'].upper() + if method not in ('GET', 'HEAD'): + exc = HTTPMethodNotAllowed( + 'You cannot %s a file' % method, + headers=[('Allow', 'GET, HEAD')]) + return exc(environ, start_response) + return self.get(environ, start_response) + + def get(self, environ, start_response): headers = self.headers[:] current_etag = str(self.last_modified) ETAG.update(headers, current_etag) @@ -175,7 +184,8 @@ class FileApp(DataApp): # called LAST_MODIFIED.update(self.headers, time=self.last_modified) - def __call__(self, environ, start_response): + def get(self, environ, start_response): + is_head = environ['REQUEST_METHOD'].upper() == 'HEAD' if 'max-age=0' in CACHE_CONTROL(environ).lower(): self.update(force=True) # RFC 2616 13.2.6 else: @@ -193,11 +203,15 @@ class FileApp(DataApp): 'You are not permitted to view this file (%s)' % e) return exc.wsgi_application( environ, start_response) - retval = DataApp.__call__(self, environ, start_response) + retval = DataApp.get(self, environ, start_response) if isinstance(retval, list): # cached content, exception, or not-modified + if is_head: + return [''] return retval (lower, content_length) = retval + if is_head: + return [''] file.seek(lower) return _FileIter(file, size=content_length) diff --git a/tests/test_fileapp.py b/tests/test_fileapp.py index ef6e366..000028c 100644 --- a/tests/test_fileapp.py +++ b/tests/test_fileapp.py @@ -195,3 +195,15 @@ def test_file_cache(): status=304) res = app.get('/', headers={'If-Modified-Since': 'invalid date'}, status=400) + +def test_methods(): + from paste import fileapp + filename = os.path.join(os.path.dirname(__file__), + 'urlparser_data', 'secured.txt') + app = TestApp(fileapp.FileApp(filename)) + get_res = app.get('') + res = app.get('', extra_environ={'REQUEST_METHOD': 'HEAD'}) + assert res.headers == get_res.headers + assert not res.body + app.post('', status=405) # Method Not Allowed + |