Hulihan Applications
about projects portfolio services contact_us
Rails Cache Problems with .htaccess

    Page caching is an important performance tool when it comes to dynamic webpages. Ruby on Rails has some cool page caching options that help store dynamically generated pages as flat html files, so as long as a rail pages doesn't change very much, it's a good idea to cache it. This minimizes server load and allows your browser to grab the page very quickly. Rails Envy has a great tutorial for getting started with page caching. There's even a section that tells you how to store cached files in a custom directory of your choice. Very cool.

However, I ran into a few snags when implementing it with rails 1.2.6. The pages were getting generated properly in the public/cache folder, but when I went to the page in question, the cached file wasn't being served. How cached files are served to a visitor all depends on the webserver that's running. In my case, I'm running rails on Apache, via fastcgi or cgi. This means that there's a file in the public folder, .htaccess, that controls how requests are sent to rails. This is an override file for apache, that lets you customize Apache settings and configuration for a particular folder. There's a section in the .htaccess file that tells apache to look for cached files first, and if none are found, send the HTTP request to rails, through dispatch.fcgi. Here's what that section looks like normally:
	RewriteRule ^$ index.html [QSA]
	RewriteRule ^([^.]+)$ $1.html [QSA]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

Now since I'm placing all cached content in the cache folder, the section should be changed to this, right?
	RewriteRule ^$ cache/index.html [QSA]
	RewriteRule ^([^.]+)$ cache/$1.html [QSA]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

Wrong! This didn't work for me at all, I even tried using a leading slash, ie: /cache/. Apache refused to look in the cache folder, and cached files still weren't served. After much searching, I finally stumbled upon the correct apache directives for a custom cache directory. Here's what it looks like:
	# This directive will look in public/ for cached files
	RewriteRule ^$ index.html [QSA]
	RewriteRule ^([^.]+)$ $1.html [QSA]
	# This directive will look in public/cache/ for cached files
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule !^cache/(.*) - [C]
	RewriteRule ^(.*)$ cache/$1 [QSA] 
	# If nothing is found, send to rails 
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

Finally, it worked properly. This particular set of directives also will look in just the public directory, so remove the first 3 lines(including the comment) if you don't want this to happen. It took me a while to find this fix, so I thought I would share.


1 Comments

greg at flightless-co-nz says...
stumbled on your post when I was looking to solve similar caching issues, along with handling annoying index pages being cached to their 'controller_name.html' instead of 'controller_name/index.html'. here's a work in progress of some htaccess rules I'm messing with... it doesn't handle other types of content yet (xml, json, etc. are passed through to rails) and there are some other preceeding rules that check for files and directories in the public directory. I think the PT directives can be left off, and debugging/logging the mod_rewrite rules shows there are some internal redirects that look a bit weird :) # site.com or site.com/ -> cache/index.html ('' or '/' root request) RewriteCond %{THE_REQUEST} ^(GET|HEAD) RewriteCond %{DOCUMENT_ROOT}cache/index.html -f RewriteRule ^/?$ cache/index.html [PT,L] # site.com/about/some-page -> cache/about/some-page.html (remove trailing '/', append .html) RewriteCond %{THE_REQUEST} ^(GET|HEAD) RewriteCond %{DOCUMENT_ROOT}cache/$1.html -f RewriteRule ^(.+?)(/?)$ cache/$1.html [PT,L] # send the original url request to the proxy RewriteRule ^(.*)$ http://127.0.0.1:3000%{REQUEST_URI} [P,QSA,L]


Add A Comment



simple_captcha.jpg



Hulihan Applications © 2007-2009
No portion of this site may be copied, altered, duplicated or otherwise used without the express written approval of Hulihan Applications.