Skip to content

Commit

Permalink
Updated documentation and comments for RFC updates.
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
ngnpope authored and felixxm committed Nov 10, 2022
1 parent fad070b commit 9bd174b
Show file tree
Hide file tree
Showing 34 changed files with 97 additions and 103 deletions.
2 changes: 1 addition & 1 deletion django/core/handlers/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def __init__(self, environ):
self.path_info = path_info
# be careful to only replace the first slash in the path because of
# 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.META = environ
self.META["PATH_INFO"] = path_info
Expand Down
6 changes: 3 additions & 3 deletions django/core/mail/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class BadHeaderError(ValueError):
pass


# Header names that contain structured address data (RFC #5322)
# Header names that contain structured address data (RFC 5322).
ADDRESS_HEADERS = {
"from",
"sender",
Expand Down Expand Up @@ -382,8 +382,8 @@ def _create_mime_attachment(self, content, mimetype):
encoding = self.encoding or settings.DEFAULT_CHARSET
attachment = SafeMIMEText(content, subtype, encoding)
elif basetype == "message" and subtype == "rfc822":
# Bug #18967: per RFC2046 s5.2.1, message/rfc822 attachments
# must not be base64 encoded.
# Bug #18967: Per RFC 2046 Section 5.2.1, message/rfc822
# attachments must not be base64 encoded.
if isinstance(content, EmailMessage):
# convert content into an email.Message first
content = content.message()
Expand Down
2 changes: 1 addition & 1 deletion django/http/multipartparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class InputStreamExhausted(Exception):

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
and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``.
Expand Down
2 changes: 1 addition & 1 deletion django/middleware/csrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ def process_view(self, request, callback, callback_args, callback_kwargs):
if getattr(callback, "csrf_exempt", False):
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"):
return self._accept(request)

Expand Down
2 changes: 1 addition & 1 deletion django/middleware/gzip.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def process_response(self, request, response):
response.headers["Content-Length"] = str(len(response.content))

# 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.
etag = response.get("ETag")
if etag and etag.startswith('"'):
Expand Down
4 changes: 2 additions & 2 deletions django/test/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def conditional_content_removal(request, response):
"""
Simulate the behavior of most web servers by removing the content of
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 response.streaming:
Expand Down Expand Up @@ -987,7 +987,7 @@ def _handle_redirects(self, response, data="", content_type="", **extra):
extra["SERVER_PORT"] = str(url.port)

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:
path = "/"
# Prepend the request path to handle relative path redirects
Expand Down
21 changes: 11 additions & 10 deletions django/utils/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
header of response objects directly and decorators that change functions to do
that header-patching themselves.
For information on the Vary header, see:
https://tools.ietf.org/html/rfc7231#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
into account when building its cache key. Requests with the same path but
Expand Down Expand Up @@ -139,7 +137,7 @@ def _precondition_failed(request):
def _not_modified(request, response=None):
new_response = HttpResponseNotModified()
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.
for header in (
"Cache-Control",
Expand Down Expand Up @@ -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 = 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):
return _precondition_failed(request)

Expand Down Expand Up @@ -212,7 +212,7 @@ def get_conditional_response(request, etag=None, last_modified=None, response=No

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 there isn't an ETag, then there can't be a match.
Expand All @@ -233,15 +233,15 @@ def _if_match_passes(target_etag, etags):

def _if_unmodified_since_passes(last_modified, if_unmodified_since):
"""
Test the If-Unmodified-Since comparison as defined in section 3.4 of
RFC 7232.
Test the If-Unmodified-Since comparison as defined in RFC 9110 Section
13.1.4.
"""
return last_modified and last_modified <= if_unmodified_since


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 there isn't an ETag, then there isn't a match.
Expand All @@ -260,7 +260,8 @@ def _if_none_match_passes(target_etag, etags):

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

Expand Down
19 changes: 9 additions & 10 deletions django/utils/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,15 @@ def iri_to_uri(iri):
Convert an Internationalized Resource Identifier (IRI) portion to a URI
portion that is suitable for inclusion in a URL.
This is the algorithm from section 3.1 of RFC 3987, slightly simplified
since the input is assumed to be a string rather than an arbitrary byte
stream.
This is the algorithm from RFC 3987 Section 3.1, slightly simplified since
the input is assumed to be a string rather than an arbitrary byte stream.
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
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
# "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
# gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
Expand All @@ -130,7 +129,7 @@ def iri_to_uri(iri):
# Of the unreserved characters, urllib.parse.quote() already considers all
# but the ~ safe.
# 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.
if iri is None:
return iri
Expand Down Expand Up @@ -161,7 +160,7 @@ def uri_to_iri(uri):
Convert a Uniform Resource Identifier(URI) into an Internationalized
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
a string containing the encoded result (e.g. '/I%20♥%20Django/').
Expand Down Expand Up @@ -197,13 +196,13 @@ def escape_uri_path(path):
Escape the unsafe characters from the path portion of a Uniform Resource
Identifier (URI).
"""
# These are the "reserved" and "unreserved" characters specified in
# sections 2.2 and 2.3 of RFC 2396:
# These are the "reserved" and "unreserved" characters specified in RFC
# 3986 Sections 2.2 and 2.3:
# reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
# unreserved = alphanum | mark
# mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
# 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 entire path, not a path segment.
return quote(path, safe="/:@&+$,-_.!~*'()")
Expand All @@ -216,7 +215,7 @@ def punycode(domain):

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
UTF-8 octet sequence.
"""
Expand Down
5 changes: 2 additions & 3 deletions django/utils/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,8 @@ def smart_urlquote(url):

def unquote_quote(segment):
segment = unquote(segment)
# Tilde is part of RFC3986 Unreserved Characters
# https://tools.ietf.org/html/rfc3986#section-2.3
# See also https://bugs.python.org/issue16285
# Tilde is part of RFC 3986 Section 2.3 Unreserved Characters,
# see also https://bugs.python.org/issue16285
return quote(segment, safe=RFC3986_SUBDELIMS + RFC3986_GENDELIMS + "~")

# Handle IDN before quoting.
Expand Down
14 changes: 7 additions & 7 deletions django/utils/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from django.utils.datastructures import MultiValueDict
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(
r"""
\A( # start of string and capture group
Expand Down Expand Up @@ -94,8 +94,8 @@ def urlencode(query, doseq=False):

def http_date(epoch_seconds=None):
"""
Format the time to match the RFC1123 date format as specified by HTTP
RFC7231 section 7.1.1.1.
Format the time to match the RFC 5322 date format as specified by RFC 9110
Section 5.6.7.
`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
Expand All @@ -108,15 +108,15 @@ def http_date(epoch_seconds=None):

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
one is still in widespread use.
Return an integer expressed in seconds since the epoch, in UTC.
"""
# email.utils.parsedate() does the job for RFC1123 dates; unfortunately
# RFC7231 makes it mandatory to support RFC850 dates too. So we roll
# email.utils.parsedate() does the job for RFC 1123 dates; unfortunately
# RFC 9110 makes it mandatory to support RFC 850 dates too. So we roll
# our own RFC-compliant parsing.
for regex in RFC1123_DATE, RFC850_DATE, ASCTIME_DATE:
m = regex.match(date)
Expand Down Expand Up @@ -210,7 +210,7 @@ def urlsafe_base64_decode(s):
def parse_etags(etag_str):
"""
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.
"""
if etag_str.strip() == "*":
Expand Down
4 changes: 2 additions & 2 deletions django/utils/translation/trans_real.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
# magic gettext number to separate context from message
CONTEXT_SEPARATOR = "\x04"

# Format of Accept-Language header values. From RFC 2616, section 14.4 and 3.9
# and RFC 3066, section 2.1
# Format of Accept-Language header values. From RFC 9110 Sections 12.4.2 and
# 12.5.4, and RFC 5646 Section 2.1.
accept_language_re = _lazy_re_compile(
r"""
# "en", "en-au", "x-y-z", "es-419", "*"
Expand Down
2 changes: 1 addition & 1 deletion django/views/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def permission_denied(request, exception, template_name=ERROR_403_TEMPLATE_NAME)
supplied).
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:
template = loader.get_template(template_name)
Expand Down
6 changes: 3 additions & 3 deletions docs/ref/csrf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.

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
protected by the steps outlined in :ref:`using-csrf`.

Expand Down Expand Up @@ -90,9 +90,9 @@ This ensures that only forms that have originated from trusted domains can be
used to POST data back.

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

Expand Down
2 changes: 1 addition & 1 deletion docs/ref/middleware.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ It will NOT compress content if any of the following are true:
containing ``gzip``.

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
:func:`~django.views.decorators.gzip.gzip_page()` decorator.
Expand Down
2 changes: 1 addition & 1 deletion docs/ref/models/instances.txt
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ track down every place that the URL might be created. Specify it once, in

.. note::
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.

Code and templates calling ``get_absolute_url()`` should be able to use the
Expand Down
2 changes: 1 addition & 1 deletion docs/ref/models/querysets.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
``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
: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::

Expand Down
14 changes: 7 additions & 7 deletions docs/ref/request-response.txt
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ Attributes

.. 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
``status_code`` outside the constructor will also modify the value of
Expand All @@ -768,7 +768,7 @@ Attributes
.. attribute:: HttpResponse.reason_phrase

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
:attr:`status_code`.
Expand Down Expand Up @@ -803,9 +803,9 @@ Methods
:setting:`DEFAULT_CHARSET` settings, by default:
``"text/html; charset=utf-8"``.

``status`` is the :rfc:`HTTP status code <7231#section-6>` for the response.
You can use Python's :py:class:`http.HTTPStatus` for meaningful aliases,
such as ``HTTPStatus.NO_CONTENT``.
``status`` is the :rfc:`HTTP status code <9110#section-15>` for the
response. You can use Python's :py:class:`http.HTTPStatus` for meaningful
aliases, such as ``HTTPStatus.NO_CONTENT``.

``reason`` is the HTTP response phrase. If not provided, a default phrase
will be used.
Expand Down Expand Up @@ -1163,7 +1163,7 @@ Attributes

.. 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
``status_code`` outside the constructor will also modify the value of
Expand All @@ -1172,7 +1172,7 @@ Attributes
.. attribute:: StreamingHttpResponse.reason_phrase

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
:attr:`status_code`.
Expand Down
2 changes: 1 addition & 1 deletion docs/ref/unicode.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ URI and IRI handling
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.
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
converting an IRI to a URI:

Expand Down
Loading

0 comments on commit 9bd174b

Please sign in to comment.