Issue #1031 new

content-type negotiation: respect server preferences

Anonymous created an issue

CherryPy doesn't (usually) respect the server preferences when it does Accept/Content-Type negotiation.

For example, suppose Firefox sends the header: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

My interpretation of the HTTP spec means it's saying: Please send either html or xhtml with priority 1; or xml with priority 0.9, or anything else with priority 0.8.

With such an Accept header, I would expect the following app to respond with application/xhtml+xml, because that's the first in the list passed to the accept callable.

{{{ import cherrypy

class TextApp(object): def index(self): mtype = cherrypy.tools.accept.callable(['application/xhtml+xml', 'text/html'], debug=True) cherrypy.response.headers['Content-Type'] = mtype index.exposed = True

cherrypy.quickstart(TextApp()) }}}

Instead, this application responds with text/html (view the debug output), because that was specified first in the Accept request, even though it was specified at the same priority level as xhtml.

The cause of the problem is CherryPy is looping through the client specified content types in order. Instead, for each qvalue, CherryPy needs to loop through the server specified content types. Then, in an inner loop, it should loop through the client specified types of the right qvalue.

Reported by iainn

Comments (1)

  1. Sylvain Hellegouarch

    The current doc for the accept(...) helper is as follow:

    Matching types are checked in order of client preference first,
        and then in the order of the given 'media' values.
    

    Which is why I believe text/html is indeed returned rather than what was provided in the media list. I'm not sure why it's an actual issue.

  2. Log in to comment