test_data_upload_settings.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. from io import BytesIO
  2. from django.core.exceptions import (
  3. RequestDataTooBig,
  4. TooManyFieldsSent,
  5. TooManyFilesSent,
  6. )
  7. from django.core.handlers.wsgi import WSGIRequest
  8. from django.test import SimpleTestCase
  9. from django.test.client import FakePayload
  10. TOO_MANY_FIELDS_MSG = (
  11. "The number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS."
  12. )
  13. TOO_MANY_FILES_MSG = (
  14. "The number of files exceeded settings.DATA_UPLOAD_MAX_NUMBER_FILES."
  15. )
  16. TOO_MUCH_DATA_MSG = "Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE."
  17. class DataUploadMaxMemorySizeFormPostTests(SimpleTestCase):
  18. def setUp(self):
  19. payload = FakePayload("a=1&a=2&a=3\r\n")
  20. self.request = WSGIRequest(
  21. {
  22. "REQUEST_METHOD": "POST",
  23. "CONTENT_TYPE": "application/x-www-form-urlencoded",
  24. "CONTENT_LENGTH": len(payload),
  25. "wsgi.input": payload,
  26. }
  27. )
  28. def test_size_exceeded(self):
  29. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=12):
  30. with self.assertRaisesMessage(RequestDataTooBig, TOO_MUCH_DATA_MSG):
  31. self.request._load_post_and_files()
  32. def test_size_not_exceeded(self):
  33. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=13):
  34. self.request._load_post_and_files()
  35. def test_no_limit(self):
  36. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=None):
  37. self.request._load_post_and_files()
  38. class DataUploadMaxMemorySizeMultipartPostTests(SimpleTestCase):
  39. def setUp(self):
  40. payload = FakePayload(
  41. "\r\n".join(
  42. [
  43. "--boundary",
  44. 'Content-Disposition: form-data; name="name"',
  45. "",
  46. "value",
  47. "--boundary--",
  48. ]
  49. )
  50. )
  51. self.request = WSGIRequest(
  52. {
  53. "REQUEST_METHOD": "POST",
  54. "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
  55. "CONTENT_LENGTH": len(payload),
  56. "wsgi.input": payload,
  57. }
  58. )
  59. def test_size_exceeded(self):
  60. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=10):
  61. with self.assertRaisesMessage(RequestDataTooBig, TOO_MUCH_DATA_MSG):
  62. self.request._load_post_and_files()
  63. def test_size_not_exceeded(self):
  64. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=11):
  65. self.request._load_post_and_files()
  66. def test_no_limit(self):
  67. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=None):
  68. self.request._load_post_and_files()
  69. def test_file_passes(self):
  70. payload = FakePayload(
  71. "\r\n".join(
  72. [
  73. "--boundary",
  74. 'Content-Disposition: form-data; name="file1"; '
  75. 'filename="test.file"',
  76. "",
  77. "value",
  78. "--boundary--",
  79. ]
  80. )
  81. )
  82. request = WSGIRequest(
  83. {
  84. "REQUEST_METHOD": "POST",
  85. "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
  86. "CONTENT_LENGTH": len(payload),
  87. "wsgi.input": payload,
  88. }
  89. )
  90. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=1):
  91. request._load_post_and_files()
  92. self.assertIn("file1", request.FILES, "Upload file not present")
  93. class DataUploadMaxMemorySizeGetTests(SimpleTestCase):
  94. def setUp(self):
  95. self.request = WSGIRequest(
  96. {
  97. "REQUEST_METHOD": "GET",
  98. "wsgi.input": BytesIO(b""),
  99. "CONTENT_LENGTH": 3,
  100. }
  101. )
  102. def test_data_upload_max_memory_size_exceeded(self):
  103. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=2):
  104. with self.assertRaisesMessage(RequestDataTooBig, TOO_MUCH_DATA_MSG):
  105. self.request.body
  106. def test_size_not_exceeded(self):
  107. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=3):
  108. self.request.body
  109. def test_no_limit(self):
  110. with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=None):
  111. self.request.body
  112. def test_empty_content_length(self):
  113. self.request.environ["CONTENT_LENGTH"] = ""
  114. self.request.body
  115. class DataUploadMaxNumberOfFieldsGet(SimpleTestCase):
  116. def test_get_max_fields_exceeded(self):
  117. with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=1):
  118. with self.assertRaisesMessage(TooManyFieldsSent, TOO_MANY_FIELDS_MSG):
  119. request = WSGIRequest(
  120. {
  121. "REQUEST_METHOD": "GET",
  122. "wsgi.input": BytesIO(b""),
  123. "QUERY_STRING": "a=1&a=2&a=3",
  124. }
  125. )
  126. request.GET["a"]
  127. def test_get_max_fields_not_exceeded(self):
  128. with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=3):
  129. request = WSGIRequest(
  130. {
  131. "REQUEST_METHOD": "GET",
  132. "wsgi.input": BytesIO(b""),
  133. "QUERY_STRING": "a=1&a=2&a=3",
  134. }
  135. )
  136. request.GET["a"]
  137. class DataUploadMaxNumberOfFieldsMultipartPost(SimpleTestCase):
  138. def setUp(self):
  139. payload = FakePayload(
  140. "\r\n".join(
  141. [
  142. "--boundary",
  143. 'Content-Disposition: form-data; name="name1"',
  144. "",
  145. "value1",
  146. "--boundary",
  147. 'Content-Disposition: form-data; name="name2"',
  148. "",
  149. "value2",
  150. "--boundary--",
  151. ]
  152. )
  153. )
  154. self.request = WSGIRequest(
  155. {
  156. "REQUEST_METHOD": "POST",
  157. "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
  158. "CONTENT_LENGTH": len(payload),
  159. "wsgi.input": payload,
  160. }
  161. )
  162. def test_number_exceeded(self):
  163. with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=1):
  164. with self.assertRaisesMessage(TooManyFieldsSent, TOO_MANY_FIELDS_MSG):
  165. self.request._load_post_and_files()
  166. def test_number_not_exceeded(self):
  167. with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=2):
  168. self.request._load_post_and_files()
  169. def test_no_limit(self):
  170. with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=None):
  171. self.request._load_post_and_files()
  172. class DataUploadMaxNumberOfFilesMultipartPost(SimpleTestCase):
  173. def setUp(self):
  174. payload = FakePayload(
  175. "\r\n".join(
  176. [
  177. "--boundary",
  178. (
  179. 'Content-Disposition: form-data; name="name1"; '
  180. 'filename="name1.txt"'
  181. ),
  182. "",
  183. "value1",
  184. "--boundary",
  185. (
  186. 'Content-Disposition: form-data; name="name2"; '
  187. 'filename="name2.txt"'
  188. ),
  189. "",
  190. "value2",
  191. "--boundary--",
  192. ]
  193. )
  194. )
  195. self.request = WSGIRequest(
  196. {
  197. "REQUEST_METHOD": "POST",
  198. "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
  199. "CONTENT_LENGTH": len(payload),
  200. "wsgi.input": payload,
  201. }
  202. )
  203. def test_number_exceeded(self):
  204. with self.settings(DATA_UPLOAD_MAX_NUMBER_FILES=1):
  205. with self.assertRaisesMessage(TooManyFilesSent, TOO_MANY_FILES_MSG):
  206. self.request._load_post_and_files()
  207. def test_number_not_exceeded(self):
  208. with self.settings(DATA_UPLOAD_MAX_NUMBER_FILES=2):
  209. self.request._load_post_and_files()
  210. def test_no_limit(self):
  211. with self.settings(DATA_UPLOAD_MAX_NUMBER_FILES=None):
  212. self.request._load_post_and_files()
  213. class DataUploadMaxNumberOfFieldsFormPost(SimpleTestCase):
  214. def setUp(self):
  215. payload = FakePayload("\r\n".join(["a=1&a=2&a=3", ""]))
  216. self.request = WSGIRequest(
  217. {
  218. "REQUEST_METHOD": "POST",
  219. "CONTENT_TYPE": "application/x-www-form-urlencoded",
  220. "CONTENT_LENGTH": len(payload),
  221. "wsgi.input": payload,
  222. }
  223. )
  224. def test_number_exceeded(self):
  225. with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=2):
  226. with self.assertRaisesMessage(TooManyFieldsSent, TOO_MANY_FIELDS_MSG):
  227. self.request._load_post_and_files()
  228. def test_number_not_exceeded(self):
  229. with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=3):
  230. self.request._load_post_and_files()
  231. def test_no_limit(self):
  232. with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=None):
  233. self.request._load_post_and_files()