#36447: HttpRequest.get_preferred_type misorders types when more specific 
accepted
types have lower q
-------------------------------------+-------------------------------------
     Reporter:  Anders Kaseorg       |                    Owner:  Jake
                                     |  Howard
         Type:  Bug                  |                   Status:  assigned
    Component:  HTTP handling        |                  Version:  5.2
     Severity:  Release blocker      |               Resolution:
     Keywords:  preferred media      |             Triage Stage:  Accepted
  type                               |
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Anders Kaseorg:

Old description:

> Consider this example from [https://www.rfc-
> editor.org/rfc/rfc9110.html#section-12.5.1-18 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'
> }}}

New description:

 Consider this example from [https://www.rfc-
 editor.org/rfc/rfc9110.html#section-12.5.1-18 RFC 9110 §12.5.1] (adjusted
 for [https://www.rfc-editor.org/errata/eid7138 erratum 7138]):

   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.3 ||

 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(['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(['image/jpeg', 'text/html;level=3']) #
 expected image/jpeg (0.5 > 0.3)
 'text/html;level=3'
 >>> 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/html;level=3', 'image/jpeg']) #
 expected image/jpeg (0.3 < 0.5)
 'text/html;level=3'
 }}}

--
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36447#comment:9>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/01070197602a5ba9-2c2ba36a-69cf-4106-bb4c-e998f94a2e60-000000%40eu-central-1.amazonses.com.

Reply via email to