Module: Roda::RodaPlugins::Caching::RequestMethods

Defined in:
lib/roda/plugins/caching.rb

Constant Summary collapse

LAST_MODIFIED =
'Last-Modified'.freeze
HTTP_IF_NONE_MATCH =
'HTTP_IF_NONE_MATCH'.freeze
HTTP_IF_MATCH =
'HTTP_IF_MATCH'.freeze
HTTP_IF_MODIFIED_SINCE =
'HTTP_IF_MODIFIED_SINCE'.freeze
HTTP_IF_UNMODIFIED_SINCE =
'HTTP_IF_UNMODIFIED_SINCE'.freeze
ETAG =
'ETag'.freeze
STAR =
'*'.freeze

Instance Method Summary collapse

Instance Method Details

#etag(value, opts = OPTS) ⇒ Object

Set the response entity tag using the ETag header.

The value argument is an identifier that uniquely identifies the current version of the resource. Options:

:weak

Use a weak cache validator (a strong cache validator is the default)

:new_resource

Whether this etag should match an etag of * (true for POST, false otherwise)

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

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



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/roda/plugins/caching.rb', line 126

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[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

#last_modified(time) ⇒ Object

Set the last modified time of the resource using the Last-Modified header. The time argument should be a Time instance.

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

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



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/roda/plugins/caching.rb', line 93

def last_modified(time)
  return unless time
  res = response
  e = env
  res[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