diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2019-06-18 01:40:44 -0700 |
---|---|---|
committer | Carlton Gibson <carlton@noumenal.es> | 2019-06-20 11:48:49 +0200 |
commit | cce47ff65a4dd3786c049ec14ee889e128ca7de9 (patch) | |
tree | a2cb518fe4919ce8038b95d2d6ebe070bdd532ec /tests/responses | |
parent | 533311782fd0c974208490ec9d11da3bbe179dea (diff) | |
download | django-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.py | 49 |
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) |