I am having trouble with content negotiation due to some Accept
headers not clearly specifying an order amongst all desired media
types. For example, Safari provides:
> application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Right now, if a Rails resource can be represented both in html and
application/xml, rails will return an application/xml representation.
Asking about it in the rest-discuss mailing list, the http specs do
not provide any guide on which media-type to pick if multiple ones
have the same q value. In Safari's example, there are three possible
media types that can be picked.
Other language and frameworks have decided to use a first-q value,
second-alphabetical sorting of the list and find the first one that it
is capable of providing. This solves the problem for typical
representations because json and xml comes after html.
I am attaching my original question on the rest-discuss list and
mike's answer which mentions the first framework (his link shows other
- python and erlang - frameworks that chose the same path).
The rails code that affects it is within the mime_responds.rb:
if ActionController::Base.use_accept_header
@mime_type_priority = Array(Mime::Type.lookup_by_extension
(@request.parameters[:format]) || @request.accepts)
else
@mime_type_priority = [@request.format]
end
The issue with Rails by default is that the first priority for Safari
in the list is priority = 'application/xml' and @responses do not
include it (Rails registered xml only, not application/xml):
if @responses[priority]
@responses[priority].call
return # mime type match found, be happy and return
end
If we register a application/xml, then Safari starts getting a xml
representation, where most would give back a html representation back.
Any suggestions?
note: the sorting is according to the name after the /
Regards
Guilherme Silveira
Caelum | Ensino e Inovação
http://www.caelum.com.br/
---------- Forwarded message ----------
From: mike amundsen <mamu...@mymediabox.com>
Date: 2009/12/18
Subject: Re: [rest-discuss] content type negotiation: multiple entries
with same quality value
To: Guilherme Silveira <guilherme...@caelum.com.br>
Cc: rest-discuss <rest-d...@yahoogroups.com>
Check the the mimeparse project [1]. The last thread there talks about
just this case, handling clients where more than one media-type has
the same q-value [2].
The most recent build orders the acceptable items in q-value, alpha
order and takes the first.
FWIW, I have a mod that also lets the server decide based on a
resource preference (the default for the resource, if one is given). I
also have a mod (in a mess, right now) that handles some "broken"
agents. For example, MS-Excel sends an accept header that prefers HTML
over CSV and I usually ignore that and send CSV anyway.
[1] http://code.google.com/p/mimeparse/
[2] http://groups.google.com/group/mimeparse-dev/browse_thread/thread/2ec7e38517fad9be
On Fri, Dec 18, 2009 at 08:10, Guilherme Silveira
<guilherme...@caelum.com.br> wrote:
> Hello guys,
>
> Safari sends the following accept header, due to webkit's code [1]:
> application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
>
> I could not find in section 12 or the Accept header definition in http
> 1.1 what to do if there is more than one content-type with the same
> q-value. In the above example, it seems like the server is free to
> decide whether to send application/xml, application/xhtml+xml or
> text/html.
>
> Any opinions on that? Should it be followed left to right
> (application/xml first)? Should the server decide?
>
> Regards
>
> [1] http://www.newmediacampaigns.com/page/webkit-team-admits-accept-header-error
>
> Guilherme Silveira
> Caelum | Ensino e Inovação
> http://www.caelum.com.br/
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
> <*> To visit your group on the web, go to:
> http://groups.yahoo.com/group/rest-discuss/
>
> <*> Your email settings:
> Individual Email | Traditional
>
> <*> To change settings online go to:
> http://groups.yahoo.com/group/rest-discuss/join
> (Yahoo! ID required)
>
> <*> To change settings via email:
> rest-disc...@yahoogroups.com
> rest-discuss...@yahoogroups.com
>
> <*> To unsubscribe from this group, send an email to:
> rest-discuss...@yahoogroups.com
>
> <*> Your use of Yahoo! Groups is subject to:
> http://docs.yahoo.com/info/terms/
>
>
If there are multiple representations with the same q level we take
the priority in the order you specify them. e.g. if you have
respond_to do |format|
format.xml
format.html
end
You get xml, flip the block order around and you get HTML instead.
This allows both the client and the server to express their preference
where an alpha sorting wouldn't. I'm guessing that you have your xml
declarations first.
I personally think this is a much better solution than what you're
describing here as you get proper content-negotiation rather than just
a fancy parser which somehow decides which of the equivalent entries
it should consider 'best'.
Having said all of that, in my personal opinion the accept header is a
horrific idea in practise as there are simply dozens of corner cases
where browsers send idiotic values. I've seen IE saying it doesn't
support HTML or XML (new tab ie7) various plugins sending completely
malformed headers etc. I'm a firm believer that you should pretty
much always disable use_accept_header if you'll ever have browsers
connecting. But rails supports both paths.
--
Cheers
Koz
> I'm guessing that you have your xml declarations first.
Its actually a generic format.xxx registration procedure so the
framework can handle content-negotiation by default instead of the
client having to describe it every time (I believe rails3 handle it
with their responders from what Ive seen).
But knowing that solves the problem... thanks...
> I personally think this is a much better solution than what you're
> describing here as you get proper content-negotiation rather than just
> a fancy parser which somehow decides which of the equivalent entries
> it should consider 'best'.
Yes
> I've seen IE saying it doesn't
> support HTML or XML (new tab ie7) various plugins sending completely
> malformed headers etc.
The famous IE 'accept' problems... ie8 still has issues from what I
have read.
Thanks again, it solved the problem.
Cheers
guilherme