I have a rails app that is working fine except for one thing.
When I request something that doesn't exist (i.e. /not_a_controller_or_file.txt) and rails throws a "No Route matches..." exception, the response is this (blank line intentional):
HTTP/1.1 200 OK
Date: Thu, 02 Oct 2008 10:28:02 GMT
Content-Type: text/html
Content-Length: 122
Vary: Accept-Encoding
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Status: 500 Internal Server Error
Content-Type: text/html
<html><body><h1>500 Internal Server Error</h1></body></html>
I have the ExceptionLogger plugin in /vendor, though that doesn't seem to be the problem. I haven't added any error handling beyond the custom 500.html in public (though the response doesn't contain that HTML) and I have no idea where this bit of html is coming from.
So Something, somewhere is adding that HTTP/1.1 200 status code too early, or the Status: 500 too late. I suspect it's Apache because I get the appropriate HTTP/1.1 500 header (at the top) when I use Webrick.
My production stack is as follows: Apache 2 Mongrel (5 instances) RubyOnRails 2.1.1 (happens in both 1.2 and 2.1.1)
I forgot to mention, the error is caused by a "no route matches..." exception
-
This html file is coming from Rails. It is encountering some sort of error (probably an exception of some kind, or some other unrecoverable error).
If the extra blank line between the Status: header and the actual headers is there, and not just a typo, then this would go a long way to explaining why Apache is reporting a 200 OK message.
The Status header is how Rails, PHP, or whatever tells Apache "There was an error, please return this code instead of 200 OK." The fact there is a blank line means something extra is going on and Ruby is outputting a blank line before the error output for whatever reason. Maybe it's previous output from your script. The long and short of it is though, the extra blank line means that Apache thinks "Oh, blank line, no extra headers, this is all content now.", which would be consistent with the Content-Length header you provided.
My guess for why there's a blank line would be previous script output, perhaps a line ending at the end of a fully script page. As to why the 500 error is happening, there isn't nearly enough info here to tell you that. Maybe a file I/O error.
Edit: Given the extra information provided by Dave about the internals, I'd say this is actually an issue with the proxying that goes on behind the scenes... I couldn't tell you exactly what though, beyond what's already been said.
Dave Cheney : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14 ^ where is the Status: header defined ?Matthew Scharley : That's because it ISN'T a HTTP header, it's a CGI header. It is supposed to be caught and used by the server, it's never meant to be seen. http://www.ietf.org/rfc/rfc3875 , section 6.3.3.Dave Cheney : But the bridge between apache and mongrel is HTTP, not CGI. -
This is coming from rails itself.
http://github.com/rails/rails/tree/master/actionpack/lib/action_controller/dispatcher.rb#L60
The dispatcher is return an error page with the status code of 200 (Success).
Matthew Scharley : See my response to your comment on my answer. This isn't correct, in so much as it's not what it's trying to do. Status is a CGI header, and is well formed.Dave Cheney : But the bridge between apache and mongrel is HTTP, not CGIMatthew Scharley : What about between Mongrel and ruby? There's CGI happening somewhere, because that's a CGI header, and if ruby wasn't being run via CGI then it'd have no reason to use that header. At any rate, my answer still stands, because the headers have become disjointed somewhere, hence the blank line andMatthew Scharley : repeated Content-Type header.Matthew Scharley : See this mail, mongrel uses CGI to talk to RoR: http://rubyforge.org/pipermail/mongrel-users/2006-October/001946.htmlDave Cheney : Yes, internally mongrel creates a CGI request and response object as that is what the rails dispatcher expects (fastCGI + lighttpd was the preferred deployment method about 2 years ago) but mongrel itself is a HTTP server so it just passes the Status: header up to apache rather than interpreting itDave Cheney : See http://github.com/mongrel/mongrel/tree/master/lib/mongrel/rails.rb#L49 -
This is a fairly old thread, but for what it's worth I found a great resource that includes a detailed description of the problem and the solution. Apparently this bug affects Rails < 2.3 when used with Mongrel.
- The article that helped me understand the problem & write my own patch.
- An official Rails bug ticket that includes a patch for Rails 2.2.2.
0 comments:
Post a Comment