Unexpected behavior with respond_to

Hi all,

I am encountering some unexpected behavior in the Rails 3.0.0.rc which
I think may be incorrect.

In my controller, I have the following:

  class FeedsController < ApplicationController
    def recent
      respond_to do |format|
        format.atom
      end
    end
  end

Likewise, I have a view (feeds/recent.atom.builder):

  xml.tag!('feed', :xmlns => "http://www.w3.org/2005/Atom") do
    xml.text!("...")
  end

and I have a route:

  match('feeds/recent' => 'feeds#recent')

If I try to fetch this with no Accept header, I get a 406 error:

  $ curl -i http://localhost:3000/feeds/recent -H "Accept:"
  HTTP/1.1 406 Not Acceptable
  [ ... ]

This is probably not correct, since RFC 2616 (sec 14.1) reads:

If no Accept header field is present, then it is assumed that the
client accepts all media types.

Moving on.

If I try to fetch this with an "Accept: */*" header or "Accept:
application/atom+xml", it works as expected. Likewise all works well
if I use an "Accept: */*, text/html" header

However, if I change the order of the formats, to "Accept: text/html,
*/*", I get a 406:

  $ curl -i http://localhost:3000/feeds/recent -H "Accept: text/html, */*"
  HTTP/1.1 406 Not Acceptable
  [ ... ]

But a "text/html, */*" Accept header should be equivalent to a "*/*,
text/html" header, since order does not matter. (This is a contrived,
but similar Accept headers are used by Firefox, with q values.)

Getting further into the bowels of RFC 2616, an "Accept:
application/*" header gives me a 406, when it should be acceptable,
because I have a response of type "application/atom+xml".

One final thing. I add a format.any entry to the controller (I am not
entirely sure the meaning of this):

  def recent
    respond_to do |format|
      format.atom
      format.any
    end
  end

And now I get a 200 with "Accept: */*" and "Accept:
application/atom+xml", but template errors with any other Accept
header including a "*/*".

Does anybody have any thoughts about this? It does not seem to me that
Rails is not doing the right thing here.

best, Erik Hetzner

I have similar issues with some js.rjs files after upgrading an app to rails 3. Some respond_to blocks keep working fine as before and I get JS returned, some keep trying to return HTML and thus spit out the 406 error. I haven’t found any good reason in my code to justify this kind of behavior, even after i tried reducing the affected js.rjs files to a simple straightforward single line of code: I still get them returned as html with error 406. I even tried to enforce javascript headers by putting: format.js {render :content_type => ‘text/javascript’} in the respond_to block, but that didn’t change it.

Really stuck on this issue. In 2.3.8 the code worked perfectly fine.