ruby-mongrel-x-sendfile


Utilize platform-native sendfile(2) to efficiently serve files from a mongrel-powered app

This project is a Mongrel::HttpHandler filter & Mongrel::HttpResponse patch developed at Scout Labs for use with our Ruby on Rails apps.

Efficiently send static files from a mongrel app

Streaming very much data through mongrel is a bad thing; springs stringy memory leaks.

What about the pre-existing HTTP server solutions?

Typically this problem is solved for dynamically-served static files via an HTTP X-Sendfile header sent back to the upstream web server/proxy, e.g. Apache mod_xsendfile or lighttpd's sendfile support.

This is an in-mongrel solution

This filter & patch avoids the icky ruby memory/object leak while still completing the request entirely with mongrel, requiring no further web server integration. It contains: * an X-Sendfile behavior written as a Mongrel::HttpHandler mounted at uri "/", only engaging when a response contains an X-Sendfile header * an around-behavior, advice style monkey patch to Mongrel::HttpResponse#send_file so that we can utilize the sendfile gem for platform-native binding to sendfile(2).

Code quality, compatibility

Developed & tested with: * mongrel 1.1.5 * Rails 2.2.2, using ActionController's #send_file with :x\_sendfile => true * local dev on OS X 10.5, ruby 1.8.6 * deploying on Solaris 10, ruby 1.8.6

Known issues: * on Solaris 10, the sendfile gem's tests hang indefinitely for nonblocking sendfile(2) calls; so, we do not use nonblock calls * OS X/Darwin is not supported at all by the sendfile gem; so, we fall back to copying the file data to the network socket via ruby (same for all unsupported platforms)

The future

Merb &/or Rails 3 may probably provide more elegant ways to accomplish this same thing.

Get it

The raw code is available in the repo. A gem package & usage guidlines soon to follow!

Project Information

Labels:
ruby mongrel sendfile rails filter http x-sendfile