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.
32 33 34 35 36 37 38 |
# File 'lib/rack/cache/response.rb', line 32 def initialize(status, headers, body) @status = status.to_i @headers = Rack::Cache::Headers(headers) @body = body @now = Time.now @headers['date'] ||= @now.httpdate end |
Instance Attribute Details
#body ⇒ Object
Rack response tuple accessors.
25 26 27 |
# File 'lib/rack/cache/response.rb', line 25 def body @body end |
#headers ⇒ Object
Rack response tuple accessors.
25 26 27 |
# File 'lib/rack/cache/response.rb', line 25 def headers @headers end |
#now ⇒ Object (readonly)
The time when the Response object was instantiated.
28 29 30 |
# File 'lib/rack/cache/response.rb', line 28 def now @now end |
#status ⇒ Object
Rack response tuple accessors.
25 26 27 |
# File 'lib/rack/cache/response.rb', line 25 def status @status end |
Instance Method Details
#age ⇒ Object
The age of the response.
152 153 154 |
# File 'lib/rack/cache/response.rb', line 152 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.
69 70 71 |
# File 'lib/rack/cache/response.rb', line 69 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.
75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/rack/cache/response.rb', line 75 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.
103 104 105 106 107 |
# File 'lib/rack/cache/response.rb', line 103 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.
209 210 211 |
# File 'lib/rack/cache/response.rb', line 209 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.
139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/rack/cache/response.rb', line 139 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.
220 221 222 |
# File 'lib/rack/cache/response.rb', line 220 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.
133 134 135 |
# File 'lib/rack/cache/response.rb', line 133 def expire! headers['age'] = max_age.to_s if fresh? end |
#expires ⇒ Object
The value of the expires header as a Time object.
169 170 171 172 173 |
# File 'lib/rack/cache/response.rb', line 169 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.
93 94 95 |
# File 'lib/rack/cache/response.rb', line 93 def fresh? ttl && ttl > 0 end |
#initialize_copy(other) ⇒ Object
40 41 42 43 44 |
# File 'lib/rack/cache/response.rb', line 40 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).
215 216 217 |
# File 'lib/rack/cache/response.rb', line 215 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.
161 162 163 164 165 166 |
# File 'lib/rack/cache/response.rb', line 161 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.
177 178 179 |
# File 'lib/rack/cache/response.rb', line 177 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.
127 128 129 |
# File 'lib/rack/cache/response.rb', line 127 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.
242 243 244 245 246 247 248 |
# File 'lib/rack/cache/response.rb', line 242 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.
117 118 119 120 121 |
# File 'lib/rack/cache/response.rb', line 117 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.
189 190 191 |
# File 'lib/rack/cache/response.rb', line 189 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.
183 184 185 |
# File 'lib/rack/cache/response.rb', line 183 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.
47 48 49 |
# File 'lib/rack/cache/response.rb', line 47 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.
197 198 199 |
# File 'lib/rack/cache/response.rb', line 197 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.
203 204 205 |
# File 'lib/rack/cache/response.rb', line 203 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.
111 112 113 |
# File 'lib/rack/cache/response.rb', line 111 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.
251 252 253 |
# File 'lib/rack/cache/response.rb', line 251 def vary headers['vary'] end |
#vary? ⇒ Boolean
Does the response include a vary header?
256 257 258 |
# File 'lib/rack/cache/response.rb', line 256 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.
262 263 264 265 |
# File 'lib/rack/cache/response.rb', line 262 def vary_header_names return [] unless vary = headers['vary'] vary.split(/[\s,]+/) end |