Class: Rack::Cache::Response
- Inherits:
-
Object
- Object
- Rack::Cache::Response
- Includes:
- Response::Helpers
- Defined in:
- lib/rack/cache/response.rb
Overview
Provides access to the response generated by the downstream application. The response, original_response, and entry objects exposed by the Core caching engine are instances of this class.
Response objects respond to a variety of convenience methods, including those defined in Rack::Response::Helpers, Rack::Cache::Headers, and Rack::Cache::ResponseHeaders.
Note that Rack::Cache::Response is not a subclass of Rack::Response and does not perform many of the same initialization and finalization tasks. For example, the body is not slurped during initialization and there are no facilities for generating response output.
Constant Summary collapse
- CACHEABLE_RESPONSE_CODES =
Status codes of responses that MAY be stored by a cache or used in reply to a subsequent request.
[ 200, # OK 203, # Non-Authoritative Information 300, # Multiple Choices 301, # Moved Permanently 302, # Found 404, # Not Found 410 # Gone ].to_set
- NOT_MODIFIED_OMIT_HEADERS =
Headers that MUST NOT be included with 304 Not Modified responses.
%w[ allow content-encoding content-language content-length content-md5 content-type last-modified ].to_set
Instance Attribute Summary collapse
-
#body ⇒ Object
Rack response tuple accessors.
-
#headers ⇒ Object
Rack response tuple accessors.
-
#now ⇒ Object
readonly
The time when the Response object was instantiated.
-
#status ⇒ Object
Rack response tuple accessors.
Instance Method Summary collapse
-
#age ⇒ Object
The age of the response.
-
#cache_control ⇒ Object
A Hash of name=value pairs that correspond to the cache-control header.
-
#cache_control=(value) ⇒ Object
Set the cache-control header to the values specified by the Hash.
-
#cacheable? ⇒ Boolean
Determine if the response is worth caching under any circumstance.
-
#client_ttl=(seconds) ⇒ Object
Set the response’s time-to-live for private/client caches.
-
#date ⇒ Object
The date, as specified by the Date header.
-
#etag ⇒ Object
The literal value of etag HTTP header or nil if no etag is specified.
-
#expire! ⇒ Object
Mark the response stale by setting the Age header to be equal to the maximum age of the response.
-
#expires ⇒ Object
The value of the expires header as a Time object.
-
#fresh? ⇒ Boolean
Determine if the response is “fresh”.
-
#initialize(status, headers, body) ⇒ Response
constructor
Create a Response instance given the response status code, header hash, and body.
- #initialize_copy(other) ⇒ Object
-
#last_modified ⇒ Object
The String value of the last-modified header exactly as it appears in the response (i.e., no date parsing / conversion is performed).
-
#max_age ⇒ Object
The number of seconds after the time specified in the response’s Date header when the the response should no longer be considered fresh.
-
#max_age=(value) ⇒ Object
The number of seconds after which the response should no longer be considered fresh.
-
#must_revalidate? ⇒ Boolean
Indicates that the cache must not serve a stale response in any circumstance without first revalidating with the origin.
-
#not_modified! ⇒ Object
Modify the response so that it conforms to the rules defined for ‘304 Not Modified’.
-
#private=(value) ⇒ Object
Mark the response “private”, making it ineligible for serving other clients.
-
#reverse_max_age=(value) ⇒ Object
Like #shared_max_age= but sets the r-maxage directive, which applies only to reverse caches.
-
#shared_max_age=(value) ⇒ Object
Like #max_age= but sets the s-maxage directive, which applies only to shared caches.
-
#to_a ⇒ Object
Return the status, headers, and body in a three-tuple.
-
#ttl ⇒ Object
The response’s time-to-live in seconds, or nil when no freshness information is present in the response.
-
#ttl=(seconds) ⇒ Object
Set the response’s time-to-live for shared caches to the specified number of seconds.
-
#validateable? ⇒ Boolean
Determine if the response includes headers that can be used to validate the response with the origin using a conditional GET request.
-
#vary ⇒ Object
The literal value of the vary header, or nil when no header is present.
-
#vary? ⇒ Boolean
Does the response include a vary header?.
-
#vary_header_names ⇒ Object
An array of header names given in the vary header or an empty array when no vary header is present.
Constructor Details
#initialize(status, headers, body) ⇒ Response
Create a Response instance given the response status code, header hash, and body.
40 41 42 43 44 45 46 |
# File 'lib/rack/cache/response.rb', line 40 def initialize(status, headers, body) @status = status.to_i @headers = Headers[headers] @body = body @now = Time.now @headers['date'] ||= @now.httpdate end |
Instance Attribute Details
#body ⇒ Object
Rack response tuple accessors.
33 34 35 |
# File 'lib/rack/cache/response.rb', line 33 def body @body end |
#headers ⇒ Object
Rack response tuple accessors.
33 34 35 |
# File 'lib/rack/cache/response.rb', line 33 def headers @headers end |
#now ⇒ Object (readonly)
The time when the Response object was instantiated.
36 37 38 |
# File 'lib/rack/cache/response.rb', line 36 def now @now end |
#status ⇒ Object
Rack response tuple accessors.
33 34 35 |
# File 'lib/rack/cache/response.rb', line 33 def status @status end |
Instance Method Details
#age ⇒ Object
The age of the response.
160 161 162 |
# File 'lib/rack/cache/response.rb', line 160 def age (headers['age'] || [(now - date).to_i, 0].max).to_i end |
#cache_control ⇒ Object
A Hash of name=value pairs that correspond to the cache-control header. Valueless parameters (e.g., must-revalidate, no-store) have a Hash value of true. This method always returns a Hash, empty if no cache-control header is present.
77 78 79 |
# File 'lib/rack/cache/response.rb', line 77 def cache_control @cache_control ||= CacheControl.new(headers['cache-control']) end |
#cache_control=(value) ⇒ Object
Set the cache-control header to the values specified by the Hash. See the #cache_control method for information on expected Hash structure.
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/rack/cache/response.rb', line 83 def cache_control=(value) if value.respond_to? :to_hash cache_control.clear cache_control.merge!(value) value = cache_control.to_s end if value.nil? || value.empty? headers.delete('cache-control') else headers['cache-control'] = value end end |
#cacheable? ⇒ Boolean
Determine if the response is worth caching under any circumstance. Responses marked “private” with an explicit cache-control directive are considered uncacheable
Responses with neither a freshness lifetime (expires, max-age) nor cache validator (last-modified, etag) are considered uncacheable.
111 112 113 114 115 |
# File 'lib/rack/cache/response.rb', line 111 def cacheable? return false unless CACHEABLE_RESPONSE_CODES.include?(status) return false if cache_control.no_store? || cache_control.private? validateable? || fresh? end |
#client_ttl=(seconds) ⇒ Object
Set the response’s time-to-live for private/client caches. This adjusts the cache-control/max-age directive.
217 218 219 |
# File 'lib/rack/cache/response.rb', line 217 def client_ttl=(seconds) self.max_age = age + seconds end |
#date ⇒ Object
The date, as specified by the Date header. When no Date header is present or is unparseable, set the Date header to Time.now and return.
147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/rack/cache/response.rb', line 147 def date if date = headers['date'] Time.httpdate(date) else headers['date'] = now.httpdate unless headers.frozen? now end rescue ArgumentError headers['date'] = now.httpdate unless headers.frozen? now end |
#etag ⇒ Object
The literal value of etag HTTP header or nil if no etag is specified.
228 229 230 |
# File 'lib/rack/cache/response.rb', line 228 def etag headers['etag'] end |
#expire! ⇒ Object
Mark the response stale by setting the Age header to be equal to the maximum age of the response.
141 142 143 |
# File 'lib/rack/cache/response.rb', line 141 def expire! headers['age'] = max_age.to_s if fresh? end |
#expires ⇒ Object
The value of the expires header as a Time object.
177 178 179 180 181 |
# File 'lib/rack/cache/response.rb', line 177 def expires headers['expires'] && Time.httpdate(headers['expires']) rescue ArgumentError nil end |
#fresh? ⇒ Boolean
Determine if the response is “fresh”. Fresh responses may be served from cache without any interaction with the origin. A response is considered fresh when it includes a cache-control/max-age indicator or Expiration header and the calculated age is less than the freshness lifetime.
101 102 103 |
# File 'lib/rack/cache/response.rb', line 101 def fresh? ttl && ttl > 0 end |
#initialize_copy(other) ⇒ Object
48 49 50 51 52 |
# File 'lib/rack/cache/response.rb', line 48 def initialize_copy(other) super @headers = other.headers.dup @cache_control = nil end |
#last_modified ⇒ Object
The String value of the last-modified header exactly as it appears in the response (i.e., no date parsing / conversion is performed).
223 224 225 |
# File 'lib/rack/cache/response.rb', line 223 def last_modified headers['last-modified'] end |
#max_age ⇒ Object
The number of seconds after the time specified in the response’s Date header when the the response should no longer be considered fresh. First check for a r-maxage directive, then a s-maxage directive, then a max-age directive, and then fall back on an expires header; return nil when no maximum age can be established.
169 170 171 172 173 174 |
# File 'lib/rack/cache/response.rb', line 169 def max_age cache_control.reverse_max_age || cache_control.shared_max_age || cache_control.max_age || (expires && (expires - date)) end |
#max_age=(value) ⇒ Object
The number of seconds after which the response should no longer be considered fresh. Sets the cache-control max-age directive.
185 186 187 |
# File 'lib/rack/cache/response.rb', line 185 def max_age=(value) self.cache_control = cache_control.merge('max-age' => value.to_s) end |
#must_revalidate? ⇒ Boolean
Indicates that the cache must not serve a stale response in any circumstance without first revalidating with the origin. When present, the TTL of the response should not be overriden to be greater than the value provided by the origin.
135 136 137 |
# File 'lib/rack/cache/response.rb', line 135 def must_revalidate? cache_control.must_revalidate || cache_control.proxy_revalidate end |
#not_modified! ⇒ Object
Modify the response so that it conforms to the rules defined for ‘304 Not Modified’. This sets the status, removes the body, and discards any headers that MUST NOT be included in 304 responses.
250 251 252 253 254 255 256 |
# File 'lib/rack/cache/response.rb', line 250 def not_modified! body.close if body.respond_to?(:close) self.status = 304 self.body = [] NOT_MODIFIED_OMIT_HEADERS.each { |name| headers.delete(name) } nil end |
#private=(value) ⇒ Object
Mark the response “private”, making it ineligible for serving other clients.
125 126 127 128 129 |
# File 'lib/rack/cache/response.rb', line 125 def private=(value) value = value ? true : nil self.cache_control = cache_control. merge('public' => !value, 'private' => value) end |
#reverse_max_age=(value) ⇒ Object
Like #shared_max_age= but sets the r-maxage directive, which applies only to reverse caches.
197 198 199 |
# File 'lib/rack/cache/response.rb', line 197 def reverse_max_age=(value) self.cache_control = cache_control.merge('r-maxage' => value.to_s) end |
#shared_max_age=(value) ⇒ Object
Like #max_age= but sets the s-maxage directive, which applies only to shared caches.
191 192 193 |
# File 'lib/rack/cache/response.rb', line 191 def shared_max_age=(value) self.cache_control = cache_control.merge('s-maxage' => value.to_s) end |
#to_a ⇒ Object
Return the status, headers, and body in a three-tuple.
55 56 57 |
# File 'lib/rack/cache/response.rb', line 55 def to_a [status, headers.to_hash, body] end |
#ttl ⇒ Object
The response’s time-to-live in seconds, or nil when no freshness information is present in the response. When the responses #ttl is <= 0, the response may not be served from cache without first revalidating with the origin.
205 206 207 |
# File 'lib/rack/cache/response.rb', line 205 def ttl max_age - age if max_age end |
#ttl=(seconds) ⇒ Object
Set the response’s time-to-live for shared caches to the specified number of seconds. This adjusts the cache-control/s-maxage directive.
211 212 213 |
# File 'lib/rack/cache/response.rb', line 211 def ttl=(seconds) self.shared_max_age = age + seconds end |
#validateable? ⇒ Boolean
Determine if the response includes headers that can be used to validate the response with the origin using a conditional GET request.
119 120 121 |
# File 'lib/rack/cache/response.rb', line 119 def validateable? headers.key?('last-modified') || headers.key?('etag') end |
#vary ⇒ Object
The literal value of the vary header, or nil when no header is present.
259 260 261 |
# File 'lib/rack/cache/response.rb', line 259 def vary headers['vary'] end |
#vary? ⇒ Boolean
Does the response include a vary header?
264 265 266 |
# File 'lib/rack/cache/response.rb', line 264 def vary? ! vary.nil? end |
#vary_header_names ⇒ Object
An array of header names given in the vary header or an empty array when no vary header is present.
270 271 272 273 |
# File 'lib/rack/cache/response.rb', line 270 def vary_header_names return [] unless vary = headers['vary'] vary.split(/[\s,]+/) end |