瀏覽代碼

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 年之前
父節點
當前提交
de66b56790
共有 2 個文件被更改,包括 26 次插入2 次删除
  1. 8 2
      django/http/request.py
  2. 18 0
      tests/requests/tests.py

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