from io import BytesIO from django.core.exceptions import RequestDataTooBig, TooManyFieldsSent from django.core.handlers.wsgi import WSGIRequest from django.test import SimpleTestCase from django.test.client import FakePayload TOO_MANY_FIELDS_MSG = 'The number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.' TOO_MUCH_DATA_MSG = 'Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.' class DataUploadMaxMemorySizeFormPostTests(SimpleTestCase): def setUp(self): payload = FakePayload('a=1&a=2;a=3\r\n') self.request = WSGIRequest({ 'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'application/x-www-form-urlencoded', 'CONTENT_LENGTH': len(payload), 'wsgi.input': payload, }) def test_size_exceeded(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=12): with self.assertRaisesMessage(RequestDataTooBig, TOO_MUCH_DATA_MSG): self.request._load_post_and_files() def test_size_not_exceeded(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=13): self.request._load_post_and_files() def test_no_limit(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=None): self.request._load_post_and_files() class DataUploadMaxMemorySizeMultipartPostTests(SimpleTestCase): def setUp(self): payload = FakePayload("\r\n".join([ '--boundary', 'Content-Disposition: form-data; name="name"', '', 'value', '--boundary--' '' ])) self.request = WSGIRequest({ 'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'multipart/form-data; boundary=boundary', 'CONTENT_LENGTH': len(payload), 'wsgi.input': payload, }) def test_size_exceeded(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=10): with self.assertRaisesMessage(RequestDataTooBig, TOO_MUCH_DATA_MSG): self.request._load_post_and_files() def test_size_not_exceeded(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=11): self.request._load_post_and_files() def test_no_limit(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=None): self.request._load_post_and_files() def test_file_passes(self): payload = FakePayload("\r\n".join([ '--boundary', 'Content-Disposition: form-data; name="file1"; filename="test.file"', '', 'value', '--boundary--' '' ])) request = WSGIRequest({ 'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'multipart/form-data; boundary=boundary', 'CONTENT_LENGTH': len(payload), 'wsgi.input': payload, }) with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=1): request._load_post_and_files() self.assertIn('file1', request.FILES, "Upload file not present") class DataUploadMaxMemorySizeGetTests(SimpleTestCase): def setUp(self): self.request = WSGIRequest({ 'REQUEST_METHOD': 'GET', 'wsgi.input': BytesIO(b''), 'CONTENT_LENGTH': 3, }) def test_data_upload_max_memory_size_exceeded(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=2): with self.assertRaisesMessage(RequestDataTooBig, TOO_MUCH_DATA_MSG): self.request.body def test_size_not_exceeded(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=3): self.request.body def test_no_limit(self): with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=None): self.request.body def test_empty_content_length(self): self.request.environ['CONTENT_LENGTH'] = '' self.request.body class DataUploadMaxNumberOfFieldsGet(SimpleTestCase): def test_get_max_fields_exceeded(self): with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=1): with self.assertRaisesMessage(TooManyFieldsSent, TOO_MANY_FIELDS_MSG): request = WSGIRequest({ 'REQUEST_METHOD': 'GET', 'wsgi.input': BytesIO(b''), 'QUERY_STRING': 'a=1&a=2;a=3', }) request.GET['a'] def test_get_max_fields_not_exceeded(self): with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=3): request = WSGIRequest({ 'REQUEST_METHOD': 'GET', 'wsgi.input': BytesIO(b''), 'QUERY_STRING': 'a=1&a=2;a=3', }) request.GET['a'] class DataUploadMaxNumberOfFieldsMultipartPost(SimpleTestCase): def setUp(self): payload = FakePayload("\r\n".join([ '--boundary', 'Content-Disposition: form-data; name="name1"', '', 'value1', '--boundary', 'Content-Disposition: form-data; name="name2"', '', 'value2', '--boundary--' '' ])) self.request = WSGIRequest({ 'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'multipart/form-data; boundary=boundary', 'CONTENT_LENGTH': len(payload), 'wsgi.input': payload, }) def test_number_exceeded(self): with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=1): with self.assertRaisesMessage(TooManyFieldsSent, TOO_MANY_FIELDS_MSG): self.request._load_post_and_files() def test_number_not_exceeded(self): with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=2): self.request._load_post_and_files() def test_no_limit(self): with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=None): self.request._load_post_and_files() class DataUploadMaxNumberOfFieldsFormPost(SimpleTestCase): def setUp(self): payload = FakePayload("\r\n".join(['a=1&a=2;a=3', ''])) self.request = WSGIRequest({ 'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'application/x-www-form-urlencoded', 'CONTENT_LENGTH': len(payload), 'wsgi.input': payload, }) def test_number_exceeded(self): with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=2): with self.assertRaisesMessage(TooManyFieldsSent, TOO_MANY_FIELDS_MSG): self.request._load_post_and_files() def test_number_not_exceeded(self): with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=3): self.request._load_post_and_files() def test_no_limit(self): with self.settings(DATA_UPLOAD_MAX_NUMBER_FIELDS=None): self.request._load_post_and_files()