From de66b56790598f2ff97b8df859356d755ce64e20 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 1 Jun 2013 10:26:46 +0200 Subject: [PATCH] Fixed #18481 -- Wrapped request.FILES read error in UnreadablePostError MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks KyleMac for the report, André Cruz for the initial patch and Hiroki Kiyohara for the tests. --- django/http/request.py | 10 ++++++++-- tests/requests/tests.py | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/django/http/request.py b/django/http/request.py index e6811aa6cc..37aa1a355a 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -238,11 +238,17 @@ class HttpRequest(object): def read(self, *args, **kwargs): self._read_started = True - return self._stream.read(*args, **kwargs) + try: + return self._stream.read(*args, **kwargs) + except IOError as e: + six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2]) def readline(self, *args, **kwargs): self._read_started = True - return self._stream.readline(*args, **kwargs) + try: + return self._stream.readline(*args, **kwargs) + except IOError as e: + six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2]) def xreadlines(self): while True: diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 676cd05679..4d730bb561 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -659,6 +659,24 @@ class RequestsTests(SimpleTestCase): with self.assertRaises(UnreadablePostError): request.body + def test_FILES_connection_error(self): + """ + If wsgi.input.read() raises an exception while trying to read() the + FILES, the exception should be identifiable (not a generic IOError). + """ + class ExplodingBytesIO(BytesIO): + def read(self, len=0): + raise IOError("kaboom!") + + payload = b'x' + request = WSGIRequest({'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'multipart/form-data; boundary=foo_', + 'CONTENT_LENGTH': len(payload), + 'wsgi.input': ExplodingBytesIO(payload)}) + + with self.assertRaises(UnreadablePostError): + request.FILES + @skipIf(connection.vendor == 'sqlite' and connection.settings_dict['NAME'] in ('', ':memory:'),