Module: Merb::ConditionalGetMixin

Included in:
Controller
Defined in:
lib/merb-core/controller/mixins/conditional_get.rb

Overview

Provides conditional get support in Merb core. Conditional get support is intentionally simple and does not do fancy stuff like making ETag value from Ruby objects for you.

The most interesting method for end user is request_fresh? that is used after setting of last modification time or ETag:

Examples:

def show
  self.etag = Digest::SHA1.hexdigest(calculate_cache_key(params))

  if request_fresh?
    self.status = 304
    return ''
  else
    @product = Product.get(params[:id])
    display @product
  end
end

Instance Method Summary collapse

Instance Method Details

#etagString?

Value of the ETag header



42
43
44
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 42

def etag
  headers[Merb::Const::ETAG]
end

#etag=(tag) ⇒ String

Sets ETag response header by calling #to_s on the argument



32
33
34
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 32

def etag=(tag)
  headers[Merb::Const::ETAG] = %("#{tag}")
end

#etag_matches?(tag = self.etag) ⇒ true

Test to see if the request’s Etag matches the one supplied locally



52
53
54
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 52

def etag_matches?(tag = self.etag)
  tag == self.request.if_none_match
end

#last_modifiedTime?

Value of the Last-Modified header



75
76
77
78
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 75

def last_modified
  last_mod = headers[Merb::Const::LAST_MODIFIED]
  Time.rfc2822(last_mod) if last_mod
end

#last_modified=(time) ⇒ String

Sets Last-Modified response header



63
64
65
66
67
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 63

def last_modified=(time)
  time = time.to_time if time.is_a?(DateTime)
  # time.utc.strftime("%a, %d %b %Y %X") if we could rely on locale being American
  headers[Merb::Const::LAST_MODIFIED] = time.httpdate
end

#not_modified?(time = self.last_modified) ⇒ true, false

Test to see if the request’s If-Modified-Since is satisfied



88
89
90
91
92
93
94
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 88

def not_modified?(time = self.last_modified)
  if !request.if_modified_since.nil? and !time.nil?
    time <= request.if_modified_since
  else
    false
  end
end

#request_fresh?true, false

Tests freshness of response using all supplied validators

A response with no validators is always stale.



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 104

def request_fresh?
  # make sure we have something to compare too.
  return false unless last_modified or etag

  fresh = true

  # only check if we have set the right headers
  fresh &&= etag_matches?(self.etag) if etag
  fresh &&= not_modified?(self.last_modified) if last_modified
  fresh
end