mirror of https://github.com/django/django.git
Updated documentation and comments for RFC updates.
- Updated references to RFC 1123 to RFC 5322 - Only partial as RFC 5322 sort of sub-references RFC 1123. - Updated references to RFC 2388 to RFC 7578 - Except RFC 2388 Section 5.3 which has no equivalent. - Updated references to RFC 2396 to RFC 3986 - Updated references to RFC 2616 to RFC 9110 - Updated references to RFC 3066 to RFC 5646 - Updated references to RFC 7230 to RFC 9112 - Updated references to RFC 7231 to RFC 9110 - Updated references to RFC 7232 to RFC 9110 - Updated references to RFC 7234 to RFC 9111 - Tidied up style of text when referring to RFC documents
This commit is contained in:
parent
fad070b07b
commit
9bd174b9a7
|
@ -76,7 +76,7 @@ class WSGIRequest(HttpRequest):
|
||||||
self.path_info = path_info
|
self.path_info = path_info
|
||||||
# be careful to only replace the first slash in the path because of
|
# be careful to only replace the first slash in the path because of
|
||||||
# http://test/something and http://test//something being different as
|
# http://test/something and http://test//something being different as
|
||||||
# stated in https://www.ietf.org/rfc/rfc2396.txt
|
# stated in RFC 3986.
|
||||||
self.path = "%s/%s" % (script_name.rstrip("/"), path_info.replace("/", "", 1))
|
self.path = "%s/%s" % (script_name.rstrip("/"), path_info.replace("/", "", 1))
|
||||||
self.META = environ
|
self.META = environ
|
||||||
self.META["PATH_INFO"] = path_info
|
self.META["PATH_INFO"] = path_info
|
||||||
|
|
|
@ -36,7 +36,7 @@ class BadHeaderError(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Header names that contain structured address data (RFC #5322)
|
# Header names that contain structured address data (RFC 5322).
|
||||||
ADDRESS_HEADERS = {
|
ADDRESS_HEADERS = {
|
||||||
"from",
|
"from",
|
||||||
"sender",
|
"sender",
|
||||||
|
@ -382,8 +382,8 @@ class EmailMessage:
|
||||||
encoding = self.encoding or settings.DEFAULT_CHARSET
|
encoding = self.encoding or settings.DEFAULT_CHARSET
|
||||||
attachment = SafeMIMEText(content, subtype, encoding)
|
attachment = SafeMIMEText(content, subtype, encoding)
|
||||||
elif basetype == "message" and subtype == "rfc822":
|
elif basetype == "message" and subtype == "rfc822":
|
||||||
# Bug #18967: per RFC2046 s5.2.1, message/rfc822 attachments
|
# Bug #18967: Per RFC 2046 Section 5.2.1, message/rfc822
|
||||||
# must not be base64 encoded.
|
# attachments must not be base64 encoded.
|
||||||
if isinstance(content, EmailMessage):
|
if isinstance(content, EmailMessage):
|
||||||
# convert content into an email.Message first
|
# convert content into an email.Message first
|
||||||
content = content.message()
|
content = content.message()
|
||||||
|
|
|
@ -43,7 +43,7 @@ FIELD = "field"
|
||||||
|
|
||||||
class MultiPartParser:
|
class MultiPartParser:
|
||||||
"""
|
"""
|
||||||
A rfc2388 multipart/form-data parser.
|
An RFC 7578 multipart/form-data parser.
|
||||||
|
|
||||||
``MultiValueDict.parse()`` reads the input stream in ``chunk_size`` chunks
|
``MultiValueDict.parse()`` reads the input stream in ``chunk_size`` chunks
|
||||||
and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``.
|
and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``.
|
||||||
|
|
|
@ -426,7 +426,7 @@ class CsrfViewMiddleware(MiddlewareMixin):
|
||||||
if getattr(callback, "csrf_exempt", False):
|
if getattr(callback, "csrf_exempt", False):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Assume that anything not defined as 'safe' by RFC7231 needs protection
|
# Assume that anything not defined as 'safe' by RFC 9110 needs protection
|
||||||
if request.method in ("GET", "HEAD", "OPTIONS", "TRACE"):
|
if request.method in ("GET", "HEAD", "OPTIONS", "TRACE"):
|
||||||
return self._accept(request)
|
return self._accept(request)
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ class GZipMiddleware(MiddlewareMixin):
|
||||||
response.headers["Content-Length"] = str(len(response.content))
|
response.headers["Content-Length"] = str(len(response.content))
|
||||||
|
|
||||||
# If there is a strong ETag, make it weak to fulfill the requirements
|
# If there is a strong ETag, make it weak to fulfill the requirements
|
||||||
# of RFC 7232 section-2.1 while also allowing conditional request
|
# of RFC 9110 Section 8.8.1 while also allowing conditional request
|
||||||
# matches on ETags.
|
# matches on ETags.
|
||||||
etag = response.get("ETag")
|
etag = response.get("ETag")
|
||||||
if etag and etag.startswith('"'):
|
if etag and etag.startswith('"'):
|
||||||
|
|
|
@ -110,7 +110,7 @@ def conditional_content_removal(request, response):
|
||||||
"""
|
"""
|
||||||
Simulate the behavior of most web servers by removing the content of
|
Simulate the behavior of most web servers by removing the content of
|
||||||
responses for HEAD requests, 1xx, 204, and 304 responses. Ensure
|
responses for HEAD requests, 1xx, 204, and 304 responses. Ensure
|
||||||
compliance with RFC 7230, section 3.3.3.
|
compliance with RFC 9112 Section 6.3.
|
||||||
"""
|
"""
|
||||||
if 100 <= response.status_code < 200 or response.status_code in (204, 304):
|
if 100 <= response.status_code < 200 or response.status_code in (204, 304):
|
||||||
if response.streaming:
|
if response.streaming:
|
||||||
|
@ -987,7 +987,7 @@ class Client(ClientMixin, RequestFactory):
|
||||||
extra["SERVER_PORT"] = str(url.port)
|
extra["SERVER_PORT"] = str(url.port)
|
||||||
|
|
||||||
path = url.path
|
path = url.path
|
||||||
# RFC 2616: bare domains without path are treated as the root.
|
# RFC 3986 Section 6.2.3: Empty path should be normalized to "/".
|
||||||
if not path and url.netloc:
|
if not path and url.netloc:
|
||||||
path = "/"
|
path = "/"
|
||||||
# Prepend the request path to handle relative path redirects
|
# Prepend the request path to handle relative path redirects
|
||||||
|
|
|
@ -4,9 +4,7 @@ managing the "Vary" header of responses. It includes functions to patch the
|
||||||
header of response objects directly and decorators that change functions to do
|
header of response objects directly and decorators that change functions to do
|
||||||
that header-patching themselves.
|
that header-patching themselves.
|
||||||
|
|
||||||
For information on the Vary header, see:
|
For information on the Vary header, see RFC 9110 Section 12.5.5.
|
||||||
|
|
||||||
https://tools.ietf.org/html/rfc7231#section-7.1.4
|
|
||||||
|
|
||||||
Essentially, the "Vary" HTTP header defines which headers a cache should take
|
Essentially, the "Vary" HTTP header defines which headers a cache should take
|
||||||
into account when building its cache key. Requests with the same path but
|
into account when building its cache key. Requests with the same path but
|
||||||
|
@ -139,7 +137,7 @@ def _precondition_failed(request):
|
||||||
def _not_modified(request, response=None):
|
def _not_modified(request, response=None):
|
||||||
new_response = HttpResponseNotModified()
|
new_response = HttpResponseNotModified()
|
||||||
if response:
|
if response:
|
||||||
# Preserve the headers required by Section 4.1 of RFC 7232, as well as
|
# Preserve the headers required by RFC 9110 Section 15.4.5, as well as
|
||||||
# Last-Modified.
|
# Last-Modified.
|
||||||
for header in (
|
for header in (
|
||||||
"Cache-Control",
|
"Cache-Control",
|
||||||
|
@ -177,7 +175,9 @@ def get_conditional_response(request, etag=None, last_modified=None, response=No
|
||||||
if_modified_since = request.META.get("HTTP_IF_MODIFIED_SINCE")
|
if_modified_since = request.META.get("HTTP_IF_MODIFIED_SINCE")
|
||||||
if_modified_since = if_modified_since and parse_http_date_safe(if_modified_since)
|
if_modified_since = if_modified_since and parse_http_date_safe(if_modified_since)
|
||||||
|
|
||||||
# Step 1 of section 6 of RFC 7232: Test the If-Match precondition.
|
# Evaluation of request preconditions below follows RFC 9110 Section
|
||||||
|
# 13.2.2.
|
||||||
|
# Step 1: Test the If-Match precondition.
|
||||||
if if_match_etags and not _if_match_passes(etag, if_match_etags):
|
if if_match_etags and not _if_match_passes(etag, if_match_etags):
|
||||||
return _precondition_failed(request)
|
return _precondition_failed(request)
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ def get_conditional_response(request, etag=None, last_modified=None, response=No
|
||||||
|
|
||||||
def _if_match_passes(target_etag, etags):
|
def _if_match_passes(target_etag, etags):
|
||||||
"""
|
"""
|
||||||
Test the If-Match comparison as defined in section 3.1 of RFC 7232.
|
Test the If-Match comparison as defined in RFC 9110 Section 13.1.1.
|
||||||
"""
|
"""
|
||||||
if not target_etag:
|
if not target_etag:
|
||||||
# If there isn't an ETag, then there can't be a match.
|
# If there isn't an ETag, then there can't be a match.
|
||||||
|
@ -233,15 +233,15 @@ def _if_match_passes(target_etag, etags):
|
||||||
|
|
||||||
def _if_unmodified_since_passes(last_modified, if_unmodified_since):
|
def _if_unmodified_since_passes(last_modified, if_unmodified_since):
|
||||||
"""
|
"""
|
||||||
Test the If-Unmodified-Since comparison as defined in section 3.4 of
|
Test the If-Unmodified-Since comparison as defined in RFC 9110 Section
|
||||||
RFC 7232.
|
13.1.4.
|
||||||
"""
|
"""
|
||||||
return last_modified and last_modified <= if_unmodified_since
|
return last_modified and last_modified <= if_unmodified_since
|
||||||
|
|
||||||
|
|
||||||
def _if_none_match_passes(target_etag, etags):
|
def _if_none_match_passes(target_etag, etags):
|
||||||
"""
|
"""
|
||||||
Test the If-None-Match comparison as defined in section 3.2 of RFC 7232.
|
Test the If-None-Match comparison as defined in RFC 9110 Section 13.1.2.
|
||||||
"""
|
"""
|
||||||
if not target_etag:
|
if not target_etag:
|
||||||
# If there isn't an ETag, then there isn't a match.
|
# If there isn't an ETag, then there isn't a match.
|
||||||
|
@ -260,7 +260,8 @@ def _if_none_match_passes(target_etag, etags):
|
||||||
|
|
||||||
def _if_modified_since_passes(last_modified, if_modified_since):
|
def _if_modified_since_passes(last_modified, if_modified_since):
|
||||||
"""
|
"""
|
||||||
Test the If-Modified-Since comparison as defined in section 3.3 of RFC 7232.
|
Test the If-Modified-Since comparison as defined in RFC 9110 Section
|
||||||
|
13.1.3.
|
||||||
"""
|
"""
|
||||||
return not last_modified or last_modified > if_modified_since
|
return not last_modified or last_modified > if_modified_since
|
||||||
|
|
||||||
|
|
|
@ -112,16 +112,15 @@ def iri_to_uri(iri):
|
||||||
Convert an Internationalized Resource Identifier (IRI) portion to a URI
|
Convert an Internationalized Resource Identifier (IRI) portion to a URI
|
||||||
portion that is suitable for inclusion in a URL.
|
portion that is suitable for inclusion in a URL.
|
||||||
|
|
||||||
This is the algorithm from section 3.1 of RFC 3987, slightly simplified
|
This is the algorithm from RFC 3987 Section 3.1, slightly simplified since
|
||||||
since the input is assumed to be a string rather than an arbitrary byte
|
the input is assumed to be a string rather than an arbitrary byte stream.
|
||||||
stream.
|
|
||||||
|
|
||||||
Take an IRI (string or UTF-8 bytes, e.g. '/I ♥ Django/' or
|
Take an IRI (string or UTF-8 bytes, e.g. '/I ♥ Django/' or
|
||||||
b'/I \xe2\x99\xa5 Django/') and return a string containing the encoded
|
b'/I \xe2\x99\xa5 Django/') and return a string containing the encoded
|
||||||
result with ASCII chars only (e.g. '/I%20%E2%99%A5%20Django/').
|
result with ASCII chars only (e.g. '/I%20%E2%99%A5%20Django/').
|
||||||
"""
|
"""
|
||||||
# The list of safe characters here is constructed from the "reserved" and
|
# The list of safe characters here is constructed from the "reserved" and
|
||||||
# "unreserved" characters specified in sections 2.2 and 2.3 of RFC 3986:
|
# "unreserved" characters specified in RFC 3986 Sections 2.2 and 2.3:
|
||||||
# reserved = gen-delims / sub-delims
|
# reserved = gen-delims / sub-delims
|
||||||
# gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
# gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||||
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||||
|
@ -130,7 +129,7 @@ def iri_to_uri(iri):
|
||||||
# Of the unreserved characters, urllib.parse.quote() already considers all
|
# Of the unreserved characters, urllib.parse.quote() already considers all
|
||||||
# but the ~ safe.
|
# but the ~ safe.
|
||||||
# The % character is also added to the list of safe characters here, as the
|
# The % character is also added to the list of safe characters here, as the
|
||||||
# end of section 3.1 of RFC 3987 specifically mentions that % must not be
|
# end of RFC 3987 Section 3.1 specifically mentions that % must not be
|
||||||
# converted.
|
# converted.
|
||||||
if iri is None:
|
if iri is None:
|
||||||
return iri
|
return iri
|
||||||
|
@ -161,7 +160,7 @@ def uri_to_iri(uri):
|
||||||
Convert a Uniform Resource Identifier(URI) into an Internationalized
|
Convert a Uniform Resource Identifier(URI) into an Internationalized
|
||||||
Resource Identifier(IRI).
|
Resource Identifier(IRI).
|
||||||
|
|
||||||
This is the algorithm from section 3.2 of RFC 3987, excluding step 4.
|
This is the algorithm from RFC 3987 Section 3.2, excluding step 4.
|
||||||
|
|
||||||
Take an URI in ASCII bytes (e.g. '/I%20%E2%99%A5%20Django/') and return
|
Take an URI in ASCII bytes (e.g. '/I%20%E2%99%A5%20Django/') and return
|
||||||
a string containing the encoded result (e.g. '/I%20♥%20Django/').
|
a string containing the encoded result (e.g. '/I%20♥%20Django/').
|
||||||
|
@ -197,13 +196,13 @@ def escape_uri_path(path):
|
||||||
Escape the unsafe characters from the path portion of a Uniform Resource
|
Escape the unsafe characters from the path portion of a Uniform Resource
|
||||||
Identifier (URI).
|
Identifier (URI).
|
||||||
"""
|
"""
|
||||||
# These are the "reserved" and "unreserved" characters specified in
|
# These are the "reserved" and "unreserved" characters specified in RFC
|
||||||
# sections 2.2 and 2.3 of RFC 2396:
|
# 3986 Sections 2.2 and 2.3:
|
||||||
# reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
|
# reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
|
||||||
# unreserved = alphanum | mark
|
# unreserved = alphanum | mark
|
||||||
# mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
|
# mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
|
||||||
# The list of safe characters here is constructed subtracting ";", "=",
|
# The list of safe characters here is constructed subtracting ";", "=",
|
||||||
# and "?" according to section 3.3 of RFC 2396.
|
# and "?" according to RFC 3986 Section 3.3.
|
||||||
# The reason for not subtracting and escaping "/" is that we are escaping
|
# The reason for not subtracting and escaping "/" is that we are escaping
|
||||||
# the entire path, not a path segment.
|
# the entire path, not a path segment.
|
||||||
return quote(path, safe="/:@&+$,-_.!~*'()")
|
return quote(path, safe="/:@&+$,-_.!~*'()")
|
||||||
|
@ -216,7 +215,7 @@ def punycode(domain):
|
||||||
|
|
||||||
def repercent_broken_unicode(path):
|
def repercent_broken_unicode(path):
|
||||||
"""
|
"""
|
||||||
As per section 3.2 of RFC 3987, step three of converting a URI into an IRI,
|
As per RFC 3987 Section 3.2, step three of converting a URI into an IRI,
|
||||||
repercent-encode any octet produced that is not part of a strictly legal
|
repercent-encode any octet produced that is not part of a strictly legal
|
||||||
UTF-8 octet sequence.
|
UTF-8 octet sequence.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -193,9 +193,8 @@ def smart_urlquote(url):
|
||||||
|
|
||||||
def unquote_quote(segment):
|
def unquote_quote(segment):
|
||||||
segment = unquote(segment)
|
segment = unquote(segment)
|
||||||
# Tilde is part of RFC3986 Unreserved Characters
|
# Tilde is part of RFC 3986 Section 2.3 Unreserved Characters,
|
||||||
# https://tools.ietf.org/html/rfc3986#section-2.3
|
# see also https://bugs.python.org/issue16285
|
||||||
# See also https://bugs.python.org/issue16285
|
|
||||||
return quote(segment, safe=RFC3986_SUBDELIMS + RFC3986_GENDELIMS + "~")
|
return quote(segment, safe=RFC3986_SUBDELIMS + RFC3986_GENDELIMS + "~")
|
||||||
|
|
||||||
# Handle IDN before quoting.
|
# Handle IDN before quoting.
|
||||||
|
|
|
@ -19,7 +19,7 @@ from urllib.parse import uses_params
|
||||||
from django.utils.datastructures import MultiValueDict
|
from django.utils.datastructures import MultiValueDict
|
||||||
from django.utils.regex_helper import _lazy_re_compile
|
from django.utils.regex_helper import _lazy_re_compile
|
||||||
|
|
||||||
# based on RFC 7232, Appendix C
|
# Based on RFC 9110 Appendix A.
|
||||||
ETAG_MATCH = _lazy_re_compile(
|
ETAG_MATCH = _lazy_re_compile(
|
||||||
r"""
|
r"""
|
||||||
\A( # start of string and capture group
|
\A( # start of string and capture group
|
||||||
|
@ -94,8 +94,8 @@ def urlencode(query, doseq=False):
|
||||||
|
|
||||||
def http_date(epoch_seconds=None):
|
def http_date(epoch_seconds=None):
|
||||||
"""
|
"""
|
||||||
Format the time to match the RFC1123 date format as specified by HTTP
|
Format the time to match the RFC 5322 date format as specified by RFC 9110
|
||||||
RFC7231 section 7.1.1.1.
|
Section 5.6.7.
|
||||||
|
|
||||||
`epoch_seconds` is a floating point number expressed in seconds since the
|
`epoch_seconds` is a floating point number expressed in seconds since the
|
||||||
epoch, in UTC - such as that outputted by time.time(). If set to None, it
|
epoch, in UTC - such as that outputted by time.time(). If set to None, it
|
||||||
|
@ -108,7 +108,7 @@ def http_date(epoch_seconds=None):
|
||||||
|
|
||||||
def parse_http_date(date):
|
def parse_http_date(date):
|
||||||
"""
|
"""
|
||||||
Parse a date format as specified by HTTP RFC7231 section 7.1.1.1.
|
Parse a date format as specified by HTTP RFC 9110 Section 5.6.7.
|
||||||
|
|
||||||
The three formats allowed by the RFC are accepted, even if only the first
|
The three formats allowed by the RFC are accepted, even if only the first
|
||||||
one is still in widespread use.
|
one is still in widespread use.
|
||||||
|
@ -116,7 +116,7 @@ def parse_http_date(date):
|
||||||
Return an integer expressed in seconds since the epoch, in UTC.
|
Return an integer expressed in seconds since the epoch, in UTC.
|
||||||
"""
|
"""
|
||||||
# email.utils.parsedate() does the job for RFC 1123 dates; unfortunately
|
# email.utils.parsedate() does the job for RFC 1123 dates; unfortunately
|
||||||
# RFC7231 makes it mandatory to support RFC850 dates too. So we roll
|
# RFC 9110 makes it mandatory to support RFC 850 dates too. So we roll
|
||||||
# our own RFC-compliant parsing.
|
# our own RFC-compliant parsing.
|
||||||
for regex in RFC1123_DATE, RFC850_DATE, ASCTIME_DATE:
|
for regex in RFC1123_DATE, RFC850_DATE, ASCTIME_DATE:
|
||||||
m = regex.match(date)
|
m = regex.match(date)
|
||||||
|
@ -210,7 +210,7 @@ def urlsafe_base64_decode(s):
|
||||||
def parse_etags(etag_str):
|
def parse_etags(etag_str):
|
||||||
"""
|
"""
|
||||||
Parse a string of ETags given in an If-None-Match or If-Match header as
|
Parse a string of ETags given in an If-None-Match or If-Match header as
|
||||||
defined by RFC 7232. Return a list of quoted ETags, or ['*'] if all ETags
|
defined by RFC 9110. Return a list of quoted ETags, or ['*'] if all ETags
|
||||||
should be matched.
|
should be matched.
|
||||||
"""
|
"""
|
||||||
if etag_str.strip() == "*":
|
if etag_str.strip() == "*":
|
||||||
|
|
|
@ -30,8 +30,8 @@ _default = None
|
||||||
# magic gettext number to separate context from message
|
# magic gettext number to separate context from message
|
||||||
CONTEXT_SEPARATOR = "\x04"
|
CONTEXT_SEPARATOR = "\x04"
|
||||||
|
|
||||||
# Format of Accept-Language header values. From RFC 2616, section 14.4 and 3.9
|
# Format of Accept-Language header values. From RFC 9110 Sections 12.4.2 and
|
||||||
# and RFC 3066, section 2.1
|
# 12.5.4, and RFC 5646 Section 2.1.
|
||||||
accept_language_re = _lazy_re_compile(
|
accept_language_re = _lazy_re_compile(
|
||||||
r"""
|
r"""
|
||||||
# "en", "en-au", "x-y-z", "es-419", "*"
|
# "en", "en-au", "x-y-z", "es-419", "*"
|
||||||
|
|
|
@ -133,7 +133,7 @@ def permission_denied(request, exception, template_name=ERROR_403_TEMPLATE_NAME)
|
||||||
supplied).
|
supplied).
|
||||||
|
|
||||||
If the template does not exist, an Http403 response containing the text
|
If the template does not exist, an Http403 response containing the text
|
||||||
"403 Forbidden" (as per RFC 7231) will be returned.
|
"403 Forbidden" (as per RFC 9110 Section 15.5.4) will be returned.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
template = loader.get_template(template_name)
|
template = loader.get_template(template_name)
|
||||||
|
|
|
@ -14,7 +14,7 @@ who visits the malicious site in their browser. A related type of attack,
|
||||||
a site with someone else's credentials, is also covered.
|
a site with someone else's credentials, is also covered.
|
||||||
|
|
||||||
The first defense against CSRF attacks is to ensure that GET requests (and other
|
The first defense against CSRF attacks is to ensure that GET requests (and other
|
||||||
'safe' methods, as defined by :rfc:`7231#section-4.2.1`) are side effect free.
|
'safe' methods, as defined by :rfc:`9110#section-9.2.1`) are side effect free.
|
||||||
Requests via 'unsafe' methods, such as POST, PUT, and DELETE, can then be
|
Requests via 'unsafe' methods, such as POST, PUT, and DELETE, can then be
|
||||||
protected by the steps outlined in :ref:`using-csrf`.
|
protected by the steps outlined in :ref:`using-csrf`.
|
||||||
|
|
||||||
|
@ -90,9 +90,9 @@ This ensures that only forms that have originated from trusted domains can be
|
||||||
used to POST data back.
|
used to POST data back.
|
||||||
|
|
||||||
It deliberately ignores GET requests (and other requests that are defined as
|
It deliberately ignores GET requests (and other requests that are defined as
|
||||||
'safe' by :rfc:`7231#section-4.2.1`). These requests ought never to have any
|
'safe' by :rfc:`9110#section-9.2.1`). These requests ought never to have any
|
||||||
potentially dangerous side effects, and so a CSRF attack with a GET request
|
potentially dangerous side effects, and so a CSRF attack with a GET request
|
||||||
ought to be harmless. :rfc:`7231#section-4.2.1` defines POST, PUT, and DELETE
|
ought to be harmless. :rfc:`9110#section-9.2.1` defines POST, PUT, and DELETE
|
||||||
as 'unsafe', and all other methods are also assumed to be unsafe, for maximum
|
as 'unsafe', and all other methods are also assumed to be unsafe, for maximum
|
||||||
protection.
|
protection.
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ It will NOT compress content if any of the following are true:
|
||||||
containing ``gzip``.
|
containing ``gzip``.
|
||||||
|
|
||||||
If the response has an ``ETag`` header, the ETag is made weak to comply with
|
If the response has an ``ETag`` header, the ETag is made weak to comply with
|
||||||
:rfc:`7232#section-2.1`.
|
:rfc:`9110#section-8.8.1`.
|
||||||
|
|
||||||
You can apply GZip compression to individual views using the
|
You can apply GZip compression to individual views using the
|
||||||
:func:`~django.views.decorators.gzip.gzip_page()` decorator.
|
:func:`~django.views.decorators.gzip.gzip_page()` decorator.
|
||||||
|
|
|
@ -848,7 +848,7 @@ track down every place that the URL might be created. Specify it once, in
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The string you return from ``get_absolute_url()`` **must** contain only
|
The string you return from ``get_absolute_url()`` **must** contain only
|
||||||
ASCII characters (required by the URI specification, :rfc:`2396#section-2`)
|
ASCII characters (required by the URI specification, :rfc:`3986#section-2`)
|
||||||
and be URL-encoded, if necessary.
|
and be URL-encoded, if necessary.
|
||||||
|
|
||||||
Code and templates calling ``get_absolute_url()`` should be able to use the
|
Code and templates calling ``get_absolute_url()`` should be able to use the
|
||||||
|
|
|
@ -2174,7 +2174,7 @@ Finally, a word on using ``get_or_create()`` in Django views. Please make sure
|
||||||
to use it only in ``POST`` requests unless you have a good reason not to.
|
to use it only in ``POST`` requests unless you have a good reason not to.
|
||||||
``GET`` requests shouldn't have any effect on data. Instead, use ``POST``
|
``GET`` requests shouldn't have any effect on data. Instead, use ``POST``
|
||||||
whenever a request to a page has a side effect on your data. For more, see
|
whenever a request to a page has a side effect on your data. For more, see
|
||||||
:rfc:`Safe methods <7231#section-4.2.1>` in the HTTP spec.
|
:rfc:`Safe methods <9110#section-9.2.1>` in the HTTP spec.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
|
|
@ -759,7 +759,7 @@ Attributes
|
||||||
|
|
||||||
.. attribute:: HttpResponse.status_code
|
.. attribute:: HttpResponse.status_code
|
||||||
|
|
||||||
The :rfc:`HTTP status code <7231#section-6>` for the response.
|
The :rfc:`HTTP status code <9110#section-15>` for the response.
|
||||||
|
|
||||||
Unless :attr:`reason_phrase` is explicitly set, modifying the value of
|
Unless :attr:`reason_phrase` is explicitly set, modifying the value of
|
||||||
``status_code`` outside the constructor will also modify the value of
|
``status_code`` outside the constructor will also modify the value of
|
||||||
|
@ -768,7 +768,7 @@ Attributes
|
||||||
.. attribute:: HttpResponse.reason_phrase
|
.. attribute:: HttpResponse.reason_phrase
|
||||||
|
|
||||||
The HTTP reason phrase for the response. It uses the :rfc:`HTTP standard's
|
The HTTP reason phrase for the response. It uses the :rfc:`HTTP standard's
|
||||||
<7231#section-6.1>` default reason phrases.
|
<9110#section-15.1>` default reason phrases.
|
||||||
|
|
||||||
Unless explicitly set, ``reason_phrase`` is determined by the value of
|
Unless explicitly set, ``reason_phrase`` is determined by the value of
|
||||||
:attr:`status_code`.
|
:attr:`status_code`.
|
||||||
|
@ -803,9 +803,9 @@ Methods
|
||||||
:setting:`DEFAULT_CHARSET` settings, by default:
|
:setting:`DEFAULT_CHARSET` settings, by default:
|
||||||
``"text/html; charset=utf-8"``.
|
``"text/html; charset=utf-8"``.
|
||||||
|
|
||||||
``status`` is the :rfc:`HTTP status code <7231#section-6>` for the response.
|
``status`` is the :rfc:`HTTP status code <9110#section-15>` for the
|
||||||
You can use Python's :py:class:`http.HTTPStatus` for meaningful aliases,
|
response. You can use Python's :py:class:`http.HTTPStatus` for meaningful
|
||||||
such as ``HTTPStatus.NO_CONTENT``.
|
aliases, such as ``HTTPStatus.NO_CONTENT``.
|
||||||
|
|
||||||
``reason`` is the HTTP response phrase. If not provided, a default phrase
|
``reason`` is the HTTP response phrase. If not provided, a default phrase
|
||||||
will be used.
|
will be used.
|
||||||
|
@ -1163,7 +1163,7 @@ Attributes
|
||||||
|
|
||||||
.. attribute:: StreamingHttpResponse.status_code
|
.. attribute:: StreamingHttpResponse.status_code
|
||||||
|
|
||||||
The :rfc:`HTTP status code <7231#section-6>` for the response.
|
The :rfc:`HTTP status code <9110#section-15>` for the response.
|
||||||
|
|
||||||
Unless :attr:`reason_phrase` is explicitly set, modifying the value of
|
Unless :attr:`reason_phrase` is explicitly set, modifying the value of
|
||||||
``status_code`` outside the constructor will also modify the value of
|
``status_code`` outside the constructor will also modify the value of
|
||||||
|
@ -1172,7 +1172,7 @@ Attributes
|
||||||
.. attribute:: StreamingHttpResponse.reason_phrase
|
.. attribute:: StreamingHttpResponse.reason_phrase
|
||||||
|
|
||||||
The HTTP reason phrase for the response. It uses the :rfc:`HTTP standard's
|
The HTTP reason phrase for the response. It uses the :rfc:`HTTP standard's
|
||||||
<7231#section-6.1>` default reason phrases.
|
<9110#section-15.1>` default reason phrases.
|
||||||
|
|
||||||
Unless explicitly set, ``reason_phrase`` is determined by the value of
|
Unless explicitly set, ``reason_phrase`` is determined by the value of
|
||||||
:attr:`status_code`.
|
:attr:`status_code`.
|
||||||
|
|
|
@ -146,7 +146,7 @@ URI and IRI handling
|
||||||
Web frameworks have to deal with URLs (which are a type of IRI). One
|
Web frameworks have to deal with URLs (which are a type of IRI). One
|
||||||
requirement of URLs is that they are encoded using only ASCII characters.
|
requirement of URLs is that they are encoded using only ASCII characters.
|
||||||
However, in an international environment, you might need to construct a
|
However, in an international environment, you might need to construct a
|
||||||
URL from an :rfc:`IRI <3987>` -- very loosely speaking, a :rfc:`URI <2396>`
|
URL from an :rfc:`IRI <3987>` -- very loosely speaking, a :rfc:`URI <3986>`
|
||||||
that can contain Unicode characters. Use these functions for quoting and
|
that can contain Unicode characters. Use these functions for quoting and
|
||||||
converting an IRI to a URI:
|
converting an IRI to a URI:
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ by managing the ``Vary`` header of responses. It includes functions to patch
|
||||||
the header of response objects directly and decorators that change functions to
|
the header of response objects directly and decorators that change functions to
|
||||||
do that header-patching themselves.
|
do that header-patching themselves.
|
||||||
|
|
||||||
For information on the ``Vary`` header, see :rfc:`7231#section-7.1.4`.
|
For information on the ``Vary`` header, see :rfc:`9110#section-12.5.5`.
|
||||||
|
|
||||||
Essentially, the ``Vary`` HTTP header defines which headers a cache should take
|
Essentially, the ``Vary`` HTTP header defines which headers a cache should take
|
||||||
into account when building its cache key. Requests with the same path but
|
into account when building its cache key. Requests with the same path but
|
||||||
|
@ -75,7 +75,7 @@ need to distinguish caches by the ``Accept-language`` header.
|
||||||
Adds (or updates) the ``Vary`` header in the given ``HttpResponse`` object.
|
Adds (or updates) the ``Vary`` header in the given ``HttpResponse`` object.
|
||||||
``newheaders`` is a list of header names that should be in ``Vary``. If
|
``newheaders`` is a list of header names that should be in ``Vary``. If
|
||||||
headers contains an asterisk, then ``Vary`` header will consist of a single
|
headers contains an asterisk, then ``Vary`` header will consist of a single
|
||||||
asterisk ``'*'``, according to :rfc:`7231#section-7.1.4`. Otherwise,
|
asterisk ``'*'``, according to :rfc:`9110#section-12.5.5`. Otherwise,
|
||||||
existing headers in ``Vary`` aren't removed.
|
existing headers in ``Vary`` aren't removed.
|
||||||
|
|
||||||
.. function:: get_cache_key(request, key_prefix=None, method='GET', cache=None)
|
.. function:: get_cache_key(request, key_prefix=None, method='GET', cache=None)
|
||||||
|
@ -721,7 +721,7 @@ escaping HTML.
|
||||||
.. function:: http_date(epoch_seconds=None)
|
.. function:: http_date(epoch_seconds=None)
|
||||||
|
|
||||||
Formats the time to match the :rfc:`1123#section-5.2.14` date format as
|
Formats the time to match the :rfc:`1123#section-5.2.14` date format as
|
||||||
specified by HTTP :rfc:`7231#section-7.1.1.1`.
|
specified by HTTP :rfc:`9110#section-5.6.7`.
|
||||||
|
|
||||||
Accepts a floating point number expressed in seconds since the epoch in
|
Accepts a floating point number expressed in seconds since the epoch in
|
||||||
UTC--such as that outputted by ``time.time()``. If set to ``None``,
|
UTC--such as that outputted by ``time.time()``. If set to ``None``,
|
||||||
|
|
|
@ -121,9 +121,9 @@ default, call the view ``django.views.defaults.permission_denied``.
|
||||||
|
|
||||||
This view loads and renders the template ``403.html`` in your root template
|
This view loads and renders the template ``403.html`` in your root template
|
||||||
directory, or if this file does not exist, instead serves the text
|
directory, or if this file does not exist, instead serves the text
|
||||||
"403 Forbidden", as per :rfc:`7231#section-6.5.3` (the HTTP 1.1 Specification).
|
"403 Forbidden", as per :rfc:`9110#section-15.5.4` (the HTTP 1.1
|
||||||
The template context contains ``exception``, which is the string
|
Specification). The template context contains ``exception``, which is the
|
||||||
representation of the exception that triggered the view.
|
string representation of the exception that triggered the view.
|
||||||
|
|
||||||
``django.views.defaults.permission_denied`` is triggered by a
|
``django.views.defaults.permission_denied`` is triggered by a
|
||||||
:exc:`~django.core.exceptions.PermissionDenied` exception. To deny access in a
|
:exc:`~django.core.exceptions.PermissionDenied` exception. To deny access in a
|
||||||
|
|
|
@ -1351,7 +1351,7 @@ its first argument and a list/tuple of case-insensitive header names as its
|
||||||
second argument.
|
second argument.
|
||||||
|
|
||||||
For more on Vary headers, see the :rfc:`official Vary spec
|
For more on Vary headers, see the :rfc:`official Vary spec
|
||||||
<7231#section-7.1.4>`.
|
<9110#section-12.5.5>`.
|
||||||
|
|
||||||
Controlling cache: Using other headers
|
Controlling cache: Using other headers
|
||||||
======================================
|
======================================
|
||||||
|
@ -1402,10 +1402,10 @@ cache control header (it is internally called by the
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
You can control downstream caches in other ways as well (see :rfc:`7234` for
|
You can control downstream caches in other ways as well (see :rfc:`9111` for
|
||||||
details on HTTP caching). For example, even if you don't use Django's
|
details on HTTP caching). For example, even if you don't use Django's
|
||||||
server-side cache framework, you can still tell clients to cache a view for a
|
server-side cache framework, you can still tell clients to cache a view for a
|
||||||
certain amount of time with the :rfc:`max-age <7234#section-5.2.2.8>`
|
certain amount of time with the :rfc:`max-age <9111#section-5.2.2.1>`
|
||||||
directive::
|
directive::
|
||||||
|
|
||||||
from django.views.decorators.cache import cache_control
|
from django.views.decorators.cache import cache_control
|
||||||
|
|
|
@ -15,16 +15,16 @@ or you can rely on the :class:`~django.middleware.http.ConditionalGetMiddleware`
|
||||||
middleware to set the ``ETag`` header.
|
middleware to set the ``ETag`` header.
|
||||||
|
|
||||||
When the client next requests the same resource, it might send along a header
|
When the client next requests the same resource, it might send along a header
|
||||||
such as either :rfc:`If-modified-since <7232#section-3.3>` or
|
such as either :rfc:`If-Modified-Since <9110#section-13.1.3>` or
|
||||||
:rfc:`If-unmodified-since <7232#section-3.4>`, containing the date of the last
|
:rfc:`If-Unmodified-Since <9110#section-13.1.4>`, containing the date of the
|
||||||
modification time it was sent, or either :rfc:`If-match <7232#section-3.1>` or
|
last modification time it was sent, or either :rfc:`If-Match
|
||||||
:rfc:`If-none-match <7232#section-3.2>`, containing the last ``ETag`` it was
|
<9110#section-13.1.1>` or :rfc:`If-None-Match <9110#section-13.1.2>`,
|
||||||
sent. If the current version of the page matches the ``ETag`` sent by the
|
containing the last ``ETag`` it was sent. If the current version of the page
|
||||||
client, or if the resource has not been modified, a 304 status code can be sent
|
matches the ``ETag`` sent by the client, or if the resource has not been
|
||||||
back, instead of a full response, telling the client that nothing has changed.
|
modified, a 304 status code can be sent back, instead of a full response,
|
||||||
Depending on the header, if the page has been modified or does not match the
|
telling the client that nothing has changed. Depending on the header, if the
|
||||||
``ETag`` sent by the client, a 412 status code (Precondition Failed) may be
|
page has been modified or does not match the ``ETag`` sent by the client, a 412
|
||||||
returned.
|
status code (Precondition Failed) may be returned.
|
||||||
|
|
||||||
When you need more fine-grained control you may use per-view conditional
|
When you need more fine-grained control you may use per-view conditional
|
||||||
processing functions.
|
processing functions.
|
||||||
|
@ -35,7 +35,7 @@ The ``condition`` decorator
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
Sometimes (in fact, quite often) you can create functions to rapidly compute
|
Sometimes (in fact, quite often) you can create functions to rapidly compute
|
||||||
the :rfc:`ETag <7232#section-2.3>` value or the last-modified time for a
|
the :rfc:`ETag <9110#section-8.8.3>` value or the last-modified time for a
|
||||||
resource, **without** needing to do all the computations needed to construct
|
resource, **without** needing to do all the computations needed to construct
|
||||||
the full view. Django can then use these functions to provide an
|
the full view. Django can then use these functions to provide an
|
||||||
"early bailout" option for the view processing. Telling the client that the
|
"early bailout" option for the view processing. Telling the client that the
|
||||||
|
@ -58,7 +58,7 @@ order, as the view function they are helping to wrap. The function passed
|
||||||
``last_modified_func`` should return a standard datetime value specifying the
|
``last_modified_func`` should return a standard datetime value specifying the
|
||||||
last time the resource was modified, or ``None`` if the resource doesn't
|
last time the resource was modified, or ``None`` if the resource doesn't
|
||||||
exist. The function passed to the ``etag`` decorator should return a string
|
exist. The function passed to the ``etag`` decorator should return a string
|
||||||
representing the :rfc:`ETag <7232#section-2.3>` for the resource, or ``None``
|
representing the :rfc:`ETag <9110#section-8.8.3>` for the resource, or ``None``
|
||||||
if it doesn't exist.
|
if it doesn't exist.
|
||||||
|
|
||||||
The decorator sets the ``ETag`` and ``Last-Modified`` headers on the response
|
The decorator sets the ``ETag`` and ``Last-Modified`` headers on the response
|
||||||
|
@ -105,8 +105,8 @@ for your front page view::
|
||||||
:func:`~django.views.decorators.vary.vary_on_cookie`,
|
:func:`~django.views.decorators.vary.vary_on_cookie`,
|
||||||
:func:`~django.views.decorators.vary.vary_on_headers`, and
|
:func:`~django.views.decorators.vary.vary_on_headers`, and
|
||||||
:func:`~django.views.decorators.cache.cache_control` should come first
|
:func:`~django.views.decorators.cache.cache_control` should come first
|
||||||
because :rfc:`RFC 7232 <7232#section-4.1>` requires that the headers they
|
because :rfc:`RFC 9110 <9110#section-15.4.5>` requires that the headers
|
||||||
set be present on 304 responses.
|
they set be present on 304 responses.
|
||||||
|
|
||||||
Shortcuts for only computing one value
|
Shortcuts for only computing one value
|
||||||
======================================
|
======================================
|
||||||
|
@ -194,7 +194,7 @@ every time.
|
||||||
The ``condition`` decorator only sets validator headers (``ETag`` and
|
The ``condition`` decorator only sets validator headers (``ETag`` and
|
||||||
``Last-Modified``) for safe HTTP methods, i.e. ``GET`` and ``HEAD``. If you
|
``Last-Modified``) for safe HTTP methods, i.e. ``GET`` and ``HEAD``. If you
|
||||||
wish to return them in other cases, set them in your view. See
|
wish to return them in other cases, set them in your view. See
|
||||||
:rfc:`7231#section-4.3.4` to learn about the distinction between setting a
|
:rfc:`9110#section-9.3.4` to learn about the distinction between setting a
|
||||||
validator header in response to requests made with ``PUT`` versus ``POST``.
|
validator header in response to requests made with ``PUT`` versus ``POST``.
|
||||||
|
|
||||||
Comparison with middleware conditional processing
|
Comparison with middleware conditional processing
|
||||||
|
|
|
@ -350,7 +350,7 @@ Use the ``django.test.Client`` class to make requests.
|
||||||
``Response`` object. Useful for simulating diagnostic probes.
|
``Response`` object. Useful for simulating diagnostic probes.
|
||||||
|
|
||||||
Unlike the other request methods, ``data`` is not provided as a keyword
|
Unlike the other request methods, ``data`` is not provided as a keyword
|
||||||
parameter in order to comply with :rfc:`7231#section-4.3.8`, which
|
parameter in order to comply with :rfc:`9110#section-9.3.8`, which
|
||||||
mandates that TRACE requests must not have a body.
|
mandates that TRACE requests must not have a body.
|
||||||
|
|
||||||
The ``follow``, ``secure``, and ``extra`` arguments act the same as for
|
The ``follow``, ``secure``, and ``extra`` arguments act the same as for
|
||||||
|
|
|
@ -122,8 +122,8 @@ class UserManagerTestCase(TransactionTestCase):
|
||||||
self.assertFalse(user.has_usable_password())
|
self.assertFalse(user.has_usable_password())
|
||||||
|
|
||||||
def test_create_user_email_domain_normalize_rfc3696(self):
|
def test_create_user_email_domain_normalize_rfc3696(self):
|
||||||
# According to https://tools.ietf.org/html/rfc3696#section-3
|
# According to RFC 3696 Section 3 the "@" symbol can be part of the
|
||||||
# the "@" symbol can be part of the local part of an email address
|
# local part of an email address.
|
||||||
returned = UserManager.normalize_email(r"Abc\@DEF@EXAMPLE.com")
|
returned = UserManager.normalize_email(r"Abc\@DEF@EXAMPLE.com")
|
||||||
self.assertEqual(returned, r"Abc\@DEF@example.com")
|
self.assertEqual(returned, r"Abc\@DEF@example.com")
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ class ConditionalGet(SimpleTestCase):
|
||||||
self.assertEqual(response.status_code, 412)
|
self.assertEqual(response.status_code, 412)
|
||||||
|
|
||||||
def test_both_headers(self):
|
def test_both_headers(self):
|
||||||
# see https://tools.ietf.org/html/rfc7232#section-6
|
# See RFC 9110 Section 13.2.2.
|
||||||
self.client.defaults["HTTP_IF_MODIFIED_SINCE"] = LAST_MODIFIED_STR
|
self.client.defaults["HTTP_IF_MODIFIED_SINCE"] = LAST_MODIFIED_STR
|
||||||
self.client.defaults["HTTP_IF_NONE_MATCH"] = ETAG
|
self.client.defaults["HTTP_IF_NONE_MATCH"] = ETAG
|
||||||
response = self.client.get("/condition/")
|
response = self.client.get("/condition/")
|
||||||
|
|
|
@ -189,8 +189,7 @@ class FileUploadTests(TestCase):
|
||||||
|
|
||||||
def test_unicode_file_name_rfc2231(self):
|
def test_unicode_file_name_rfc2231(self):
|
||||||
"""
|
"""
|
||||||
Test receiving file upload when filename is encoded with RFC2231
|
Receiving file upload when filename is encoded with RFC 2231.
|
||||||
(#22971).
|
|
||||||
"""
|
"""
|
||||||
payload = client.FakePayload()
|
payload = client.FakePayload()
|
||||||
payload.write(
|
payload.write(
|
||||||
|
@ -219,8 +218,7 @@ class FileUploadTests(TestCase):
|
||||||
|
|
||||||
def test_unicode_name_rfc2231(self):
|
def test_unicode_name_rfc2231(self):
|
||||||
"""
|
"""
|
||||||
Test receiving file upload when filename is encoded with RFC2231
|
Receiving file upload when filename is encoded with RFC 2231.
|
||||||
(#22971).
|
|
||||||
"""
|
"""
|
||||||
payload = client.FakePayload()
|
payload = client.FakePayload()
|
||||||
payload.write(
|
payload.write(
|
||||||
|
|
|
@ -1234,8 +1234,8 @@ class BaseEmailBackendTests(HeadersCheckMixin):
|
||||||
|
|
||||||
def test_send_long_lines(self):
|
def test_send_long_lines(self):
|
||||||
"""
|
"""
|
||||||
Email line length is limited to 998 chars by the RFC:
|
Email line length is limited to 998 chars by the RFC 5322 Section
|
||||||
https://tools.ietf.org/html/rfc5322#section-2.1.1
|
2.1.1.
|
||||||
Message body containing longer lines are converted to Quoted-Printable
|
Message body containing longer lines are converted to Quoted-Printable
|
||||||
to avoid having to insert newlines, which could be hairy to do properly.
|
to avoid having to insert newlines, which could be hairy to do properly.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -640,7 +640,7 @@ class ConditionalGetMiddlewareTest(SimpleTestCase):
|
||||||
def test_not_modified_headers(self):
|
def test_not_modified_headers(self):
|
||||||
"""
|
"""
|
||||||
The 304 Not Modified response should include only the headers required
|
The 304 Not Modified response should include only the headers required
|
||||||
by section 4.1 of RFC 7232, Last-Modified, and the cookies.
|
by RFC 9110 Section 15.4.5, Last-Modified, and the cookies.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_response(req):
|
def get_response(req):
|
||||||
|
|
|
@ -425,10 +425,8 @@ class RequestsTests(SimpleTestCase):
|
||||||
Multipart POST requests with Content-Length >= 0 are valid and need to
|
Multipart POST requests with Content-Length >= 0 are valid and need to
|
||||||
be handled.
|
be handled.
|
||||||
"""
|
"""
|
||||||
# According to:
|
# According to RFC 9110 Section 8.6 every POST with Content-Length >= 0
|
||||||
# https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
|
# is a valid request, so ensure that we handle Content-Length == 0.
|
||||||
# Every request.POST with Content-Length >= 0 is a valid request,
|
|
||||||
# this test ensures that we handle Content-Length == 0.
|
|
||||||
payload = FakePayload(
|
payload = FakePayload(
|
||||||
"\r\n".join(
|
"\r\n".join(
|
||||||
[
|
[
|
||||||
|
|
|
@ -395,8 +395,7 @@ def django_project_redirect(request):
|
||||||
|
|
||||||
def no_trailing_slash_external_redirect(request):
|
def no_trailing_slash_external_redirect(request):
|
||||||
"""
|
"""
|
||||||
RFC 2616 3.2.2: A bare domain without any abs_path element should be
|
RFC 3986 Section 6.2.3: Empty path should be normalized to "/".
|
||||||
treated as having the trailing `/`.
|
|
||||||
|
|
||||||
Use https://testserver, rather than an external domain, in order to allow
|
Use https://testserver, rather than an external domain, in order to allow
|
||||||
use of follow=True, triggering Client._handle_redirects().
|
use of follow=True, triggering Client._handle_redirects().
|
||||||
|
|
|
@ -329,7 +329,7 @@ class ETagProcessingTests(unittest.TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(parse_etags("*"), ["*"])
|
self.assertEqual(parse_etags("*"), ["*"])
|
||||||
|
|
||||||
# Ignore RFC 2616 ETags that are invalid according to RFC 7232.
|
# Ignore RFC 2616 ETags that are invalid according to RFC 9110.
|
||||||
self.assertEqual(parse_etags(r'"etag", "e\"t\"ag"'), ['"etag"'])
|
self.assertEqual(parse_etags(r'"etag", "e\"t\"ag"'), ['"etag"'])
|
||||||
|
|
||||||
def test_quoting(self):
|
def test_quoting(self):
|
||||||
|
|
|
@ -32,7 +32,7 @@ class TestUtilsIPv6(unittest.TestCase):
|
||||||
self.assertFalse(is_valid_ipv6_address("::ffff:999.42.16.14"))
|
self.assertFalse(is_valid_ipv6_address("::ffff:999.42.16.14"))
|
||||||
self.assertFalse(is_valid_ipv6_address("::ffff:zzzz:0a0a"))
|
self.assertFalse(is_valid_ipv6_address("::ffff:zzzz:0a0a"))
|
||||||
# The ::1.2.3.4 format used to be valid but was deprecated
|
# The ::1.2.3.4 format used to be valid but was deprecated
|
||||||
# in rfc4291 section 2.5.5.1
|
# in RFC 4291 section 2.5.5.1.
|
||||||
self.assertTrue(is_valid_ipv6_address("::254.42.16.14"))
|
self.assertTrue(is_valid_ipv6_address("::254.42.16.14"))
|
||||||
self.assertTrue(is_valid_ipv6_address("::0a0a:0a0a"))
|
self.assertTrue(is_valid_ipv6_address("::0a0a:0a0a"))
|
||||||
self.assertFalse(is_valid_ipv6_address("::999.42.16.14"))
|
self.assertFalse(is_valid_ipv6_address("::999.42.16.14"))
|
||||||
|
|
|
@ -83,7 +83,7 @@ class StaticTests(SimpleTestCase):
|
||||||
"""Handle bogus If-Modified-Since values gracefully
|
"""Handle bogus If-Modified-Since values gracefully
|
||||||
|
|
||||||
Assume that a file is modified since an invalid timestamp as per RFC
|
Assume that a file is modified since an invalid timestamp as per RFC
|
||||||
2616, section 14.25.
|
9110 Section 13.1.3.
|
||||||
"""
|
"""
|
||||||
file_name = "file.txt"
|
file_name = "file.txt"
|
||||||
invalid_date = "Mon, 28 May 999999999999 28:25:26 GMT"
|
invalid_date = "Mon, 28 May 999999999999 28:25:26 GMT"
|
||||||
|
@ -99,7 +99,7 @@ class StaticTests(SimpleTestCase):
|
||||||
"""Handle even more bogus If-Modified-Since values gracefully
|
"""Handle even more bogus If-Modified-Since values gracefully
|
||||||
|
|
||||||
Assume that a file is modified since an invalid timestamp as per RFC
|
Assume that a file is modified since an invalid timestamp as per RFC
|
||||||
2616, section 14.25.
|
9110 Section 13.1.3.
|
||||||
"""
|
"""
|
||||||
file_name = "file.txt"
|
file_name = "file.txt"
|
||||||
invalid_date = ": 1291108438, Wed, 20 Oct 2010 14:05:00 GMT"
|
invalid_date = ": 1291108438, Wed, 20 Oct 2010 14:05:00 GMT"
|
||||||
|
|
Loading…
Reference in New Issue