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:

Example

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

#etagObject

Returns

<String>

Value of ETag response header or nil if it’s not set.

:api: public



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

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

#etag=(tag) ⇒ Object

Sets ETag response header by calling #to_s on the argument.

Parameters

tag<~to_s>

value of ETag header enclosed in double quotes as required by the RFC

:api: public



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

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

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

Returns

<Boolean>

true if ETag response header equals If-None-Match request header, false otherwise

:api: public

Returns:

  • (Boolean)


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

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

#last_modifiedObject

Returns

<String>

Value of Last-Modified response header or nil if it’s not set.

:api: public



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

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

#last_modified=(time) ⇒ Object

Sets Last-Modified response header.

Parameters

tag<Time>

resource modification timestamp converted into format required by the RFC

:api: public



65
66
67
68
69
# File '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

#not_modified?(time = self.last_modified) ⇒ Boolean

Returns

<Boolean>

true if Last-Modified response header is < than If-Modified-Since request header value, false otherwise.

:api: public

Returns:

  • (Boolean)


87
88
89
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 87

def not_modified?(time = self.last_modified)
  request.if_modified_since && time && time <= request.if_modified_since
end

#request_fresh?Boolean

Returns

<Boolean>

true if either ETag matches or entity is not modified, so request is fresh; false otherwise

:api: public

Returns:

  • (Boolean)


97
98
99
# File 'lib/merb-core/controller/mixins/conditional_get.rb', line 97

def request_fresh?
  etag_matches?(self.etag) || not_modified?(self.last_modified)
end