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::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.
151 152 153 |
# File 'lib/rack/cache/response.rb', line 151 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.
208 209 210 |
# File 'lib/rack/cache/response.rb', line 208 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.
138 139 140 141 142 143 144 145 146 147 148 |
# 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 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.
219 220 221 |
# File 'lib/rack/cache/response.rb', line 219 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.
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.
168 169 170 171 172 |
# File 'lib/rack/cache/response.rb', line 168 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.
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).
214 215 216 |
# File 'lib/rack/cache/response.rb', line 214 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.
160 161 162 163 164 165 |
# File 'lib/rack/cache/response.rb', line 160 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.
176 177 178 |
# File 'lib/rack/cache/response.rb', line 176 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.
241 242 243 244 245 246 247 |
# File 'lib/rack/cache/response.rb', line 241 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.
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 |
#reverse_max_age=(value) ⇒ Object
Like #shared_max_age= but sets the r-maxage directive, which applies only to reverse caches.
188 189 190 |
# File 'lib/rack/cache/response.rb', line 188 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.
182 183 184 |
# File 'lib/rack/cache/response.rb', line 182 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.
196 197 198 |
# File 'lib/rack/cache/response.rb', line 196 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.
202 203 204 |
# File 'lib/rack/cache/response.rb', line 202 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 |