Skip to content

Instantly share code, notes, and snippets.

@robertsosinski
Created September 1, 2011 22:20
Show Gist options
  • Select an option

  • Save robertsosinski/1187446 to your computer and use it in GitHub Desktop.

Select an option

Save robertsosinski/1187446 to your computer and use it in GitHub Desktop.
Varnish utility module, requires extended Net::HTTP
require 'net/http'
module Net
class HTTP
class Purge < HTTPRequest
METHOD = "PURGE"
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
end
class Ban < HTTPRequest
METHOD = "BAN"
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
end
def ban(path, initheader = nil)
request(Ban.new(path, initheader))
end
def purge(path, initheader = nil)
request(Purge.new(path, initheader))
end
end
def HTTP.purge(path, initheader = nil)
uri = URI.parse(path)
new(uri.host, uri.port).start do |http|
http.purge(uri.path)
end
end
def HTTP.ban(path, initheader = nil)
uri = URI.parse(path)
new(uri.host, uri.port).start do |http|
http.ban(uri.path)
end
end
end
require 'net/http'
module Varnish
def self.included(base)
base.send :extend, ClassMethods
base.send :include, InstanceMethods
end
module ClassMethods
# Enables edge-side-includes for the listed actions
# esi :index, :show, :new
def esi(*actions)
after_filter lambda { response.headers['X-Varnish-Esi'] = 'true' }, :only => actions
end
end
module InstanceMethods
# Removes an object from cache
# purge("/pages/123")
def purge(path)
http = Net::HTTP.new(request.host, request.port)
http.purge(path).code == "200"
end
# Creates a new netry in varnish's ban list
# ban("req.http.host == example.com && req.url ~ \.png$")
def ban(value)
http = Net::HTTP.new(request.host, request.port)
http.ban('/', {'X-Varnish-Ban' => value}).code == "200"
end
# Sets the time-to-live for an object in varnish. Can take both a Time or Integer.
# cache 1.hour
# cache 1.day.from_now
def cache(value)
if value.is_a?(Time)
ttl = value.utc.to_i - Time.now.utc.to_i
stale = value.utc + 1.second
else
ttl = value.to_i
stale = ttl.from_now.utc + 1.second
end
response.headers['X-Fresh-Until'] = stale.strftime("%a, %d %b %Y %H:%M:%S GMT")
response.headers['X-Varnish-Ttl'] = ttl.to_s
end
# Sets the Cache-Control header for the response, this was taken from Sinatra.
# cache_control :public, :max_age => 1.hour
# cache_control :private, :must_revalidate
def cache_control(*values)
if values.last.kind_of?(Hash)
hash = values.pop
hash.reject! { |k,v| v == false }
hash.reject! { |k,v| values << k if v == true }
else
hash = {}
end
values = values.map { |value| value.to_s.tr('_','-') }
hash.each do |key, value|
key = key.to_s.tr('_', '-')
value = value.to_i if key == "max-age"
values << [key, value].join('=')
end
response['Cache-Control'] = values.join(', ') if values.any?
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment