raskchanky (owner)

Fork Of

gist: 113441 by gmalamid Middleware for configuring ...

Revisions

gist: 113605 Download_button fork
public
Public Clone URL: git://gist.github.com/113605.git
Embed All Files: show embed
cache_headers.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# 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