class Rack::Cache::Response
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.
Constants
- CACHEABLE_RESPONSE_CODES
Status codes of responses that MAY be stored by a cache or used in reply to a subsequent request.
- NOT_MODIFIED_OMIT_HEADERS
Headers that MUST NOT be included with 304 Not Modified responses.
Attributes
Rack
response tuple accessors.
Rack
response tuple accessors.
The time when the Response
object was instantiated.
Rack
response tuple accessors.
Public Class Methods
Create a Response
instance given the response status code, header hash, and body.
# File lib/rack/cache/response.rb 32 def initialize(status, headers, body) 33 @status = status.to_i 34 @headers = Rack::Utils::HeaderHash.new(headers) 35 @body = body 36 @now = Time.now 37 @headers['Date'] ||= @now.httpdate 38 end
Public Instance Methods
The age of the response.
# File lib/rack/cache/response.rb 152 def age 153 (headers['Age'] || [(now - date).to_i, 0].max).to_i 154 end
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.
# File lib/rack/cache/response.rb 69 def cache_control 70 @cache_control ||= CacheControl.new(headers['Cache-Control']) 71 end
Set the Cache-Control header to the values specified by the Hash. See the cache_control
method for information on expected Hash structure.
# File lib/rack/cache/response.rb 75 def cache_control=(value) 76 if value.respond_to? :to_hash 77 cache_control.clear 78 cache_control.merge!(value) 79 value = cache_control.to_s 80 end 81 82 if value.nil? || value.empty? 83 headers.delete('Cache-Control') 84 else 85 headers['Cache-Control'] = value 86 end 87 end
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.
# File lib/rack/cache/response.rb 103 def cacheable? 104 return false unless CACHEABLE_RESPONSE_CODES.include?(status) 105 return false if cache_control.no_store? || cache_control.private? 106 validateable? || fresh? 107 end
Set the response's time-to-live for private/client caches. This adjusts the Cache-Control/max-age directive.
# File lib/rack/cache/response.rb 209 def client_ttl=(seconds) 210 self.max_age = age + seconds 211 end
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.
# File lib/rack/cache/response.rb 139 def date 140 if date = headers['Date'] 141 Time.httpdate(date) 142 else 143 headers['Date'] = now.httpdate unless headers.frozen? 144 now 145 end 146 rescue ArgumentError 147 headers['Date'] = now.httpdate unless headers.frozen? 148 now 149 end
The literal value of ETag HTTP header or nil if no ETag is specified.
# File lib/rack/cache/response.rb 220 def etag 221 headers['ETag'] 222 end
Mark the response stale by setting the Age header to be equal to the maximum age of the response.
# File lib/rack/cache/response.rb 133 def expire! 134 headers['Age'] = max_age.to_s if fresh? 135 end
The value of the Expires header as a Time object.
# File lib/rack/cache/response.rb 169 def expires 170 headers['Expires'] && Time.httpdate(headers['Expires']) 171 rescue ArgumentError 172 nil 173 end
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.
# File lib/rack/cache/response.rb 93 def fresh? 94 ttl && ttl > 0 95 end
# File lib/rack/cache/response.rb 40 def initialize_copy(other) 41 super 42 @headers = other.headers.dup 43 @cache_control = nil 44 end
The String value of the Last-Modified header exactly as it appears in the response (i.e., no date parsing / conversion is performed).
# File lib/rack/cache/response.rb 215 def last_modified 216 headers['Last-Modified'] 217 end
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.
# File lib/rack/cache/response.rb 161 def max_age 162 cache_control.reverse_max_age || 163 cache_control.shared_max_age || 164 cache_control.max_age || 165 (expires && (expires - date)) 166 end
The number of seconds after which the response should no longer be considered fresh. Sets the Cache-Control max-age directive.
# File lib/rack/cache/response.rb 177 def max_age=(value) 178 self.cache_control = cache_control.merge('max-age' => value.to_s) 179 end
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.
# File lib/rack/cache/response.rb 127 def must_revalidate? 128 cache_control.must_revalidate || cache_control.proxy_revalidate 129 end
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.
tools.ietf.org/html/rfc2616#section-10.3.5
# File lib/rack/cache/response.rb 242 def not_modified! 243 body.close if body.respond_to?(:close) 244 self.status = 304 245 self.body = [] 246 NOT_MODIFIED_OMIT_HEADERS.each { |name| headers.delete(name) } 247 nil 248 end
Mark the response “private”, making it ineligible for serving other clients.
# File lib/rack/cache/response.rb 117 def private=(value) 118 value = value ? true : nil 119 self.cache_control = cache_control. 120 merge('public' => !value, 'private' => value) 121 end
Like shared_max_age=
but sets the r-maxage directive, which applies only to reverse caches.
# File lib/rack/cache/response.rb 189 def reverse_max_age=(value) 190 self.cache_control = cache_control.merge('r-maxage' => value.to_s) 191 end
Return the status, headers, and body in a three-tuple.
# File lib/rack/cache/response.rb 47 def to_a 48 [status, headers.to_hash, body] 49 end
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.
# File lib/rack/cache/response.rb 197 def ttl 198 max_age - age if max_age 199 end
Set the response's time-to-live for shared caches to the specified number of seconds. This adjusts the Cache-Control/s-maxage directive.
# File lib/rack/cache/response.rb 203 def ttl=(seconds) 204 self.shared_max_age = age + seconds 205 end
Determine if the response includes headers that can be used to validate the response with the origin using a conditional GET request.
# File lib/rack/cache/response.rb 111 def validateable? 112 headers.key?('Last-Modified') || headers.key?('ETag') 113 end
The literal value of the Vary header, or nil when no header is present.
# File lib/rack/cache/response.rb 251 def vary 252 headers['Vary'] 253 end
Does the response include a Vary header?
# File lib/rack/cache/response.rb 256 def vary? 257 ! vary.nil? 258 end
An array of header names given in the Vary header or an empty array when no Vary header is present.
# File lib/rack/cache/response.rb 262 def vary_header_names 263 return [] unless vary = headers['Vary'] 264 vary.split(/[\s,]+/) 265 end