Nginx gotcha

Yesterday morning I noticed some odd behavior: Nginx was serving pages with the wrong mime type. All of a sudden, links to cached pages were interpreted as octet-stream, when instead they were just straight-up html.

I suspected immediately that it had something to do with Rails page caching with Passenger plus Nginx, but what? Rails caches pages with the correct file extension, so shouldn't Nginx pick up on that and serve the page correctly? Turns out it's more complicated than that.

Part of the problem is the way Rails requests are structured. Rails requests don't contain file extensions, for obvious reasons. A request for my "About" page would look like this:

http://aronpilhofer.com/about-aron-pilhofer

In a dynamic application, that's no problem. The request gets passed to Rails through Passenger and Rails responds by rendering the correct action. But if you are using page caching (as I am), Rails never gets the request by design. Nginx should get the request, and then serve the cached page without ever hitting Rails.

But how does Nginx know that about-aron-pilhofer actually means about-aron-pilhofer.html? I am not entirely sure, but I suspect this is part of the magic of Passenger. On Apache, caching just works without any additional configuration. Not on Nginx, though.

I tried changing defaults, playing around with the mime types file, all to no avail. No matter what I did, cached pages were being served as binary data.

Thanks to Ezra Zygmuntowicz for proving me a clue to solving the problem in a sample config file he posted on his website. Turns out, putting in a rewrite to handle this problem solves it.

if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}

Very simple. All this does is check to see if the incoming request continues the extension .html. If not, it appends it to the request. If that page exists (meaning it's cached), it gets served. If not, the request is passed to Rails, and all is well with the world.

Tue, 11 Aug 2009 11:53

Tags , , ,

Comment Nginx gotcha


RSS