Module: Merb::ConditionalGetMixin

Included in:
Controller
Defined in:
merb-core/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:

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

- (String?) etag

Value of the ETag header.



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

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

- (String) etag=(tag)

Sets ETag response header by calling #to_s on the argument



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

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

- (Boolean) etag_matches?(tag = self.etag)

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



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

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

- (Time?) last_modified

Value of the Last-Modified header



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

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

- (String) last_modified=(time)

Sets Last-Modified response header



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

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

- (Boolean) not_modified?(time = self.last_modified)

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



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

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

- (Boolean) request_fresh?

Tests freshness of response using all supplied validators

A response with no validators is always stale.



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

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