Rack::Thumb: Drop-in image thumbnailing for your Rack stack
Rack::Thumb
is drop-in dynamic thumbnailing middleware for Rack-based applications, featuring simple configuration, optional security (via url-signing), and maximum flexibility.
Getting Started
You will need ImageMagick and the Mapel gem (github.com/akdubya/mapel).
gem install rack-thumb
# rackup.ru
require 'myapp'
require 'rack/thumb'
use Rack::Thumb
use Rack::Static, :urls => ["/media"]
run MyApp.new
Rack::Thumb
is file-server agnostic to provide maximum deployment flexibility. Simply set it up in front of any application that’s capable of serving source images (I’m using it with an app that serves images from CouchDB).
See the example directory for more Rack
configurations. Because thumbnailing is an expensive operation, you should run Rack::Thumb
behind a cache, such as the excellent Rack::Cache
.
Rendering Options
Rack::Thumb
intercepts requests for images that have urls of the form /path/to/image_{metadata}.ext
and returns rendered thumbnails. Rendering options include width
, height
and gravity
. If both width
and height
are supplied, images are cropped and resized to fit the aspect ratio.
Link to thumbnails from your templates as follows:
/media/foobar_50x50.jpg # => Crop and resize to 50x50
/media/foobar_50x50-nw.jpg # => Crop and resize with northwest gravity
/media/foobar_50x.jpg # => Resize to a width of 50, preserving AR
/media/foobar_x50.jpg # => Resize to a height of 50, preserving AR
URL Signing
To prevent pesky end-users and bots from flooding your application with render requests you can set up Rack::Thumb
to check for a SHA-1
signature that is unique to every url. Using this option, only thumbnails requested by your templates will be valid. Example:
use Rack::Thumb, {
:secret => "My secret", # => Don't tell anyone!
:keylength => "16" # => Only use 16 digits of the SHA-1 key
}
You can then use your secret
to generate secure links in your templates using Ruby’s built-in Digest::SHA1
library:
/media/foobar_50x100-sw-a267c193a7eff046.jpg # => Successful
/media/foobar_120x250-a267c193a7eff046.jpg # => Returns a bad request error
There are no helper modules just yet but it’s easy enough to roll your own.
Deep Thoughts
Rack::Thumb
respects any extra headers you set in your downstream app. You are free to set caching policies, etc. however you like. Incoming HEAD requests skip the rendering step.
There are a decent number of specs but the middleware isn’t very strict at checking setup options at the moment, and I’m sure there are a few edge cases that need to be looked into. Comments, suggestions and bug reports are welcome.
Meta
Written by Aleks Williams (github.com/akdubya)
Credit goes to the repoze.bitblt (pypi.python.org/pypi/repoze.bitblt) team for the clever url-signing implementation. My original security scheme was stupidly complex.
Released under the MIT License: www.opensource.org/licenses/mit-license.php
github.com/akdubya/rack-thumb