Tuesday, August 16, 2011

Rails incorrectly parses HTTP Accept header for single media with range

Try hitting your Rails app with an HTTP header like this:

Accept: text/html;q=0.7



You will most likely get an exception that looks something like this:

Missing template home/index with {:locale=>[:en, :en],  :formats=>["text/html;q=0.7"], :handlers=>[:rhtml, :erb, :haml,  :rxml, :builder, :rjs]} in view paths  "/path/to/my_app/app/views"



This is because the ActionPack Mime::Type class is buggy in the way it parses this header when there is only one media type specified, and that media type has a range specified (the ";q=0.7"). This is perfectly valid HTML, and ActionPack actually handles the ranges correctly when there are more than one type specified.

An issue has been open for a while on this: https://github.com/rails/rails/issues/736 -- working patches have been proposed but not applied, yet the issue got closed for some reason.

I prefer not to patch my own version of Rails, so instead I am using a small monkey patch that works around this problem. I've created a file named config/initializers/rails_issue_736.rb that fixes the Mime::Type.lookup method to only use the part that comes before the semi-colon:


3 comments:

Matt Huggins said...

Thanks for sharing this! Just saw a Hoptoad with this exact error, and you were the first search result for such an Accept header. I'll have to monkeypatch like you for now, but hopefully we can get a fix in ActionPack itself.

scottwb said...

Hoptoad is exactly how I found this too. Some domain tool crawler hits my site with that header. Glad this was helpful.

essay best said...

Thanks for this post man! This was really really ehelpful and i would really like to applaud your work too. You're blog's been useful so many times, i lost count.