Opened 4 months ago

Last modified 4 months ago

#36447 closed Bug

HttpRequest.get_preferred_type misorders types when more specific accepted types have lower q — at Initial Version

Reported by: Anders Kaseorg Owned by:
Component: HTTP handling Version: 5.2
Severity: Release blocker Keywords: preferred media type
Cc: Anders Kaseorg, Rodrigo Vieira, Jake Howard 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

Consider this example from RFC 9110 §12.5.1:

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/plain;q=0.7, text/plain;format=flowed,
       text/plain;format=fixed;q=0.4, */*;q=0.5

would cause the following values to be associated:

Media Type Quality Value
text/plain;format=flowed 1
text/plain 0.7
text/html 0.3
image/jpeg 0.5
text/plain;format=fixed 0.4
text/html;level=3 0.7

Django’s HttpRequest.get_preferred_type fails to match this behavior.

>>> from django.conf import settings
>>> from django.http import HttpRequest
>>> settings.configure()
>>> request = HttpRequest()
>>> request.META["HTTP_ACCEPT"] = "text/*;q=0.3, text/plain;q=0.7, text/plain;format=flowed, text/plain;format=fixed;q=0.4, */*;q=0.5"
>>> request.get_preferred_type(['text/plain', 'text/plain;format=fixed']) # expected text/plain (0.7 > 0.4)
'text/plain;format=fixed'
>>> request.get_preferred_type(['text/html', 'image/jpeg']) # expected image/jpeg (0.3 < 0.5)
'text/html'
>>> request.get_preferred_type(['text/html', 'text/html;level=3']) # expected text/html;level=3 (0.3 < 0.7)
'text/html'
>>> request.get_preferred_type(['image/jpeg', 'text/html']) # expected image/jpeg (0.5 > 0.3)
'text/html'
>>> request.get_preferred_type(['image/jpeg', 'text/plain;format=fixed']) # expected image/jpeg (0.5 > 0.4)
'text/plain;format=fixed'
>>> request.get_preferred_type(['text/plain;format=fixed', 'text/plain']) # expected text/plain (0.4 < 0.7)
'text/plain;format=fixed'
>>> request.get_preferred_type(['text/plain;format=fixed', 'image/jpeg']) # expected image/jpeg (0.4 < 0.5)
'text/plain;format=fixed'
>>> request.get_preferred_type(['text/plain;format=fixed', 'text/html;level=3']) # expected text/html;level=3 (0.4 < 0.7)
'text/plain;format=fixed'
>>> request.get_preferred_type(['text/html;level=3', 'text/plain;format=fixed']) # expected text/html;level=3 (0.7 > 0.4)
'text/plain;format=fixed'

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top