Guilherme Silveira
2009-Dec-18 15:25 UTC
content negotiation and media types order in the accept header
Hello, 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.5Right 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 <mamundsen@mymediabox.com> Date: 2009/12/18 Subject: Re: [rest-discuss] content type negotiation: multiple entries with same quality value To: Guilherme Silveira <guilherme.silveira@caelum.com.br> Cc: rest-discuss <rest-discuss@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. mca http://amundsen.com/blog/ [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.silveira@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-discuss-digest@yahoogroups.com > rest-discuss-fullfeatured@yahoogroups.com > > <*> To unsubscribe from this group, send an email to: > rest-discuss-unsubscribe@yahoogroups.com > > <*> Your use of Yahoo! Groups is subject to: > http://docs.yahoo.com/info/terms/ > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Michael Koziarski
2009-Dec-18 23:49 UTC
Re: content negotiation and media types order in the accept header
> Right now, if a Rails resource can be represented both in html and > application/xml, rails will return an application/xml representation.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 -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Guilherme Silveira
2009-Dec-19 11:54 UTC
Re: content negotiation and media types order in the accept header
Hello Michael,> 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 -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.