Class: HTTP::Response::Caching

Inherits:
HTTP::Response show all
Defined in:
lib/http/response/caching.rb

Overview

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

Constant Summary collapse

CACHEABLE_RESPONSE_CODES =
[200, 203, 300, 301, 410].freeze

Constants inherited from HTTP::Response

STATUS_CODES, SYMBOL_TO_STATUS_CODE

Instance Attribute Summary collapse

Attributes inherited from HTTP::Response

#status, #uri

Attributes included from Headers::Mixin

#headers

Instance Method Summary collapse

Methods inherited from HTTP::Response

#charset, #code, #content_type, #cookies, #flush, #inspect, #mime_type, #parse, #readpartial, #reason, #to_a, #to_s

Methods included from Headers::Mixin

#[], #[]=

Constructor Details

#initialize(obj) ⇒ Caching

Returns a new instance of Caching.



12
13
14
15
16
# File 'lib/http/response/caching.rb', line 12

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

Instance Attribute Details

#received_atTime

Returns the time at which this response was received.

Returns:

  • (Time)

    the time at which this response was received



73
74
75
# File 'lib/http/response/caching.rb', line 73

def received_at
  @received_at ||= Time.now
end

#requested_atTime

Returns the time at which this response was requested.

Returns:

  • (Time)

    the time at which this response was requested



67
68
69
# File 'lib/http/response/caching.rb', line 67

def requested_at
  @requested_at ||= received_at
end

Instance Method Details

#bodyObject



91
92
93
94
95
96
97
# File 'lib/http/response/caching.rb', line 91

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

#body=(new_body) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/http/response/caching.rb', line 99

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

#cache_headersHTTP::Cache::Headers

Returns cache control headers helper object.

Returns:



87
88
89
# File 'lib/http/response/caching.rb', line 87

def cache_headers
  @cache_headers ||= HTTP::Cache::Headers.new headers
end

#cacheable?Boolean


A Vary header field-value of "*" always fails to match and subsequent requests on that resource can only be properly interpreted by the

Returns:

  • (Boolean)

    true iff this response is cacheable



39
40
41
42
43
44
45
46
47
# File 'lib/http/response/caching.rb', line 39

def cacheable?
  @cacheable ||=
    begin
      CACHEABLE_RESPONSE_CODES.include?(code) \
        && !(cache_headers.vary_star? ||
             cache_headers.no_store?  ||
             cache_headers.no_cache?)
    end
end

#cachingHTTP::Response::Caching



19
20
21
# File 'lib/http/response/caching.rb', line 19

def caching
  self
end

#current_ageNumeric

Returns:

  • (Numeric)

    the current age (in seconds) of this response



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/http/response/caching.rb', line 53

def current_age
  now = Time.now
  age_value  = headers.get("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

#expired?Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/http/response/caching.rb', line 29

def expired?
  current_age >= cache_headers.max_age
end

#stale?Boolean

Returns true iff this response is stale.

Returns:

  • (Boolean)

    true iff this response is stale



24
25
26
# File 'lib/http/response/caching.rb', line 24

def stale?
  expired? || cache_headers.must_revalidate?
end

#validated!(validating_response) ⇒ Object

Update self based on this response being revalidated by the server.



80
81
82
83
84
# File 'lib/http/response/caching.rb', line 80

def validated!(validating_response)
  headers.merge!(validating_response.headers)
  self.requested_at  = validating_response.requested_at
  self.received_at   = validating_response.received_at
end

#varyObject



118
119
120
# File 'lib/http/response/caching.rb', line 118

def vary
  headers.get("Vary").first
end