summaryrefslogtreecommitdiff
path: root/tests/responses
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2019-06-18 01:40:44 -0700
committerCarlton Gibson <carlton@noumenal.es>2019-06-20 11:48:49 +0200
commitcce47ff65a4dd3786c049ec14ee889e128ca7de9 (patch)
treea2cb518fe4919ce8038b95d2d6ebe070bdd532ec /tests/responses
parent533311782fd0c974208490ec9d11da3bbe179dea (diff)
downloaddjango-cce47ff65a4dd3786c049ec14ee889e128ca7de9.tar.gz
Fixed #30565 -- Closed HttpResponse when wsgi.file_wrapper closes file-like object.
Diffstat (limited to 'tests/responses')
-rw-r--r--tests/responses/test_fileresponse.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/responses/test_fileresponse.py b/tests/responses/test_fileresponse.py
index e77df4513a..a6bcb58466 100644
--- a/tests/responses/test_fileresponse.py
+++ b/tests/responses/test_fileresponse.py
@@ -80,3 +80,52 @@ class FileResponseTests(SimpleTestCase):
response['Content-Disposition'],
"attachment; filename*=utf-8''%E7%A5%9D%E6%82%A8%E5%B9%B3%E5%AE%89.odt"
)
+
+ def test_file_to_stream_closes_response(self):
+ # Closing file_to_stream calls FileResponse.close(), even when
+ # file-like object doesn't have a close() method.
+ class FileLike:
+ def read(self):
+ pass
+
+ class FileLikeWithClose(FileLike):
+ def __init__(self):
+ self.closed = False
+
+ def close(self):
+ self.closed = True
+
+ for filelike_cls in (FileLike, FileLikeWithClose):
+ with self.subTest(filelike_cls=filelike_cls.__name__):
+ filelike = filelike_cls()
+ response = FileResponse(filelike)
+ self.assertFalse(response.closed)
+ # Object with close() is added to the list of closable.
+ if hasattr(filelike, 'closed'):
+ self.assertEqual(response._closable_objects, [filelike])
+ else:
+ self.assertEqual(response._closable_objects, [])
+ file_to_stream = response.file_to_stream
+ file_to_stream.close()
+ if hasattr(filelike, 'closed'):
+ self.assertTrue(filelike.closed)
+ self.assertTrue(response.closed)
+
+ def test_file_to_stream_closes_response_on_error(self):
+ # Closing file_to_stream calls FileResponse.close(), even when
+ # closing file-like raises exceptions.
+ class FileLikeWithRaisingClose:
+ def read(self):
+ pass
+
+ def close(self):
+ raise RuntimeError()
+
+ filelike = FileLikeWithRaisingClose()
+ response = FileResponse(filelike)
+ self.assertFalse(response.closed)
+ self.assertEqual(response._closable_objects, [filelike])
+ file_to_stream = response.file_to_stream
+ with self.assertRaises(RuntimeError):
+ file_to_stream.close()
+ self.assertTrue(response.closed)