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.5would 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'
Note:
See TracTickets
for help on using tickets.