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:
Nick Pope 2022-11-04 12:33:09 +00:00 committed by Mariusz Felisiak
parent fad070b07b
commit 9bd174b9a7
34 changed files with 97 additions and 103 deletions

View File

@ -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

View File

@ -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()

View File

@ -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))``.

View File

@ -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)

View File

@ -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('"'):

View File

@ -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

View File

@ -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

View File

@ -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.
""" """

View File

@ -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.

View File

@ -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() == "*":

View File

@ -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", "*"

View File

@ -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)

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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::

View File

@ -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`.

View File

@ -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:

View File

@ -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``,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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/")

View File

@ -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(

View File

@ -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.
""" """

View File

@ -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):

View File

@ -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(
[ [

View File

@ -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().

View File

@ -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):

View File

@ -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"))

View File

@ -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"