Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

MissingTemplate issues in Rails 3.0 due to badly set MIME types...

#5113

I've been having a very odd error under Rails 3.0 which has taken me some time to isolate.

I recently moved a client's site to Rails 3.0 over the last couple of months, and my exception notifier had been giving me the occasional HTTP 5xx email regarding missing templates which were not missing at all. Each time I tried to access the offending URL/resource I had no issues.

After careful inspection in the HTTP headers I noticed the Accept header was occasionally different on the machines reporting errors, it was named as "hc/url;/" instead of a proper list of accepted MIME types. After a quick stab at trying to forge these headers I little luck at replicating it (I think I was using curl).

After more investigation I managed to replicate this using the following:

  rails new test
  cd test
  # Create blank pages controller & route here
  mkdir app/views/pages
  echo 'Hello World' > app/views/pages/index.html.erb
  rails server -e production

Then under "telnet localhost 3000"

GET / HTTP/1.1
Accept: hc/url;/

The above won't work, however below works:

GET / HTTP/1.1
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5

I have found under some situations manipulating the "Accept" header under curl and browsers don't seem to replicate this perfectly, probably because other headers seem to have some influence in the way the request works possibly.

I hope this is replicate-able for you.

Cheers
J.

Reported by VirtualFunction · July 14th, 2010 @ 05:50 PM

State: new
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. mpd
    mpd

    We're seeing this as well since updating to 3.0 - on 3.0.3 and it still happens.

    In addition to hc/url, a small number of the errors instead mention text/*, and yet a few others have ws/ws as the requested format.

    December 14th, 2010 @ 07:38 PM

  2. Neeraj Singh
    Neeraj Singh
    • Importance changed from to Low

    In the given case there is hardly anything rails can do. One way to handle such cases would be to have a before filter and for bad HTTP_ACCEPT_HEADER you can set params[:format] = 'html' and then html will be the response content-type.

    More on this topic at http://neeraj.name/2010/11/23/mime-type-resolution-in-rails.html

    December 14th, 2010 @ 09:01 PM

  3. mpd
    mpd

    In my case the HTTP_ACCEPT header is coming in from the browser as "hc/url;*/*" which doesn't parse I guess. It shows up as :formats=>[:"hc/url;*/*"] in the exception output. I've captured this in a failing test in my app. Changing the semicolon to a comma 'solves' it, but I don't know enough about HTTP_ACCEPT parsing to know where the problem is.

    The ws/ws header is "*/*, ws/ws", with the space, which parses to :formats=>[:"ws/ws", :"*/*"], and the last is "text/*" by itself (:formats=>[:"text/*"]).

    The action itself just sets a single instance var.

    Forcing the format to html in a before filter as suggested isn't working for me. Am I just doing it wrong?

    December 14th, 2010 @ 11:29 PM

  4. mpd
    mpd

    Can't edit my previous, but the juice that worked for me is self.formats = [:html]

    December 14th, 2010 @ 11:49 PM

  5. VirtualFunction
    VirtualFunction

    Yes, the way I've been getting round this for the last 5 or so months I've been on Rails 3 I've used this:

    request.format = :html if request.format.to_s.include? 'hc/url'

    as part of a before filter.

    I also have issues with text/* occasionally too.

    What I've not figured out is why the browser sends these odd content types... It seems somewhat random when it does happen (or from what I can see). I can't remember what browsers these happens on , I seem to recall Firefox on Windows being the main offender.

    December 15th, 2010 @ 12:52 AM

  6. Roel van der Hoorn
    Roel van der Hoorn
    • Tag changed from rails 3.0.0.beta4, action_view, header, mime, missi, template to rails 3.0.0.beta4, rails 3.0.4, action_dispatch, action_view, header, mime, missi, template

    Same problems here on Rails (at least versions 3.0.0 to 3.0.4). Especially crawlers are known to use different HTTP ACCEPT headers than most web browsers. The following appear quite often:
    "text/" * "image/jpeg", "image/pjpeg", "image/png", "image/gif"

    For "text/*" Rails does not have any support, i.e. it does not recognize it. This is a bug as it is a valid HTTP ACCEPT header to request only text MIME types, see e.g. http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. I created a separate ticket for this, see: #6458 Rails does not recognize the "text/*" MIME type.

    In the second case Rails should return a 406 (Not Acceptable) if the respond_to block does not respond to any of the requested MIME types. Rails throws a missing template instead, so this is a different bug than the first case describes.

    February 21st, 2011 @ 10:37 AM

  7. Nathaniel Bibler
    Nathaniel Bibler
    • Tag changed from rails 3.0.0.beta4, rails 3.0.4, action_dispatch, action_view, header, mime, missi, template to rails 3.0.0.beta4, rails 3.0.4, rails 3.0.5, action_dispatch, action_view, header, mime, missi, template

    I'm seeing the same issue, as well, in multiple Rails 3 applications. Some are Rails 3.0.3, some are 3.0.5. In all cases, making a simple GET request using the following curl statement causes 500 errors:

    curl -v -H "Accept: */*;q=0.1" http://example.com/
    curl -v -H "Accept: */*; q=0.5, application/xml" http://example.com/
    curl -v -H "Accept: text/*" http://example.com/
    

    It'd be nice if Rails would recognize an invalid or unhandled Accept-type and failover to the default response type (generally, HTML when listed by priority in respond_to blocks).

    March 24th, 2011 @ 01:59 PM

  8. Duff OMelia
    Duff OMelia

    I'm seeing the same thing Nathaniel Bibler's seeing.

    curl -H "Accept: text/*" http://example.com
    curl -H "Accept: */*, application/youtube-client" http://example.com
    

    Both raising ActionView::MissingTemplate exceptions. Using rails 3.0.4.

    March 24th, 2011 @ 10:01 PM

  9. Duff OMelia
    Duff OMelia

    Would there be a downside for Rails to return a 406 (Not Acceptable) if we're unable handle the Accept header? (Like Roel suggested)

    March 25th, 2011 @ 01:18 PM