Enabling browser caching of static content in Mongrel
This post describes a simple snippet you can include in your rails environment to enable caching of static content served up from Rails via Mongrel in a development environment.
By design, Mongrel doesn't include configuration options for caching headers on static content. Mongrel is optimized for dynamic content, and in a production deployments another web server such as Apache is used to render static content.
However, in a development environment, the lack of static content caching can be an issue for pages with large numbers of images, scripts, and stylesheets. Waiting to fetch all of these resources on every page request makes iterative development feel sluggish and doesn't accurately reflect what will occur in production.
The class used in Mongrel to serve static content is called DirHandler. By adding the following lines to your environment.rb file, you can extend DirHandler to set the Expires and Cache-Control headers so that all static content lives 10 years. As long as you refer to that content using the Rails helpers like "image_tag", timestamps will be appending to the URLs so that new versions of these assets will be correctly loaded whenever you update the files.
-
if defined? Mongrel::DirHandler
-
module Mongrel
-
class DirHandler
-
def send_file_with_expires(req_path, request, response, header_only=false)
-
response.header['Cache-Control'] = 'max-age=315360000'
-
response.header['Expires'] = (Time.now + 10.years).rfc2822
-
send_file_without_expires(req_path, request, response, header_only)
-
end
-
alias_method :send_file_without_expires, :send_file
-
alias_method :send_file, :send_file_with_expires
-
end
-
end
-
end
9 Comments so far
Leave a comment
I think this is an important addition. This allows front-end caching servers and clients to receive better hints from the app server without requiring additional explicit configuration for apache/nginx, etc.
You should submit this as a patch to the mongrel team.
I’d like to see the same approach implemented for thin.
By darren on 03.20.08 4:19 pm
Hi,
After adding those lines to my environment.rb file I found that the expires headers are being added to only images (that have been added using image_tag). I want the same to happen to stylesheets that i’ve inserted using stylesheet_link_tag and javascripts using the javascript_include_tag. Shouldn’t this be applicable to all helper tags by default?
Thanks.
By swamy on 04.01.08 1:37 am
Hi,
I’ve added those lines of code to my environment.rb file and only the image files have expires header added to them. I want this to happen to javascripts and stylesheets as well. I have linked them using stylesheet_link_tag and javascript_include_tag helper methods. Any help will be greatly appreciated.
Thanks.
By swamy on 04.01.08 1:58 am
Thanks a lot !
Exactly what I was looking for.
By Coren on 04.04.08 7:57 am
I spend a whole day trying to fix this, thank you very much!
By Marcio on 04.24.08 5:50 pm
I almost forgot, you can replace this:
alias_method :send_file_without_expires, :send_file
alias_method :send_file, :send_file_with_expires
with this:
alias_method_chain :send_file, :expires
By Marcio on 04.24.08 6:14 pm
I tried the above code and like Swamy I still don’t get an expires header for CSS files.
Is there a fix for this?
Scott
By Scott on 05.06.08 4:39 pm
Let me look into the expires header for CSS files.
By philbo on 05.07.08 2:44 pm
Hi,
thanks for this, looks like I’m almost there, but I can’t figure out how to enable a specific cache path.
to avoid messing up my public directory, I added this to my environment:
config.action_controller.page_cache_directory = RAILS_ROOT + “/public/cache/”
my production server is using a mongrel cluster + apache, I configured the path and it works great.
but it doesn’t work on my development machine (mac - leopard)
if I remove this extra path, then the cached pages are created in my public directory, and served correctly, but then it beaks my sweepers :-/ (no errors, the files are simply not erased)
to start my application in development, I use this command:
> mongrel_rails start -m config/mongrel_mime.yml
(I use this mime config otherwise my utf-8 get messed up after caching)
looking for help, typing
mongrel_rails start -h
tells me there is an option:
-C, –config PATH Use a config file
couldn’t we use this config file to set these caching options? (and maybe my extra path issue aswell?)
I found many articles that explains how to configure mongrel in production, but none in a development environment…..) so I have no clue of what this config file should look like…
thanks so much for any help !
cheers
julien
By jujudellago on 06.02.08 9:17 am
Leave a comment