Skip to content

Instantly share code, notes, and snippets.

@nutrun
Created May 18, 2009 12:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nutrun/113441 to your computer and use it in GitHub Desktop.
Save nutrun/113441 to your computer and use it in GitHub Desktop.
Middleware for configuring HTTP cache policy headers in Rack based web applications.
# Cache Headers
# Middleware for configuring HTTP cache policy headers in Rack based web applications.
# Apply cache headers to HTTP responses corresponding to requests that match defined
# URI patterns.
#
# Example usage:
#
# use Rack::CacheHeaders
#
# Rack::CacheHeaders.configure do |cache|
# cache.max_age(/^\/$/, 3600)
# cache.private(/^\/search$/)
# cache.pragma_no_cache(/^\/search$/)
# cache.expires(/^\/search$/, Time.now - 630720000)
# cache.expires(/^\/about\/.+$/, "00:00")
# end
module Rack
class CacheHeaders
def initialize(app)
@app = app
end
def call(env)
result = @app.call(env)
if path = Configuration[env['PATH_INFO']]
path.each do |policy|
header = policy.to_header
result[1][header.key] = header.value
end
end
result
end
def self.configure(&block)
yield Configuration
end
class Configuration
def self.max_age(path, duration)
(paths[path] ||= []) << MaxAge.new(duration)
end
def self.expires(path, date)
(paths[path] ||= []) << Expires.new(date)
end
def self.private(path)
(paths[path] ||= []) << Private.new
end
def self.pragma_no_cache(path)
(paths[path] ||= []) << PragmaNoCache.new
end
def self.[](key)
key = paths.keys.find { |e| e =~ key }
paths[key] if key
end
def self.paths
@paths ||= {}
end
end
class MaxAge
def initialize(duration)
@duration = duration
end
def to_header
Header.new("Cache-Control", "max-age=#{@duration}, must-revalidate")
end
end
class Expires
def initialize(date)
@date = date
end
def to_header
if @date.is_a?(Time)
Header.new("Expires", @date.httpdate)
else
d = Time.parse(@date)
d = d + (60*60*24) if d < Time.now
Header.new("Expires", d.httpdate)
end
end
end
class Private
def to_header
Header.new("Cache-Control", 'private')
end
end
class PragmaNoCache
def to_header
Header.new('Pragma', 'no-cache')
end
end
class Header < Struct.new(:key, :value);end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment