1
0
mirror of https://github.com/django/django.git synced 2025-10-24 14:16:09 +00:00

Fixed #36411 -- Made HttpRequest.get_preferred_type() consider media type parameters.

HttpRequest.get_preferred_type() did not account for parameters in
Accept header media types (e.g., "text/vcard; version=3.0"). This caused
incorrect content negotiation when multiple types differed only by
parameters, reducing specificity as per RFC 7231 section 5.3.2
(https://datatracker.ietf.org/doc/html/rfc7231.html#section-5.3.2).

This fix updates get_preferred_type() to treat media types with
parameters as distinct, allowing more precise and standards-compliant
matching.

Thanks to magicfelix for the report, and to David Sanders and Sarah
Boyce for the reviews.
This commit is contained in:
Jake Howard
2025-05-27 17:00:29 +01:00
committed by nessita
parent 26313bc219
commit c075508b4d
4 changed files with 200 additions and 31 deletions

View File

@@ -445,6 +445,41 @@ Methods
>>> request.get_preferred_type(["application/xml", "text/plain"])
None
If the mime type includes parameters, these are also considered when
determining the preferred media type. For example, with an ``Accept``
header of ``text/vcard;version=3.0,text/html;q=0.5``, the return value of
``request.get_preferred_type()`` depends on the available media types:
.. code-block:: pycon
>>> request.get_preferred_type(
... [
... "text/vcard; version=4.0",
... "text/vcard; version=3.0",
... "text/vcard",
... "text/directory",
... ]
... )
"text/vcard; version=3.0"
>>> request.get_preferred_type(
... [
... "text/vcard; version=4.0",
... "text/html",
... ]
... )
"text/html"
>>> request.get_preferred_type(
... [
... "text/vcard; version=4.0",
... "text/vcard",
... "text/directory",
... ]
... )
None
(For further details on how content negotiation is performed, see
:rfc:`7231#section-5.3.2`.)
Most browsers send ``Accept: */*`` by default, meaning they don't have a
preference, in which case the first item in ``media_types`` would be
returned.

View File

@@ -38,3 +38,8 @@ Bugfixes
* Fixed a bug in Django 5.2 where calling ``QuerySet.in_bulk()`` with an
``id_list`` argument on models with a ``CompositePrimaryKey`` failed to
observe database parameter limits (:ticket:`36416`).
* Fixed a bug in Django 5.2 where :meth:`HttpRequest.get_preferred_type()
<django.http.HttpRequest.get_preferred_type>` did not account for media type
parameters in ``Accept`` headers, reducing specificity in content negotiation
(:ticket:`36411`).