module Roda::RodaPlugins::Caching::RequestMethods

def etag(value, opts=OPTS)

etag that doesn't match, immediately returns a response with a 412 status.
When the current request includes an If-Match header with a

depending on the request method.
matching etag, immediately returns a response with a 304 or 412 status,
When the current request includes an If-None-Match header with a

:new_resource :: Whether this etag should match an etag of * (true for POST, false otherwise)
:weak :: Use a weak cache validator (a strong cache validator is the default)
Options:
identifies the current version of the resource.
The +value+ argument is an identifier that uniquely

Set the response entity tag using the ETag header.
def etag(value, opts=OPTS)
  # Before touching this code, please double check RFC 2616 14.24 and 14.26.
  weak = opts[:weak]
  new_resource = opts.fetch(:new_resource){post?}
  res = response
  e = env
  res[RodaResponseHeaders::ETAG] = etag = "#{'W/' if weak}\"#{value}\""
  status = res.status
  if (!status || (status >= 200 && status < 300) || status == 304)
    if etag_matches?(e['HTTP_IF_NONE_MATCH'], etag, new_resource)
      res.status = (request_method =~ /\AGET|HEAD|OPTIONS|TRACE\z/i ? 304 : 412)
      halt
    end
    if ifm = e['HTTP_IF_MATCH']
      unless etag_matches?(ifm, etag, new_resource)
        res.status = 412
        halt
      end
    end
  end
end

def etag_matches?(list, etag, new_resource)

Helper method checking if a ETag value list includes the current ETag.
def etag_matches?(list, etag, new_resource)
  return unless list
  return !new_resource if list == '*'
  list.to_s.split(/\s*,\s*/).include?(etag)
end

def last_modified(time)

with a 412 status.
before than the time specified, immediately returns a response
If the current request includes an If-Unmodified-Since header that is

with a 304 status.
equal or later than the time specified, immediately returns a response
If the current request includes an If-Modified-Since header that is

The +time+ argument should be a Time instance.
Set the last modified time of the resource using the Last-Modified header.
def last_modified(time)
  return unless time
  res = response
  e = env
  res[RodaResponseHeaders::LAST_MODIFIED] = time.httpdate
  return if e['HTTP_IF_NONE_MATCH']
  status = res.status
  if (!status || status == 200) && (ims = time_from_header(e['HTTP_IF_MODIFIED_SINCE'])) && ims >= time.to_i
    res.status = 304
    halt
  end
  if (!status || (status >= 200 && status < 300) || status == 412) && (ius = time_from_header(e['HTTP_IF_UNMODIFIED_SINCE'])) && ius < time.to_i
    res.status = 412
    halt
  end
end

def time_from_header(t)

time as an integer.
Helper method parsing a time value from an HTTP header, returning the
def time_from_header(t)
  Time.httpdate(t).to_i if t
rescue ArgumentError
end