Fast, authenticated file downloads with rails, apache and xsendfile

Sunday, April 26th, 2009 - 4 Comments

So your rails app manages uploads and downloads of files, be it pictures, documents or other random things the user may wish to store online, and they wish to protect those uploads so only they can access them, via a login and password.

That means you can’t just store all of your files in the public directory and have apache send them out, rails has to get involved to check that you are logged in and have proper access rights.

To do this you can use the send_file method, passing the path to the file (or it’s data if it’s from a db or amazon s3) and the type of file it is.

If you’re using attachment_fu, with a model called Upload it will look something like this:

def download
  @upload = Upload.find(params[:id])
  send_file @upload.public_filename, :type => @upload.content_type
end

This works fine, but it’s not exactly speedy, and while the file is being sent to the user that rails process has it’s hands completely full, meaning it can’t serve anyone else any pages until it’s done with the file transfer.

In steps mod_xsendfile, a module for apache that also happens to be supported in rails. Below are the brief instructions for installing it for apache on ubuntu:

wget http://tn123.ath.cx/mod_xsendfile/mod_xsendfile.c
apxs2 -cia mod_xsendfile.c

At this point I recieved an error like:

apxs:Error: Activation failed for custom /etc/apache2/httpd.conf file..
apxs:Error: At least one `LoadModule' directive already has to exist..

To fix it I opened the apache config:

sudo nano /etc/apache2/httpd.conf

And pasted this line at the bottom of the file:

LoadModule xsendfile_module /usr/lib/apache2/modules/mod_xsendfile.so

Then restart apache and your server is ready to go:

sudo /etc/init.d/apache2 restart

The last thing to do, is back in your controller, tell rails to utilize xsendfile by passing an extra option to send_file, like this:

def download
  @upload = Upload.find(params[:id])
  send_file @upload.public_filename, :type => @upload.content_type, :x_sendfile => true
end

All the benefits of rails, with the speed of apache.

Thanks to: gra2, therailsway, and radient for getting me started with this.

Window Box

Sunday, April 26th, 2009 - No Comments

Window Box

Parsing Google Analytics data with Ruby

Saturday, April 25th, 2009 - No Comments

The google analytics api come out a few days ago, meaning we can do some cool things with integrating stats data into web apps.

It should be pretty easy to show the number of page views or the most popular browsers in your templates, or even change the amount of advertising depending on the popularity of the page.

A couple of ruby gems have been created gattaca and garb to make it really easy to interface with the api, so I’ve put together a couple of examples to get you started.

Top 10 pages in the past day

The first one is nice and simple, setting up a few options then looping through the results to display the url and number of page views for each.

Graph of hits on the homepage for past month

This one uses the sparklines gem to draw a line graph of the hits on a particular url (’/’ in this example) over the past 30 days.

Neither of these scripts are particularly fast so if you’re planning on using them in a web page be sure to fragment cache them.

It will be really interesting to see how this data is used in the future, maybe we’ll even see self-tuning web sites!

May contain products from Switzerland

Saturday, April 25th, 2009 - No Comments

May contain products from Switzerland

Pragmatic Programming book sale

Friday, April 17th, 2009 - No Comments

Prototype and script.aculo.us My Job Went to India: 52 Ways to Save Your Job

I’ve just listed some of my pragmatic programmer books for sale on amazon, including Prototype and script.aculo.us, My Job Went to India: 52 Ways to Save Your Job and Pragmatic Version Control: Using Subversion

Each one is very well written, and a perfect way to help advance your skills and career in web development, either in a specific topic (interface design, version control, ruby on rails) or more general advise in how to become a better programmer.

They are all in very good condition, will be delivered within 3 days of purchase and all the proceeds from the sales will go towards helping me further develop my own skills.

Browse all the books I’m selling on my amazon page