class HTTP::Response::Caching

related to caching.
Decorator class for responses to provide convenience methods

def body

def body
  @body ||= if __getobj__.body.respond_to? :each
              __getobj__.body
            else
              StringBody.new(__getobj__.body.to_s)
            end
end

def body=(new_body)

def body=(new_body)
  @body = if new_body.respond_to?(:readpartial) && new_body.respond_to?(:read)
            # IO-ish, probably a rack cache response body
            IoBody.new(new_body)
          elsif new_body.respond_to? :join
            # probably an array of body parts (rack cache does this sometimes)
            StringBody.new(new_body.join(""))
          elsif new_body.respond_to? :readpartial
            # normal body, just use it.
            new_body
          else
            # backstop, just to_s it
            StringBody.new(new_body.to_s)
          end
end

def cache_headers

Returns:
  • (HTTP::Cache::Headers) - cache control headers helper object.
def cache_headers
  @cache_headers ||= HTTP::Cache::Headers.new headers
end

def cacheable?

Returns:
  • (Boolean) - true iff this response is cacheable
def cacheable?
  @cacheable ||=
    begin
      CACHEABLE_RESPONSE_CODES.include?(code) \
        && !(cache_headers.vary_star? ||
             cache_headers.no_store?  ||
             cache_headers.no_cache?)
    end
end

def caching

Returns:
  • (HTTP::Response::Caching) -
def caching
  self
end

def current_age

Returns:
  • (Numeric) - the current age (in seconds) of this response
def current_age
  now = Time.now
  age_value  = headers.get(HTTP::Headers::AGE).map(&:to_i).max || 0
  apparent_age = [0, received_at - server_response_time].max
  corrected_received_age = [apparent_age, age_value].max
  response_delay = [0, received_at - requested_at].max
  corrected_initial_age = corrected_received_age + response_delay
  resident_time = [0, now - received_at].max
  corrected_initial_age + resident_time
end

def expired?

Returns:
  • (Boolean) - true iff this response has expired
def expired?
  current_age >= cache_headers.max_age
end

def initialize(obj)

def initialize(obj)
  super
  @requested_at = nil
  @received_at  = nil
end

def received_at

Returns:
  • (Time) - the time at which this response was received
def received_at
  @received_at ||= Time.now
end

def requested_at

Returns:
  • (Time) - the time at which this response was requested
def requested_at
  @requested_at ||= received_at
end

def server_response_time

Returns:
  • (Time) - the time at which the server generated this response.
def server_response_time
  headers.get(HTTP::Headers::DATE).
    map(&method(:to_time_or_epoch)).
    max || begin
              # set it if it is not already set
              headers[HTTP::Headers::DATE] = received_at.httpdate
              received_at
            end
end

def stale?

Returns:
  • (Boolean) - true iff this response is stale
def stale?
  expired? || cache_headers.must_revalidate?
end

def to_time_or_epoch(t_str)

def to_time_or_epoch(t_str)
  Time.httpdate(t_str)
rescue ArgumentError
  Time.at(0)
end

def validated!(validating_response)

server.
Update self based on this response being revalidated by the
def validated!(validating_response)
  headers.merge!(validating_response.headers)
  self.requested_at  = validating_response.requested_at
  self.received_at   = validating_response.received_at
end

def vary

def vary
  headers.get(HTTP::Headers::VARY).first
end