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.
-
#etag_matches?(etag) ⇒ Boolean
Determine if response’s ETag matches the etag value provided.
-
#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).
-
#last_modified_at?(time_value) ⇒ Boolean
Determine if the response was last modified at the time provided.
-
#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.
-
#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 @headers = Rack::Utils::HeaderHash.new(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.
148 149 150 |
# File 'lib/rack/cache/response.rb', line 148 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.
68 69 70 |
# File 'lib/rack/cache/response.rb', line 68 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.
74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rack/cache/response.rb', line 74 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.
102 103 104 105 106 |
# File 'lib/rack/cache/response.rb', line 102 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.
196 197 198 |
# File 'lib/rack/cache/response.rb', line 196 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, set the Date header to Time.now and return.
138 139 140 141 142 143 144 145 |
# File 'lib/rack/cache/response.rb', line 138 def date if date = headers['Date'] Time.httpdate(date) else headers['Date'] = now.httpdate unless headers.frozen? now end end |
#etag ⇒ Object
The literal value of ETag HTTP header or nil if no ETag is specified.
207 208 209 |
# File 'lib/rack/cache/response.rb', line 207 def etag headers['ETag'] end |
#etag_matches?(etag) ⇒ Boolean
Determine if response’s ETag matches the etag value provided. Return false when either value is nil.
220 221 222 |
# File 'lib/rack/cache/response.rb', line 220 def etag_matches?(etag) etag && self.etag == etag end |
#expire! ⇒ Object
Mark the response stale by setting the Age header to be equal to the maximum age of the response.
132 133 134 |
# File 'lib/rack/cache/response.rb', line 132 def expire! headers['Age'] = max_age.to_s if fresh? end |
#expires ⇒ Object
The value of the Expires header as a Time object.
164 165 166 |
# File 'lib/rack/cache/response.rb', line 164 def expires headers['Expires'] && Time.httpdate(headers['Expires']) 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.
92 93 94 |
# File 'lib/rack/cache/response.rb', line 92 def fresh? ttl && ttl > 0 end |
#initialize_copy(other) ⇒ Object
40 41 42 43 |
# File 'lib/rack/cache/response.rb', line 40 def initialize_copy(other) super @headers = other.headers.dup 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).
202 203 204 |
# File 'lib/rack/cache/response.rb', line 202 def last_modified headers['Last-Modified'] end |
#last_modified_at?(time_value) ⇒ Boolean
Determine if the response was last modified at the time provided. time_value is the exact string provided in an origin response’s Last-Modified header.
214 215 216 |
# File 'lib/rack/cache/response.rb', line 214 def last_modified_at?(time_value) time_value && last_modified == time_value 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 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.
157 158 159 160 161 |
# File 'lib/rack/cache/response.rb', line 157 def 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.
170 171 172 |
# File 'lib/rack/cache/response.rb', line 170 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.
126 127 128 |
# File 'lib/rack/cache/response.rb', line 126 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 |
# File 'lib/rack/cache/response.rb', line 242 def not_modified! 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.
116 117 118 119 120 |
# File 'lib/rack/cache/response.rb', line 116 def private=(value) value = value ? true : nil self.cache_control = cache_control. merge('public' => !value, 'private' => value) end |
#shared_max_age=(value) ⇒ Object
Like #max_age= but sets the s-maxage directive, which applies only to shared caches.
176 177 178 |
# File 'lib/rack/cache/response.rb', line 176 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.
46 47 48 |
# File 'lib/rack/cache/response.rb', line 46 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.
184 185 186 |
# File 'lib/rack/cache/response.rb', line 184 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.
190 191 192 |
# File 'lib/rack/cache/response.rb', line 190 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.
110 111 112 |
# File 'lib/rack/cache/response.rb', line 110 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.
250 251 252 |
# File 'lib/rack/cache/response.rb', line 250 def vary headers['Vary'] end |
#vary? ⇒ Boolean
Does the response include a Vary header?
255 256 257 |
# File 'lib/rack/cache/response.rb', line 255 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.
261 262 263 264 |
# File 'lib/rack/cache/response.rb', line 261 def vary_header_names return [] unless vary = headers['Vary'] vary.split(/[\s,]+/) end |