Skip to content

Commit

Permalink
gh-102247: http: support rfc9110 status codes
Browse files Browse the repository at this point in the history
rfc9110 obsoletes the earlier rfc 7231. This document also includes some
status codes that were previously only used for WebDAV and assigns more
generic names to these status codes.

ref: https://www.rfc-editor.org/rfc/rfc9110.html#name-changes-from-rfc-7231

- http.HTTPStatus.CONTENT_TOO_LARGE (413, previously
  REQUEST_ENTITY_TOO_LARGE)
- http.HTTPStatus.URI_TOO_LONG (414, previously REQUEST_URI_TOO_LONG)
- http.HTTPStatus.RANGE_NOT_SATISFYABLE (416, previously
  REQUEST_RANGE_NOT_SATISFYABLE)
- http.HTTPStatus.UNPROCESSABLE_CONTENT (422, previously
  UNPROCESSABLE_ENTITY)

The new constants are added to http.HTTPStatus and the old constants are
preserved for backwards compatibility.

References in documentation to the obsoleted rfc 7231 are updated
  • Loading branch information
mbeijen committed Apr 9, 2024
1 parent 22b25d1 commit 51858f5
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 76 deletions.
124 changes: 64 additions & 60 deletions Doc/library/http.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,63 +59,63 @@ available in :class:`http.HTTPStatus` are:
======= =================================== ==================================================================
Code Enum Name Details
======= =================================== ==================================================================
``100`` ``CONTINUE`` HTTP/1.1 :rfc:`7231`, Section 6.2.1
``101`` ``SWITCHING_PROTOCOLS`` HTTP/1.1 :rfc:`7231`, Section 6.2.2
``100`` ``CONTINUE`` HTTP Semantics :rfc:`9110`, Section 15.2.1
``101`` ``SWITCHING_PROTOCOLS`` HTTP Semantics :rfc:`9110`, Section 15.2.2
``102`` ``PROCESSING`` WebDAV :rfc:`2518`, Section 10.1
``103`` ``EARLY_HINTS`` An HTTP Status Code for Indicating Hints :rfc:`8297`
``200`` ``OK`` HTTP/1.1 :rfc:`7231`, Section 6.3.1
``201`` ``CREATED`` HTTP/1.1 :rfc:`7231`, Section 6.3.2
``202`` ``ACCEPTED`` HTTP/1.1 :rfc:`7231`, Section 6.3.3
``203`` ``NON_AUTHORITATIVE_INFORMATION`` HTTP/1.1 :rfc:`7231`, Section 6.3.4
``204`` ``NO_CONTENT`` HTTP/1.1 :rfc:`7231`, Section 6.3.5
``205`` ``RESET_CONTENT`` HTTP/1.1 :rfc:`7231`, Section 6.3.6
``206`` ``PARTIAL_CONTENT`` HTTP/1.1 :rfc:`7233`, Section 4.1
``200`` ``OK`` HTTP Semantics :rfc:`9110`, Section 15.3.1
``201`` ``CREATED`` HTTP Semantics :rfc:`9110`, Section 15.3.2
``202`` ``ACCEPTED`` HTTP Semantics :rfc:`9110`, Section 15.3.3
``203`` ``NON_AUTHORITATIVE_INFORMATION`` HTTP Semantics :rfc:`9110`, Section 15.3.4
``204`` ``NO_CONTENT`` HTTP Semantics :rfc:`9110`, Section 15.3.5
``205`` ``RESET_CONTENT`` HTTP Semantics :rfc:`9110`, Section 15.3.6
``206`` ``PARTIAL_CONTENT`` HTTP Semantics :rfc:`9110`, Section 15.3.7
``207`` ``MULTI_STATUS`` WebDAV :rfc:`4918`, Section 11.1
``208`` ``ALREADY_REPORTED`` WebDAV Binding Extensions :rfc:`5842`, Section 7.1 (Experimental)
``226`` ``IM_USED`` Delta Encoding in HTTP :rfc:`3229`, Section 10.4.1
``300`` ``MULTIPLE_CHOICES`` HTTP/1.1 :rfc:`7231`, Section 6.4.1
``301`` ``MOVED_PERMANENTLY`` HTTP/1.1 :rfc:`7231`, Section 6.4.2
``302`` ``FOUND`` HTTP/1.1 :rfc:`7231`, Section 6.4.3
``303`` ``SEE_OTHER`` HTTP/1.1 :rfc:`7231`, Section 6.4.4
``304`` ``NOT_MODIFIED`` HTTP/1.1 :rfc:`7232`, Section 4.1
``305`` ``USE_PROXY`` HTTP/1.1 :rfc:`7231`, Section 6.4.5
``307`` ``TEMPORARY_REDIRECT`` HTTP/1.1 :rfc:`7231`, Section 6.4.7
``308`` ``PERMANENT_REDIRECT`` Permanent Redirect :rfc:`7238`, Section 3 (Experimental)
``400`` ``BAD_REQUEST`` HTTP/1.1 :rfc:`7231`, Section 6.5.1
``401`` ``UNAUTHORIZED`` HTTP/1.1 Authentication :rfc:`7235`, Section 3.1
``402`` ``PAYMENT_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.2
``403`` ``FORBIDDEN`` HTTP/1.1 :rfc:`7231`, Section 6.5.3
``404`` ``NOT_FOUND`` HTTP/1.1 :rfc:`7231`, Section 6.5.4
``405`` ``METHOD_NOT_ALLOWED`` HTTP/1.1 :rfc:`7231`, Section 6.5.5
``406`` ``NOT_ACCEPTABLE`` HTTP/1.1 :rfc:`7231`, Section 6.5.6
``407`` ``PROXY_AUTHENTICATION_REQUIRED`` HTTP/1.1 Authentication :rfc:`7235`, Section 3.2
``408`` ``REQUEST_TIMEOUT`` HTTP/1.1 :rfc:`7231`, Section 6.5.7
``409`` ``CONFLICT`` HTTP/1.1 :rfc:`7231`, Section 6.5.8
``410`` ``GONE`` HTTP/1.1 :rfc:`7231`, Section 6.5.9
``411`` ``LENGTH_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.10
``412`` ``PRECONDITION_FAILED`` HTTP/1.1 :rfc:`7232`, Section 4.2
``413`` ``REQUEST_ENTITY_TOO_LARGE`` HTTP/1.1 :rfc:`7231`, Section 6.5.11
``414`` ``REQUEST_URI_TOO_LONG`` HTTP/1.1 :rfc:`7231`, Section 6.5.12
``415`` ``UNSUPPORTED_MEDIA_TYPE`` HTTP/1.1 :rfc:`7231`, Section 6.5.13
``416`` ``REQUESTED_RANGE_NOT_SATISFIABLE`` HTTP/1.1 Range Requests :rfc:`7233`, Section 4.4
``417`` ``EXPECTATION_FAILED`` HTTP/1.1 :rfc:`7231`, Section 6.5.14
``300`` ``MULTIPLE_CHOICES`` HTTP Semantics :rfc:`9110`, Section 15.4.1
``301`` ``MOVED_PERMANENTLY`` HTTP Semantics :rfc:`9110`, Section 15.4.2
``302`` ``FOUND`` HTTP Semantics :rfc:`9110`, Section 15.4.3
``303`` ``SEE_OTHER`` HTTP Semantics :rfc:`9110`, Section 15.4.4
``304`` ``NOT_MODIFIED`` HTTP Semantics :rfc:`9110`, Section 15.4.5
``305`` ``USE_PROXY`` HTTP Semantics :rfc:`9110`, Section 15.4.6
``307`` ``TEMPORARY_REDIRECT`` HTTP Semantics :rfc:`9110`, Section 15.4.8
``308`` ``PERMANENT_REDIRECT`` HTTP Semantics :rfc:`9110`, Section 15.4.9
``400`` ``BAD_REQUEST`` HTTP Semantics :rfc:`9110`, Section 15.5.1
``401`` ``UNAUTHORIZED`` HTTP Semantics :rfc:`9110`, Section 15.5.2
``402`` ``PAYMENT_REQUIRED`` HTTP Semantics :rfc:`9110`, Section 15.5.3
``403`` ``FORBIDDEN`` HTTP Semantics :rfc:`9110`, Section 15.5.4
``404`` ``NOT_FOUND`` HTTP Semantics :rfc:`9110`, Section 15.5.5
``405`` ``METHOD_NOT_ALLOWED`` HTTP Semantics :rfc:`9110`, Section 15.5.6
``406`` ``NOT_ACCEPTABLE`` HTTP Semantics :rfc:`9110`, Section 15.5.7
``407`` ``PROXY_AUTHENTICATION_REQUIRED`` HTTP Semantics :rfc:`9110`, Section 15.5.8
``408`` ``REQUEST_TIMEOUT`` HTTP Semantics :rfc:`9110`, Section 15.5.9
``409`` ``CONFLICT`` HTTP Semantics :rfc:`9110`, Section 15.5.10
``410`` ``GONE`` HTTP Semantics :rfc:`9110`, Section 15.5.11
``411`` ``LENGTH_REQUIRED`` HTTP Semantics :rfc:`9110`, Section 15.5.12
``412`` ``PRECONDITION_FAILED`` HTTP Semantics :rfc:`9110`, Section 15.5.13
``413`` ``CONTENT_TOO_LARGE`` HTTP Semantics :rfc:`9110`, Section 15.5.14
``414`` ``URI_TOO_LONG`` HTTP Semantics :rfc:`9110`, Section 15.5.15
``415`` ``UNSUPPORTED_MEDIA_TYPE`` HTTP Semantics :rfc:`9110`, Section 15.5.16
``416`` ``RANGE_NOT_SATISFIABLE`` HTTP Semantics :rfc:`9110`, Section 15.5.17
``417`` ``EXPECTATION_FAILED`` HTTP Semantics :rfc:`9110`, Section 15.5.18
``418`` ``IM_A_TEAPOT`` HTCPCP/1.0 :rfc:`2324`, Section 2.3.2
``421`` ``MISDIRECTED_REQUEST`` HTTP/2 :rfc:`7540`, Section 9.1.2
``422`` ``UNPROCESSABLE_ENTITY`` WebDAV :rfc:`4918`, Section 11.2
``421`` ``MISDIRECTED_REQUEST`` HTTP Semantics :rfc:`9110`, Section 15.5.20
``422`` ``UNPROCESSABLE_CONTENT`` HTTP Semantics :rfc:`9110`, Section 15.5.21
``423`` ``LOCKED`` WebDAV :rfc:`4918`, Section 11.3
``424`` ``FAILED_DEPENDENCY`` WebDAV :rfc:`4918`, Section 11.4
``425`` ``TOO_EARLY`` Using Early Data in HTTP :rfc:`8470`
``426`` ``UPGRADE_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.15
``426`` ``UPGRADE_REQUIRED`` HTTP Semantics :rfc:`9110`, Section 15.5.22
``428`` ``PRECONDITION_REQUIRED`` Additional HTTP Status Codes :rfc:`6585`
``429`` ``TOO_MANY_REQUESTS`` Additional HTTP Status Codes :rfc:`6585`
``431`` ``REQUEST_HEADER_FIELDS_TOO_LARGE`` Additional HTTP Status Codes :rfc:`6585`
``451`` ``UNAVAILABLE_FOR_LEGAL_REASONS`` An HTTP Status Code to Report Legal Obstacles :rfc:`7725`
``500`` ``INTERNAL_SERVER_ERROR`` HTTP/1.1 :rfc:`7231`, Section 6.6.1
``501`` ``NOT_IMPLEMENTED`` HTTP/1.1 :rfc:`7231`, Section 6.6.2
``502`` ``BAD_GATEWAY`` HTTP/1.1 :rfc:`7231`, Section 6.6.3
``503`` ``SERVICE_UNAVAILABLE`` HTTP/1.1 :rfc:`7231`, Section 6.6.4
``504`` ``GATEWAY_TIMEOUT`` HTTP/1.1 :rfc:`7231`, Section 6.6.5
``505`` ``HTTP_VERSION_NOT_SUPPORTED`` HTTP/1.1 :rfc:`7231`, Section 6.6.6
``500`` ``INTERNAL_SERVER_ERROR`` HTTP Semantics :rfc:`9110`, Section 15.6.1
``501`` ``NOT_IMPLEMENTED`` HTTP Semantics :rfc:`9110`, Section 15.6.2
``502`` ``BAD_GATEWAY`` HTTP Semantics :rfc:`9110`, Section 15.6.3
``503`` ``SERVICE_UNAVAILABLE`` HTTP Semantics :rfc:`9110`, Section 15.6.4
``504`` ``GATEWAY_TIMEOUT`` HTTP Semantics :rfc:`9110`, Section 15.6.5
``505`` ``HTTP_VERSION_NOT_SUPPORTED`` HTTP Semantics :rfc:`9110`, Section 15.6.6
``506`` ``VARIANT_ALSO_NEGOTIATES`` Transparent Content Negotiation in HTTP :rfc:`2295`, Section 8.1 (Experimental)
``507`` ``INSUFFICIENT_STORAGE`` WebDAV :rfc:`4918`, Section 11.5
``508`` ``LOOP_DETECTED`` WebDAV Binding Extensions :rfc:`5842`, Section 7.2 (Experimental)
Expand All @@ -137,22 +137,26 @@ equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as
.. versionadded:: 3.9
Added ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` status codes.

.. versionchanged:: 3.13
Implemented RFC9110 naming for status constants. Old constant names are preserved for
backwards compatibility.

HTTP status category
--------------------

.. versionadded:: 3.12

The enum values have several properties to indicate the HTTP status category:

==================== ======================== ===============================
==================== ======================== ======================================
Property Indicates that Details
==================== ======================== ===============================
``is_informational`` ``100 <= status <= 199`` HTTP/1.1 :rfc:`7231`, Section 6
``is_success`` ``200 <= status <= 299`` HTTP/1.1 :rfc:`7231`, Section 6
``is_redirection`` ``300 <= status <= 399`` HTTP/1.1 :rfc:`7231`, Section 6
``is_client_error`` ``400 <= status <= 499`` HTTP/1.1 :rfc:`7231`, Section 6
``is_server_error`` ``500 <= status <= 599`` HTTP/1.1 :rfc:`7231`, Section 6
==================== ======================== ===============================
==================== ======================== ======================================
``is_informational`` ``100 <= status <= 199`` HTTP Semantics :rfc:`9110`, Section 15
``is_success`` ``200 <= status <= 299`` HTTP Semantics :rfc:`9110`, Section 15
``is_redirection`` ``300 <= status <= 399`` HTTP Semantics :rfc:`9110`, Section 15
``is_client_error`` ``400 <= status <= 499`` HTTP Semantics :rfc:`9110`, Section 15
``is_server_error`` ``500 <= status <= 599`` HTTP Semantics :rfc:`9110`, Section 15
==================== ======================== ======================================

Usage::

Expand Down Expand Up @@ -203,13 +207,13 @@ available in :class:`http.HTTPMethod` are:
=========== =================================== ==================================================================
Method Enum Name Details
=========== =================================== ==================================================================
``GET`` ``GET`` HTTP/1.1 :rfc:`7231`, Section 4.3.1
``HEAD`` ``HEAD`` HTTP/1.1 :rfc:`7231`, Section 4.3.2
``POST`` ``POST`` HTTP/1.1 :rfc:`7231`, Section 4.3.3
``PUT`` ``PUT`` HTTP/1.1 :rfc:`7231`, Section 4.3.4
``DELETE`` ``DELETE`` HTTP/1.1 :rfc:`7231`, Section 4.3.5
``CONNECT`` ``CONNECT`` HTTP/1.1 :rfc:`7231`, Section 4.3.6
``OPTIONS`` ``OPTIONS`` HTTP/1.1 :rfc:`7231`, Section 4.3.7
``TRACE`` ``TRACE`` HTTP/1.1 :rfc:`7231`, Section 4.3.8
``GET`` ``GET`` HTTP Semantics :rfc:`9110`, Section 9.3.1
``HEAD`` ``HEAD`` HTTP Semantics :rfc:`9110`, Section 9.3.2
``POST`` ``POST`` HTTP Semantics :rfc:`9110`, Section 9.3.3
``PUT`` ``PUT`` HTTP Semantics :rfc:`9110`, Section 9.3.4
``DELETE`` ``DELETE`` HTTP Semantics :rfc:`9110`, Section 9.3.5
``CONNECT`` ``CONNECT`` HTTP Semantics :rfc:`9110`, Section 9.3.6
``OPTIONS`` ``OPTIONS`` HTTP Semantics :rfc:`9110`, Section 9.3.7
``TRACE`` ``TRACE`` HTTP Semantics :rfc:`9110`, Section 9.3.8
``PATCH`` ``PATCH`` HTTP/1.1 :rfc:`5789`
=========== =================================== ==================================================================
20 changes: 11 additions & 9 deletions Lib/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class HTTPStatus:
Status codes from the following RFCs are all observed:
* RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616
* RFC 9110: HTTP Semantics, obsoletes 7231, which obsoleted 2616
* RFC 6585: Additional HTTP Status Codes
* RFC 3229: Delta encoding in HTTP
* RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518
Expand All @@ -26,7 +26,6 @@ class HTTPStatus:
def __new__(cls, value, phrase, description=''):
obj = int.__new__(cls, value)
obj._value_ = value

obj.phrase = phrase
obj.description = description
return obj
Expand Down Expand Up @@ -115,22 +114,25 @@ def is_server_error(self):
'Client must specify Content-Length')
PRECONDITION_FAILED = (412, 'Precondition Failed',
'Precondition in headers is false')
REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large',
'Entity is too large')
REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long',
CONTENT_TOO_LARGE = (413, 'Content Too Large',
'Content is too large')
REQUEST_ENTITY_TOO_LARGE = CONTENT_TOO_LARGE
URI_TOO_LONG = (414, 'URI Too Long',
'URI is too long')
REQUEST_URI_TOO_LONG = URI_TOO_LONG
UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type',
'Entity body in unsupported format')
REQUESTED_RANGE_NOT_SATISFIABLE = (416,
'Requested Range Not Satisfiable',
RANGE_NOT_SATISFIABLE = (416, 'Range Not Satisfiable',
'Cannot satisfy request range')
REQUESTED_RANGE_NOT_SATISFIABLE = RANGE_NOT_SATISFIABLE
EXPECTATION_FAILED = (417, 'Expectation Failed',
'Expect condition could not be satisfied')
IM_A_TEAPOT = (418, 'I\'m a Teapot',
'Server refuses to brew coffee because it is a teapot.')
MISDIRECTED_REQUEST = (421, 'Misdirected Request',
'Server is not able to produce a response')
UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity'
UNPROCESSABLE_CONTENT = 422, 'Unprocessable Content'
UNPROCESSABLE_ENTITY = UNPROCESSABLE_CONTENT
LOCKED = 423, 'Locked'
FAILED_DEPENDENCY = 424, 'Failed Dependency'
TOO_EARLY = 425, 'Too Early'
Expand Down Expand Up @@ -177,7 +179,7 @@ class HTTPMethod:
Methods from the following RFCs are all observed:
* RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616
* RFF 9110: HTTP Semantics, obsoletes 7231, which obsoleted 2616
* RFC 5789: PATCH Method for HTTP
"""
def __new__(cls, value, description):
Expand Down
21 changes: 14 additions & 7 deletions Lib/test/test_httplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,22 +651,25 @@ def is_server_error(self):
'Client must specify Content-Length')
PRECONDITION_FAILED = (412, 'Precondition Failed',
'Precondition in headers is false')
REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large',
'Entity is too large')
REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long',
'URI is too long')
CONTENT_TOO_LARGE = (413, 'Content Too Large',
'Content is too large')
REQUEST_ENTITY_TOO_LARGE = CONTENT_TOO_LARGE
URI_TOO_LONG = (414, 'URI Too Long', 'URI is too long')
REQUEST_URI_TOO_LONG = URI_TOO_LONG
UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type',
'Entity body in unsupported format')
REQUESTED_RANGE_NOT_SATISFIABLE = (416,
'Requested Range Not Satisfiable',
RANGE_NOT_SATISFIABLE = (416,
'Range Not Satisfiable',
'Cannot satisfy request range')
REQUESTED_RANGE_NOT_SATISFIABLE = RANGE_NOT_SATISFIABLE
EXPECTATION_FAILED = (417, 'Expectation Failed',
'Expect condition could not be satisfied')
IM_A_TEAPOT = (418, 'I\'m a Teapot',
'Server refuses to brew coffee because it is a teapot.')
MISDIRECTED_REQUEST = (421, 'Misdirected Request',
'Server is not able to produce a response')
UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity'
UNPROCESSABLE_CONTENT = 422, 'Unprocessable Content'
UNPROCESSABLE_ENTITY = UNPROCESSABLE_CONTENT
LOCKED = 423, 'Locked'
FAILED_DEPENDENCY = 424, 'Failed Dependency'
TOO_EARLY = 425, 'Too Early'
Expand Down Expand Up @@ -1718,13 +1721,17 @@ def test_client_constants(self):
'GONE',
'LENGTH_REQUIRED',
'PRECONDITION_FAILED',
'CONTENT_TOO_LARGE',
'REQUEST_ENTITY_TOO_LARGE',
'URI_TOO_LONG',
'REQUEST_URI_TOO_LONG',
'UNSUPPORTED_MEDIA_TYPE',
'RANGE_NOT_SATISFIABLE',
'REQUESTED_RANGE_NOT_SATISFIABLE',
'EXPECTATION_FAILED',
'IM_A_TEAPOT',
'MISDIRECTED_REQUEST',
'UNPROCESSABLE_CONTENT',
'UNPROCESSABLE_ENTITY',
'LOCKED',
'FAILED_DEPENDENCY',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
the status codes enum with constants in http.HTTPStatus are updated to include the names from RFC9110. This RFC includes some HTTP statuses previously only used for WEBDAV and assigns more generic names to them.

The old constants are preserved for backwards compatibility.

0 comments on commit 51858f5

Please sign in to comment.