Skip to content

Instantly share code, notes, and snippets.

@shinzui
Created October 21, 2009 00:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shinzui/214739 to your computer and use it in GitHub Desktop.
Save shinzui/214739 to your computer and use it in GitHub Desktop.
Rack route decoupling example using the rack sparklines middleware
# Example from Rick Olson's Sparklines middleware
# http://github.com/technoweenie/rack-sparklines/blob/master/lib/rack-sparklines.rb
module Rack
class Sparklines
def initialize(app, options = {})
@app, @options = app, options
end
def call(env)
if env['PATH_INFO'][@options[:prefix]] == @options[:prefix]
@data_path = env['PATH_INFO'][@options[:prefix].size+1..-1]
@data_path.sub! /\.png$/, ''
@png_path = @data_path + ".png"
@cache_file = ::File.join(@options[:directory], @png_path)
# ...
[200, {
"Last-Modified" => ::File.mtime(@cache_file).rfc822,
"Content-Type" => "image/png",
"Content-Length" => ::File.size(@cache_file).to_s
}, self]
else
@app.call(env)
end
end
end
end
# Refactored to decouple rack app from routing concern
module Rack
class Sparklines
def initialize(options = {})
@options = options
end
def call(env)
data_path = env['PATH_INFO']
data_path.sub! /\.png$/, ''
png_path = data_path + ".png"
cache_file = ::File.join(@options[:directory], png_path)
# ...
[200, {
"Last-Modified" => ::File.mtime(cache_file).rfc822,
"Content-Type" => "image/png",
"Content-Length" => ::File.size(cache_file).to_s
}, self]
end
class Mapping
def initialize(app, options = {})
@app, @prefix = app, /^#{options.delete(:prefix)}/
@sparklines = Sparklines.new(options)
end
def call(env)
if env['PATH_INFO'] =~ @prefix
env['PATH_INFO'] = env['PATH_INFO'].gsub(@prefix, '')
@sparklines.call(env)
else
@app.call(env)
end
end
end
end
end
# Use as a middleware
use Rack::Sparklines::Mapping, :prefix => "/sparks", :directory => 'data'
# Or use with map or any standard rack router
map '/sparks', Rack::Sparklines.new(:directory => 'data')
map '/', Sinatra::Application
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment