2
0
Эх сурвалжийг харах

Fixed #18481 -- Wrapped request.FILES read error in UnreadablePostError

Thanks KyleMac for the report, André Cruz for the initial patch and
Hiroki Kiyohara for the tests.
Claude Paroz 12 жил өмнө
parent
commit
de66b56790

+ 8 - 2
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:

+ 18 - 0
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:'),