Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
929684d6
Kaydet (Commit)
929684d6
authored
Ock 07, 2015
tarafından
Andre Cruz
Kaydeden (comit)
Tim Graham
May 12, 2016
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #21231 -- Enforced a max size for GET/POST values read into memory.
Thanks Tom Christie for review.
üst
4065f429
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
387 additions
and
11 deletions
+387
-11
global_settings.py
django/conf/global_settings.py
+8
-0
exceptions.py
django/core/exceptions.py
+16
-0
multipartparser.py
django/http/multipartparser.py
+34
-3
request.py
django/http/request.py
+19
-8
http.py
django/utils/http.py
+60
-0
exceptions.txt
docs/ref/exceptions.txt
+2
-0
settings.txt
docs/ref/settings.txt
+49
-0
1.10.txt
docs/releases/1.10.txt
+13
-0
test_data_upload_settings.py
tests/requests/test_data_upload_settings.py
+186
-0
No files found.
django/conf/global_settings.py
Dosyayı görüntüle @
929684d6
...
@@ -285,6 +285,14 @@ FILE_UPLOAD_HANDLERS = [
...
@@ -285,6 +285,14 @@ FILE_UPLOAD_HANDLERS = [
# file system instead of into memory.
# file system instead of into memory.
FILE_UPLOAD_MAX_MEMORY_SIZE
=
2621440
# i.e. 2.5 MB
FILE_UPLOAD_MAX_MEMORY_SIZE
=
2621440
# i.e. 2.5 MB
# Maximum size in bytes of request data (excluding file uploads) that will be
# read before a SuspiciousOperation (RequestDataTooBig) is raised.
DATA_UPLOAD_MAX_MEMORY_SIZE
=
2621440
# i.e. 2.5 MB
# Maximum number of GET/POST parameters that will be read before a
# SuspiciousOperation (TooManyFieldsSent) is raised.
DATA_UPLOAD_MAX_NUMBER_FIELDS
=
1000
# Directory in which upload streamed files will be temporarily saved. A value of
# Directory in which upload streamed files will be temporarily saved. A value of
# `None` will make Django use the operating system's default temporary directory
# `None` will make Django use the operating system's default temporary directory
# (i.e. "/tmp" on *nix systems).
# (i.e. "/tmp" on *nix systems).
...
...
django/core/exceptions.py
Dosyayı görüntüle @
929684d6
...
@@ -53,6 +53,22 @@ class DisallowedRedirect(SuspiciousOperation):
...
@@ -53,6 +53,22 @@ class DisallowedRedirect(SuspiciousOperation):
pass
pass
class
TooManyFieldsSent
(
SuspiciousOperation
):
"""
The number of fields in a POST request exceeded
settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.
"""
pass
class
RequestDataTooBig
(
SuspiciousOperation
):
"""
The size of the request (excluding any file uploads) exceeded
settings.DATA_UPLOAD_MAX_MEMORY_SIZE.
"""
pass
class
PermissionDenied
(
Exception
):
class
PermissionDenied
(
Exception
):
"""The user did not have permission to do that"""
"""The user did not have permission to do that"""
pass
pass
...
...
django/http/multipartparser.py
Dosyayı görüntüle @
929684d6
...
@@ -12,7 +12,9 @@ import cgi
...
@@ -12,7 +12,9 @@ import cgi
import
sys
import
sys
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core.exceptions
import
SuspiciousMultipartForm
from
django.core.exceptions
import
(
RequestDataTooBig
,
SuspiciousMultipartForm
,
TooManyFieldsSent
,
)
from
django.core.files.uploadhandler
import
(
from
django.core.files.uploadhandler
import
(
SkipFile
,
StopFutureHandlers
,
StopUpload
,
SkipFile
,
StopFutureHandlers
,
StopUpload
,
)
)
...
@@ -145,6 +147,13 @@ class MultiPartParser(object):
...
@@ -145,6 +147,13 @@ class MultiPartParser(object):
old_field_name
=
None
old_field_name
=
None
counters
=
[
0
]
*
len
(
handlers
)
counters
=
[
0
]
*
len
(
handlers
)
# Number of bytes that have been read.
num_bytes_read
=
0
# To count the number of keys in the request.
num_post_keys
=
0
# To limit the amount of data read from the request.
read_size
=
None
try
:
try
:
for
item_type
,
meta_data
,
field_stream
in
Parser
(
stream
,
self
.
_boundary
):
for
item_type
,
meta_data
,
field_stream
in
Parser
(
stream
,
self
.
_boundary
):
if
old_field_name
:
if
old_field_name
:
...
@@ -166,15 +175,37 @@ class MultiPartParser(object):
...
@@ -166,15 +175,37 @@ class MultiPartParser(object):
field_name
=
force_text
(
field_name
,
encoding
,
errors
=
'replace'
)
field_name
=
force_text
(
field_name
,
encoding
,
errors
=
'replace'
)
if
item_type
==
FIELD
:
if
item_type
==
FIELD
:
# Avoid storing more than DATA_UPLOAD_MAX_NUMBER_FIELDS.
num_post_keys
+=
1
if
(
settings
.
DATA_UPLOAD_MAX_NUMBER_FIELDS
is
not
None
and
settings
.
DATA_UPLOAD_MAX_NUMBER_FIELDS
<
num_post_keys
):
raise
TooManyFieldsSent
(
'The number of GET/POST parameters exceeded '
'settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.'
)
# Avoid reading more than DATA_UPLOAD_MAX_MEMORY_SIZE.
if
settings
.
DATA_UPLOAD_MAX_MEMORY_SIZE
is
not
None
:
read_size
=
settings
.
DATA_UPLOAD_MAX_MEMORY_SIZE
-
num_bytes_read
# This is a post field, we can just set it in the post
# This is a post field, we can just set it in the post
if
transfer_encoding
==
'base64'
:
if
transfer_encoding
==
'base64'
:
raw_data
=
field_stream
.
read
()
raw_data
=
field_stream
.
read
(
size
=
read_size
)
num_bytes_read
+=
len
(
raw_data
)
try
:
try
:
data
=
base64
.
b64decode
(
raw_data
)
data
=
base64
.
b64decode
(
raw_data
)
except
_BASE64_DECODE_ERROR
:
except
_BASE64_DECODE_ERROR
:
data
=
raw_data
data
=
raw_data
else
:
else
:
data
=
field_stream
.
read
()
data
=
field_stream
.
read
(
size
=
read_size
)
num_bytes_read
+=
len
(
data
)
# Add two here to make the check consistent with the
# x-www-form-urlencoded check that includes '&='.
num_bytes_read
+=
len
(
field_name
)
+
2
if
(
settings
.
DATA_UPLOAD_MAX_MEMORY_SIZE
is
not
None
and
num_bytes_read
>
settings
.
DATA_UPLOAD_MAX_MEMORY_SIZE
):
raise
RequestDataTooBig
(
'Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.'
)
self
.
_post
.
appendlist
(
field_name
,
self
.
_post
.
appendlist
(
field_name
,
force_text
(
data
,
encoding
,
errors
=
'replace'
))
force_text
(
data
,
encoding
,
errors
=
'replace'
))
...
...
django/http/request.py
Dosyayı görüntüle @
929684d6
...
@@ -8,7 +8,9 @@ from itertools import chain
...
@@ -8,7 +8,9 @@ from itertools import chain
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core
import
signing
from
django.core
import
signing
from
django.core.exceptions
import
DisallowedHost
,
ImproperlyConfigured
from
django.core.exceptions
import
(
DisallowedHost
,
ImproperlyConfigured
,
RequestDataTooBig
,
)
from
django.core.files
import
uploadhandler
from
django.core.files
import
uploadhandler
from
django.http.multipartparser
import
MultiPartParser
,
MultiPartParserError
from
django.http.multipartparser
import
MultiPartParser
,
MultiPartParserError
from
django.utils
import
six
from
django.utils
import
six
...
@@ -16,9 +18,9 @@ from django.utils.datastructures import ImmutableList, MultiValueDict
...
@@ -16,9 +18,9 @@ from django.utils.datastructures import ImmutableList, MultiValueDict
from
django.utils.encoding
import
(
from
django.utils.encoding
import
(
escape_uri_path
,
force_bytes
,
force_str
,
force_text
,
iri_to_uri
,
escape_uri_path
,
force_bytes
,
force_str
,
force_text
,
iri_to_uri
,
)
)
from
django.utils.http
import
is_same_domain
from
django.utils.http
import
is_same_domain
,
limited_parse_qsl
from
django.utils.six.moves.urllib.parse
import
(
from
django.utils.six.moves.urllib.parse
import
(
parse_qsl
,
quote
,
urlencode
,
urljoin
,
urlsplit
,
quote
,
urlencode
,
urljoin
,
urlsplit
,
)
)
RAISE_ERROR
=
object
()
RAISE_ERROR
=
object
()
...
@@ -259,6 +261,12 @@ class HttpRequest(object):
...
@@ -259,6 +261,12 @@ class HttpRequest(object):
if
not
hasattr
(
self
,
'_body'
):
if
not
hasattr
(
self
,
'_body'
):
if
self
.
_read_started
:
if
self
.
_read_started
:
raise
RawPostDataException
(
"You cannot access body after reading from request's data stream"
)
raise
RawPostDataException
(
"You cannot access body after reading from request's data stream"
)
# Limit the maximum request data size that will be handled in-memory.
if
(
settings
.
DATA_UPLOAD_MAX_MEMORY_SIZE
is
not
None
and
int
(
self
.
META
.
get
(
'CONTENT_LENGTH'
,
0
))
>
settings
.
DATA_UPLOAD_MAX_MEMORY_SIZE
):
raise
RequestDataTooBig
(
'Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.'
)
try
:
try
:
self
.
_body
=
self
.
read
()
self
.
_body
=
self
.
read
()
except
IOError
as
e
:
except
IOError
as
e
:
...
@@ -368,6 +376,12 @@ class QueryDict(MultiValueDict):
...
@@ -368,6 +376,12 @@ class QueryDict(MultiValueDict):
if
not
encoding
:
if
not
encoding
:
encoding
=
settings
.
DEFAULT_CHARSET
encoding
=
settings
.
DEFAULT_CHARSET
self
.
encoding
=
encoding
self
.
encoding
=
encoding
query_string
=
query_string
or
''
parse_qsl_kwargs
=
{
'keep_blank_values'
:
True
,
'fields_limit'
:
settings
.
DATA_UPLOAD_MAX_NUMBER_FIELDS
,
'encoding'
:
encoding
,
}
if
six
.
PY3
:
if
six
.
PY3
:
if
isinstance
(
query_string
,
bytes
):
if
isinstance
(
query_string
,
bytes
):
# query_string normally contains URL-encoded data, a subset of ASCII.
# query_string normally contains URL-encoded data, a subset of ASCII.
...
@@ -376,13 +390,10 @@ class QueryDict(MultiValueDict):
...
@@ -376,13 +390,10 @@ class QueryDict(MultiValueDict):
except
UnicodeDecodeError
:
except
UnicodeDecodeError
:
# ... but some user agents are misbehaving :-(
# ... but some user agents are misbehaving :-(
query_string
=
query_string
.
decode
(
'iso-8859-1'
)
query_string
=
query_string
.
decode
(
'iso-8859-1'
)
for
key
,
value
in
parse_qsl
(
query_string
or
''
,
for
key
,
value
in
limited_parse_qsl
(
query_string
,
**
parse_qsl_kwargs
):
keep_blank_values
=
True
,
encoding
=
encoding
):
self
.
appendlist
(
key
,
value
)
self
.
appendlist
(
key
,
value
)
else
:
else
:
for
key
,
value
in
parse_qsl
(
query_string
or
''
,
for
key
,
value
in
limited_parse_qsl
(
query_string
,
**
parse_qsl_kwargs
):
keep_blank_values
=
True
):
try
:
try
:
value
=
value
.
decode
(
encoding
)
value
=
value
.
decode
(
encoding
)
except
UnicodeDecodeError
:
except
UnicodeDecodeError
:
...
...
django/utils/http.py
Dosyayı görüntüle @
929684d6
...
@@ -9,6 +9,7 @@ import unicodedata
...
@@ -9,6 +9,7 @@ import unicodedata
from
binascii
import
Error
as
BinasciiError
from
binascii
import
Error
as
BinasciiError
from
email.utils
import
formatdate
from
email.utils
import
formatdate
from
django.core.exceptions
import
TooManyFieldsSent
from
django.utils
import
six
from
django.utils
import
six
from
django.utils.datastructures
import
MultiValueDict
from
django.utils.datastructures
import
MultiValueDict
from
django.utils.encoding
import
force_bytes
,
force_str
,
force_text
from
django.utils.encoding
import
force_bytes
,
force_str
,
force_text
...
@@ -34,6 +35,8 @@ ASCTIME_DATE = re.compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y))
...
@@ -34,6 +35,8 @@ ASCTIME_DATE = re.compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y))
RFC3986_GENDELIMS
=
str
(
":/?#[]@"
)
RFC3986_GENDELIMS
=
str
(
":/?#[]@"
)
RFC3986_SUBDELIMS
=
str
(
"!$&'()*+,;="
)
RFC3986_SUBDELIMS
=
str
(
"!$&'()*+,;="
)
FIELDS_MATCH
=
re
.
compile
(
'[&;]'
)
@keep_lazy_text
@keep_lazy_text
def
urlquote
(
url
,
safe
=
'/'
):
def
urlquote
(
url
,
safe
=
'/'
):
...
@@ -314,3 +317,60 @@ def _is_safe_url(url, host):
...
@@ -314,3 +317,60 @@ def _is_safe_url(url, host):
return
False
return
False
return
((
not
url_info
.
netloc
or
url_info
.
netloc
==
host
)
and
return
((
not
url_info
.
netloc
or
url_info
.
netloc
==
host
)
and
(
not
url_info
.
scheme
or
url_info
.
scheme
in
[
'http'
,
'https'
]))
(
not
url_info
.
scheme
or
url_info
.
scheme
in
[
'http'
,
'https'
]))
def
limited_parse_qsl
(
qs
,
keep_blank_values
=
False
,
encoding
=
'utf-8'
,
errors
=
'replace'
,
fields_limit
=
None
):
"""
Return a list of key/value tuples parsed from query string.
Copied from urlparse with an additional "fields_limit" argument.
Copyright (C) 2013 Python Software Foundation (see LICENSE.python).
Arguments:
qs: percent-encoded query string to be parsed
keep_blank_values: flag indicating whether blank values in
percent-encoded queries should be treated as blank strings. A
true value indicates that blanks should be retained as blank
strings. The default false value indicates that blank values
are to be ignored and treated as if they were not included.
encoding and errors: specify how to decode percent-encoded sequences
into Unicode characters, as accepted by the bytes.decode() method.
fields_limit: maximum number of fields parsed or an exception
is raised. None means no limit and is the default.
"""
if
fields_limit
:
pairs
=
FIELDS_MATCH
.
split
(
qs
,
fields_limit
)
if
len
(
pairs
)
>
fields_limit
:
raise
TooManyFieldsSent
(
'The number of GET/POST parameters exceeded '
'settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.'
)
else
:
pairs
=
FIELDS_MATCH
.
split
(
qs
)
r
=
[]
for
name_value
in
pairs
:
if
not
name_value
:
continue
nv
=
name_value
.
split
(
str
(
'='
),
1
)
if
len
(
nv
)
!=
2
:
# Handle case of a control-name with no equal sign
if
keep_blank_values
:
nv
.
append
(
''
)
else
:
continue
if
len
(
nv
[
1
])
or
keep_blank_values
:
if
six
.
PY3
:
name
=
nv
[
0
]
.
replace
(
'+'
,
' '
)
name
=
unquote
(
name
,
encoding
=
encoding
,
errors
=
errors
)
value
=
nv
[
1
]
.
replace
(
'+'
,
' '
)
value
=
unquote
(
value
,
encoding
=
encoding
,
errors
=
errors
)
else
:
name
=
unquote
(
nv
[
0
]
.
replace
(
b
'+'
,
b
' '
))
value
=
unquote
(
nv
[
1
]
.
replace
(
b
'+'
,
b
' '
))
r
.
append
((
name
,
value
))
return
r
docs/ref/exceptions.txt
Dosyayı görüntüle @
929684d6
...
@@ -61,9 +61,11 @@ Django core exception classes are defined in ``django.core.exceptions``.
...
@@ -61,9 +61,11 @@ Django core exception classes are defined in ``django.core.exceptions``.
* ``DisallowedModelAdminToField``
* ``DisallowedModelAdminToField``
* ``DisallowedRedirect``
* ``DisallowedRedirect``
* ``InvalidSessionKey``
* ``InvalidSessionKey``
* ``RequestDataTooBig``
* ``SuspiciousFileOperation``
* ``SuspiciousFileOperation``
* ``SuspiciousMultipartForm``
* ``SuspiciousMultipartForm``
* ``SuspiciousSession``
* ``SuspiciousSession``
* ``TooManyFieldsSent``
If a ``SuspiciousOperation`` exception reaches the WSGI handler level it is
If a ``SuspiciousOperation`` exception reaches the WSGI handler level it is
logged at the ``Error`` level and results in
logged at the ``Error`` level and results in
...
...
docs/ref/settings.txt
Dosyayı görüntüle @
929684d6
...
@@ -880,6 +880,51 @@ This is an Oracle-specific setting.
...
@@ -880,6 +880,51 @@ This is an Oracle-specific setting.
The maximum size that the DATAFILE_TMP is allowed to grow to.
The maximum size that the DATAFILE_TMP is allowed to grow to.
.. setting:: DATA_UPLOAD_MAX_MEMORY_SIZE
DATA_UPLOAD_MAX_MEMORY_SIZE
---------------------------
.. versionadded:: 1.10
Default: ``2621440`` (i.e. 2.5 MB).
The maximum size in bytes that a request body may be before a
:exc:`~django.core.exceptions.SuspiciousOperation` (``RequestDataTooBig``) is
raised. The check is done when accessing ``request.body`` or ``request.POST``
and is calculated against the total request size excluding any file upload
data. You can set this to ``None`` to disable the check. Applications that are
expected to receive unusually large form posts should tune this setting.
The amount of request data is correlated to the amount of memory needed to
process the request and populate the GET and POST dictionaries. Large requests
could be used as a denial-of-service attack vector if left unchecked. Since web
servers don't typically perform deep request inspection, it's not possible to
perform a similar check at that level.
See also :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`.
.. setting:: DATA_UPLOAD_MAX_NUMBER_FIELDS
DATA_UPLOAD_MAX_NUMBER_FIELDS
-----------------------------
.. versionadded:: 1.10
Default: ``1000``
The maximum number of parameters that may be received via GET or POST before a
:exc:`~django.core.exceptions.SuspiciousOperation` (``TooManyFields``) is
raised. You can set this to ``None`` to disable the check. Applications that
are expected to receive an unusually large number of form fields should tune
this setting.
The number of request parameters is correlated to the amount of time needed to
process the request and populate the GET and POST dictionaries. Large requests
could be used as a denial-of-service attack vector if left unchecked. Since web
servers don't typically perform deep request inspection, it's not possible to
perform a similar check at that level.
.. setting:: DATABASE_ROUTERS
.. setting:: DATABASE_ROUTERS
``DATABASE_ROUTERS``
``DATABASE_ROUTERS``
...
@@ -1325,6 +1370,8 @@ Default: ``2621440`` (i.e. 2.5 MB).
...
@@ -1325,6 +1370,8 @@ Default: ``2621440`` (i.e. 2.5 MB).
The maximum size (in bytes) that an upload will be before it gets streamed to
The maximum size (in bytes) that an upload will be before it gets streamed to
the file system. See :doc:`/topics/files` for details.
the file system. See :doc:`/topics/files` for details.
See also :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE`.
.. setting:: FILE_UPLOAD_DIRECTORY_PERMISSIONS
.. setting:: FILE_UPLOAD_DIRECTORY_PERMISSIONS
``FILE_UPLOAD_DIRECTORY_PERMISSIONS``
``FILE_UPLOAD_DIRECTORY_PERMISSIONS``
...
@@ -3258,6 +3305,8 @@ Globalization (``i18n``/``l10n``)
...
@@ -3258,6 +3305,8 @@ Globalization (``i18n``/``l10n``)
HTTP
HTTP
----
----
* :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE`
* :setting:`DATA_UPLOAD_MAX_NUMBER_FIELDS`
* :setting:`DEFAULT_CHARSET`
* :setting:`DEFAULT_CHARSET`
* :setting:`DEFAULT_CONTENT_TYPE`
* :setting:`DEFAULT_CONTENT_TYPE`
* :setting:`DISALLOWED_USER_AGENTS`
* :setting:`DISALLOWED_USER_AGENTS`
...
...
docs/releases/1.10.txt
Dosyayı görüntüle @
929684d6
...
@@ -719,6 +719,19 @@ custom lookup for it. For example::
...
@@ -719,6 +719,19 @@ custom lookup for it. For example::
``POINT (23.0000000000000000 5.5000000000000000)``, you'll get
``POINT (23.0000000000000000 5.5000000000000000)``, you'll get
``POINT (23 5.5)``.
``POINT (23 5.5)``.
Maximum size of a request body and the number of GET/POST parameters is limited
-------------------------------------------------------------------------------
Two new settings help mitigate denial-of-service attacks via large requests:
* :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE` limits the size that a request body
may be. File uploads don't count towards this limit.
* :setting:`DATA_UPLOAD_MAX_NUMBER_FIELDS` limits the number of GET/POST
parameters that are parsed.
Applications that receive unusually large form posts may need to tune these
settings.
Miscellaneous
Miscellaneous
-------------
-------------
...
...
tests/requests/test_data_upload_settings.py
0 → 100644
Dosyayı görüntüle @
929684d6
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
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
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment