From 2506c0b9a96d48f14624acfa552fc88e38a542ae Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Sat, 8 Feb 2014 17:45:09 +0000 Subject: [PATCH 1/3] Fixed sending etags for file streams with a name. This fixes #930. --- CHANGES | 1 + flask/helpers.py | 21 +++++++++++++-------- flask/testsuite/helpers.py | 11 +++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 0737c590..8b76c5fc 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,7 @@ Version 0.10.2 - Fixed an issue with query parameters getting removed from requests in the test client when absolute URLs were requested. - Made `@before_first_request` into a decorator as intended. +- Fixed an etags bug when sending a file without a name. Version 0.10.1 -------------- diff --git a/flask/helpers.py b/flask/helpers.py index c71da85b..7b69b63c 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -538,14 +538,19 @@ def send_file(filename_or_fp, mimetype=None, as_attachment=False, rv.expires = int(time() + cache_timeout) if add_etags and filename is not None: - rv.set_etag('flask-%s-%s-%s' % ( - os.path.getmtime(filename), - os.path.getsize(filename), - adler32( - filename.encode('utf-8') if isinstance(filename, text_type) - else filename - ) & 0xffffffff - )) + try: + rv.set_etag('flask-%s-%s-%s' % ( + os.path.getmtime(filename), + os.path.getsize(filename), + adler32( + filename.encode('utf-8') if isinstance(filename, text_type) + else filename + ) & 0xffffffff + )) + except OSError: + warn('Access %s failed, maybe it does not exist, so ignore etags in ' + 'headers' % filename, stacklevel=2) + if conditional: rv = rv.make_conditional(request) # make sure we don't send x-sendfile for servers that diff --git a/flask/testsuite/helpers.py b/flask/testsuite/helpers.py index 518d9384..c645dc14 100644 --- a/flask/testsuite/helpers.py +++ b/flask/testsuite/helpers.py @@ -264,6 +264,17 @@ class SendfileTestCase(FlaskTestCase): rv.close() # etags self.assert_equal(len(captured), 1) + with catch_warnings() as captured: + from StringIO import StringIO as PYStringIO + f = PYStringIO('Test') + f.name = 'test.txt' + rv = flask.send_file(f) + rv.direct_passthrough = False + self.assert_equal(rv.data, b'Test') + self.assert_equal(rv.mimetype, 'text/plain') + rv.close() + # attachment_filename and etags + self.assert_equal(len(captured), 3) with catch_warnings() as captured: f = StringIO('Test') rv = flask.send_file(f, mimetype='text/plain') From e67d9a04b2f5ccd16ed6bd62b1d5ca1526bbf0ab Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Sat, 8 Feb 2014 17:46:02 +0000 Subject: [PATCH 2/3] Fixed a changelog entry --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 8b76c5fc..b66432af 100644 --- a/CHANGES +++ b/CHANGES @@ -17,7 +17,7 @@ Version 0.10.2 - Fixed an issue with query parameters getting removed from requests in the test client when absolute URLs were requested. - Made `@before_first_request` into a decorator as intended. -- Fixed an etags bug when sending a file without a name. +- Fixed an etags bug when sending a file streams with a name. Version 0.10.1 -------------- From d094d5b6fc86a26680a8c496f719c4d711fcd766 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Sat, 8 Feb 2014 22:29:46 +0000 Subject: [PATCH 3/3] Fixed warning and broken tests on 3.3 --- flask/testsuite/helpers.py | 5 +++-- flask/testsuite/testing.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/flask/testsuite/helpers.py b/flask/testsuite/helpers.py index c645dc14..b765528b 100644 --- a/flask/testsuite/helpers.py +++ b/flask/testsuite/helpers.py @@ -265,8 +265,9 @@ class SendfileTestCase(FlaskTestCase): # etags self.assert_equal(len(captured), 1) with catch_warnings() as captured: - from StringIO import StringIO as PYStringIO - f = PYStringIO('Test') + class PyStringIO(StringIO): + pass + f = PyStringIO('Test') f.name = 'test.txt' rv = flask.send_file(f) rv.direct_passthrough = False diff --git a/flask/testsuite/testing.py b/flask/testsuite/testing.py index de78746b..11ab763b 100644 --- a/flask/testsuite/testing.py +++ b/flask/testsuite/testing.py @@ -207,8 +207,8 @@ class TestToolsTestCase(FlaskTestCase): with app.test_client() as c: rv = c.post('http://domain.com/action?vodka=42', data={'gin': 43}) self.assert_equal(rv.status_code, 200) - self.assert_('gin' in flask.request.form) - self.assert_('vodka' in flask.request.args) + self.assert_true('gin' in flask.request.form) + self.assert_true('vodka' in flask.request.args) class SubdomainTestCase(FlaskTestCase):