Code

Ticket #15762: patch_test_client_wsgi_input.diff

File patch_test_client_wsgi_input.diff, 3.7 KB (added by tomchristie, 3 years ago)

Ensure test client wsgi.input is wrapped in LimitedStream

Line 
1Index: tests/regressiontests/test_client_regress/views.py
2===================================================================
3--- tests/regressiontests/test_client_regress/views.py  (revision 16013)
4+++ tests/regressiontests/test_client_regress/views.py  (working copy)
5@@ -96,6 +96,10 @@
6     "A view that is requested with GET and accesses request.raw_post_data. Refs #14753."
7     return HttpResponse(request.raw_post_data)
8 
9+def read_limited_stream(request):
10+    "A view that is requested with PUT and accesses request.read(LARGE_BUFFER)."
11+    return HttpResponse(request.read(99999))
12+
13 def request_context_view(request):
14     # Special attribute that won't be present on a plain HttpRequest
15     request.special_path = request.path
16Index: tests/regressiontests/test_client_regress/models.py
17===================================================================
18--- tests/regressiontests/test_client_regress/models.py (revision 16013)
19+++ tests/regressiontests/test_client_regress/models.py (working copy)
20@@ -908,3 +908,15 @@
21             response = self.client.get("/test_client_regress/raw_post_data/")
22         except AssertionError:
23             self.fail("Accessing request.raw_post_data from a view fetched with GET by the test client shouldn't fail.")
24+
25+class ReadLimitedStreamTest(TestCase):
26+    """
27+    Attempting to read beyond META["CONTENT_LENGTH"] from the test client
28+    should simply return the full content of the request.
29+    """
30+    def test_read_limited_stream(self):
31+        try:
32+            response = self.client.put("/test_client_regress/read_limited_stream/", data={'foo':'whiz'})
33+        except AssertionError:
34+            self.fail("Reading more than META['CONTENT_LENGTH'] of data from a view fetched with PUT by the test client " +
35+                      "shouldn't fail, it should simply return the full content of the request.")       
36Index: tests/regressiontests/test_client_regress/urls.py
37===================================================================
38--- tests/regressiontests/test_client_regress/urls.py   (revision 16013)
39+++ tests/regressiontests/test_client_regress/urls.py   (working copy)
40@@ -27,5 +27,6 @@
41     (r'^check_headers/$', views.check_headers),
42     (r'^check_headers_redirect/$', RedirectView.as_view(url='/test_client_regress/check_headers/')),
43     (r'^raw_post_data/$', views.raw_post_data),
44+    (r'^read_limited_stream/$', views.read_limited_stream),
45     (r'^request_context_view/$', views.request_context_view),
46 )
47Index: django/test/client.py
48===================================================================
49--- django/test/client.py       (revision 16013)
50+++ django/test/client.py       (working copy)
51@@ -26,6 +26,7 @@
52 from django.utils.itercompat import is_iterable
53 from django.db import transaction, close_connection
54 from django.test.utils import ContextList
55+import socket
56 
57 __all__ = ('Client', 'RequestFactory', 'encode_file', 'encode_multipart')
58 
59@@ -34,12 +35,16 @@
60 MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
61 CONTENT_TYPE_RE = re.compile('.*; charset=([\w\d-]+);?')
62 
63-class FakePayload(object):
64+class FakePayload(socket._fileobject):
65     """
66     A wrapper around StringIO that restricts what can be read since data from
67     the network can't be seeked and cannot be read outside of its content
68     length. This makes sure that views can't do anything under the test client
69     that wouldn't work in Real Life.
70+
71+    We fake this up as a socket._fileobject, so that the WSGIrequest wraps it
72+    up in a LimitedStream as it would do for any WSGI stream that hasn't
73+    already defined it's own .read()/.readlines() implementations.
74     """
75     def __init__(self, content):
76         self.__content = StringIO(content)