#36411 closed Bug (fixed)
MediaType.get_preferred_type ignores params
Reported by: | magicfelix | Owned by: | Jake Howard |
---|---|---|---|
Component: | HTTP handling | Version: | 5.2 |
Severity: | Release blocker | Keywords: | |
Cc: | Jake Howard, magicfelix | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I use the following code to get the preferred content type:
media_types = ["text/vcard; version=4.0", "text/vcard; version=3.0", "text/vcard", "text/directory"] print("Preferred type:", request.get_preferred_type(media_types))
A request using the following header …
Accept: text/vcard; version=3.0
… produces the following result
Preferred type: text/vcard; version=4.0
It should instead return text/vcard; version=3.0
, as 4.0
was not included in the Accept header.
Change History (17)
comment:1 by , 8 weeks ago
comment:2 by , 8 weeks ago
There is also this old SO answer about Spring: https://stackoverflow.com/a/32073014
This apparently incorrect behaviour of Spring already has a Spring bug report, SPR-10903. The Spring developers closed it as "Works as Designed", noting:
I don't know any rule for comparing media types with their parameters effectively. It really depends on the media type...If you're actually trying to achieve REST versioning through media types, it seems that the most common solution is to use different media types, since their format obviously changed between versions:
comment:3 by , 8 weeks ago
Cc: | added |
---|
comment:4 by , 8 weeks ago
Looking at the Accept header in https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2, there are some examples including parameters:
Media ranges can be overridden by more specific media ranges or specific media types. If more than one media range applies to a given type, the most specific reference has precedence. For example, Accept: text/*, text/plain, text/plain;format=flowed, */* have the following precedence: 1. text/plain;format=flowed 2. text/plain 3. text/* 4. */* The media type quality factor associated with a given type is determined by finding the media range with the highest precedence that matches the type. For example, Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5 would cause the following values to be associated: +-------------------+---------------+ | Media Type | Quality Value | +-------------------+---------------+ | text/html;level=1 | 1 | | text/html | 0.7 | | text/plain | 0.3 | | image/jpeg | 0.5 | | text/html;level=2 | 0.4 | | text/html;level=3 | 0.7 | +-------------------+---------------+
So I think we probably should take into account parameters but open to hearing other opinions
comment:5 by , 8 weeks ago
Nice find 👍 So it sounds like
- params to be included in matching, but also
- the precedence is determined by the specificity
? 🤔
comment:6 by , 8 weeks ago
I agree with Sarah that we should take into account the parameters (I'd not come across them before when I implemented this).
The q
param specifically will still need some special handling when it comes to ordering, as I think all other parameters should be considered exact matches rather than trying to parse version numbers from them.
I believe the current implementation considers specificity in the ordering, but I may be wrong. Either way, we should make sure it's covered by tests!
comment:7 by , 8 weeks ago
Owner: | set to |
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
comment:9 by , 7 weeks ago
Severity: | Normal → Release blocker |
---|
comment:10 by , 7 weeks ago
Summary: | get_preferred_type ignores params → MediaType.get_preferred_type ignores params |
---|
follow-up: 12 comment:11 by , 7 weeks ago
Cc: | added |
---|
Replying to magicfelix:
Hello! Could you please check if the proposed PR solves the issue for you?
comment:12 by , 7 weeks ago
Hello! Could you please check if the proposed PR solves the issue for you?
It does, thanks :)
comment:13 by , 7 weeks ago
Patch needs improvement: | set |
---|
comment:14 by , 7 weeks ago
Patch needs improvement: | unset |
---|
comment:15 by , 6 weeks ago
Triage Stage: | Accepted → Ready for checkin |
---|
Perhaps someone can weigh in on the correct behaviour on matching mime types, but
MediaType.match()
only checks<main-type>/<sub-type>
without consideration for the; <params>
:https://github.com/django/django/blob/d2732c30af28381f5a2ff1b08f754eeb7a6dfeca/django/http/request.py#L716-L719