Class: Wrest::Native::Response
- Inherits:
-
Object
- Object
- Wrest::Native::Response
- Extended by:
- Forwardable
- Includes:
- HttpCodes
- Defined in:
- lib/wrest/native/response.rb
Overview
Decorates a response providing support for deserialisation.
The following methods are also available (unlisted by rdoc because they’re forwarded to Net::HTTP::Response):
:@Http_response, :code, :message, :body, :Http_version, :[], :content_length, :content_type, :each_header, :each_name, :each_value, :fetch, :get_fields, :key?, :type_params
They behave exactly like their Net::HttpResponse equivalents.
Also provides set of HTTP response code checkers. For instance, the method ok? checks if the response was successful with HTTP code 200. See HttpCodes for a list of all such response checkers.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#deserialised_body ⇒ Object
Returns the value of attribute deserialised_body.
-
#http_response ⇒ Object
readonly
Returns the value of attribute http_response.
Class Method Summary collapse
-
.new(http_response) ⇒ Object
We’re overriding :new to act as a factory so we can build the appropriate Response instance based on the response code.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Checks equality between two Wrest::Native::Response objects.
-
#cache_control_headers ⇒ Object
The values in Cache-Control header as an array.
-
#cacheable? ⇒ Boolean
Returns whether this response is cacheable.
-
#can_be_validated? ⇒ Boolean
Can this response be validated by sending a validation request to the server.
-
#code_cacheable? ⇒ Boolean
:nodoc:.
- #connection_closed? ⇒ Boolean
-
#current_age ⇒ Object
Age of the response calculated according to RFC 2616 13.2.3.
- #deserialise(options = {}) ⇒ Object
- #deserialise_using(translator, options = {}) ⇒ Object
- #deserialize(options = {}) ⇒ Object
- #deserialize_using(options = {}) ⇒ Object
-
#expired? ⇒ Boolean
Has this response expired? The expiry is calculated from the Max-Age/Expires header.
-
#expires ⇒ Object
Returns the Expires date from the response headers.
-
#expires_not_in_its_past? ⇒ Boolean
Is the Expires of this response earlier than its Date header.
-
#expires_not_in_our_past? ⇒ Boolean
Returns whether the Expires header of this response is earlier than current time.
-
#follow(_redirect_request_options = {}) ⇒ Object
A null object implementation - invoking this method on a response simply returns the same response unless the response is Redirection (code 3xx), in which case a get is invoked on the url stored in the response headers under the key ‘location’ and the new Response is returned.
-
#freshness_lifetime ⇒ Object
How long (in seconds) is this response expected to be fresh.
-
#hash ⇒ Object
Return the hash of a Wrest::Native::Response object.
-
#headers ⇒ Object
Gives a hash of the response headers.
-
#initialize(http_response) ⇒ Response
constructor
A new instance of Response.
- #initialize_copy(source) ⇒ Object
- #last_modified ⇒ Object
-
#max_age ⇒ Object
:nodoc:.
- #no_cache_flag_not_set? ⇒ Boolean
- #no_store_flag_not_set? ⇒ Boolean
-
#parse_datefield(hash, key) ⇒ Object
:nodoc: helper function.
- #pragma_nocache_not_set? ⇒ Boolean
-
#recalculate_cache_control_headers ⇒ Object
:nodoc:.
-
#recalculate_freshness_lifetime ⇒ Object
:nodoc:.
-
#response_date ⇒ Object
Returns the Date from the response headers.
-
#vary_header_valid? ⇒ Boolean
:nodoc:.
Methods included from HttpCodes
#accepted?, #bad_request?, #created?, #forbidden?, #found?, #internal_server_error?, #method_not_allowed?, #moved_permanently?, #no_content?, #not_acceptable?, #not_found?, #not_modified?, #ok?, #see_other?, #temporary_redirect?, #unauthorized?, #unprocessable_entity?
Constructor Details
#initialize(http_response) ⇒ Response
Returns a new instance of Response.
53 54 55 |
# File 'lib/wrest/native/response.rb', line 53 def initialize(http_response) @http_response = http_response end |
Instance Attribute Details
#deserialised_body ⇒ Object
Returns the value of attribute deserialised_body.
29 30 31 |
# File 'lib/wrest/native/response.rb', line 29 def deserialised_body @deserialised_body end |
#http_response ⇒ Object (readonly)
Returns the value of attribute http_response.
28 29 30 |
# File 'lib/wrest/native/response.rb', line 28 def http_response @http_response end |
Class Method Details
.new(http_response) ⇒ Object
We’re overriding :new to act as a factory so we can build the appropriate Response instance based on the response code.
46 47 48 49 50 51 |
# File 'lib/wrest/native/response.rb', line 46 def self.new(http_response) code = http_response.code.to_i instance = ((300..303).include?(code) || (305..399).include?(code) ? Wrest::Native::Redirection : self).allocate instance.send :initialize, http_response instance end |
Instance Method Details
#==(other) ⇒ Object
Checks equality between two Wrest::Native::Response objects.
62 63 64 65 66 67 68 |
# File 'lib/wrest/native/response.rb', line 62 def ==(other) return true if equal?(other) return false unless other.class == self.class return true if these_fields_are_equal(other) false end |
#cache_control_headers ⇒ Object
The values in Cache-Control header as an array.
205 206 207 |
# File 'lib/wrest/native/response.rb', line 205 def cache_control_headers @cache_control_headers ||= recalculate_cache_control_headers end |
#cacheable? ⇒ Boolean
Returns whether this response is cacheable.
117 118 119 120 121 |
# File 'lib/wrest/native/response.rb', line 117 def cacheable? cache_configs_set? && (!max_age.nil? or (expires_not_in_our_past? && expires_not_in_its_past?)) && pragma_nocache_not_set? && vary_header_valid? end |
#can_be_validated? ⇒ Boolean
Can this response be validated by sending a validation request to the server. The response need to have either Last-Modified or ETag header (or both) for it to be validatable.
245 246 247 |
# File 'lib/wrest/native/response.rb', line 245 def can_be_validated? !(last_modified.nil? and headers['etag'].nil?) end |
#code_cacheable? ⇒ Boolean
:nodoc:
124 125 126 |
# File 'lib/wrest/native/response.rb', line 124 def code_cacheable? !code.nil? && [200, 203, 300, 301, 302, 304, 307].include?(code.to_i) end |
#connection_closed? ⇒ Boolean
112 113 114 |
# File 'lib/wrest/native/response.rb', line 112 def connection_closed? self[Native::StandardHeaders::Connection].downcase == Native::StandardTokens::Close.downcase end |
#current_age ⇒ Object
Age of the response calculated according to RFC 2616 13.2.3
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/wrest/native/response.rb', line 188 def current_age current_time = Time.now.to_i # RFC 2616 13.2.3 Age Calculations. TODO: include response_delay in the calculation as defined in RFC. For this, include original Request with Response. date_value = begin Utils.datetime_to_i(DateTime.parse(headers['date'])) rescue StandardError current_time end age_value = headers['age'].to_i || 0 apparent_age = current_time - date_value [apparent_age, age_value].max end |
#deserialise(options = {}) ⇒ Object
75 76 77 78 |
# File 'lib/wrest/native/response.rb', line 75 def deserialise( = {}) @deserialised_body ||= deserialise_using(Wrest::Components::Translators.lookup(@http_response.content_type), ) end |
#deserialise_using(translator, options = {}) ⇒ Object
84 85 86 |
# File 'lib/wrest/native/response.rb', line 84 def deserialise_using(translator, = {}) translator.deserialise(@http_response, ) end |
#deserialize(options = {}) ⇒ Object
80 81 82 |
# File 'lib/wrest/native/response.rb', line 80 def deserialize( = {}) deserialise() end |
#deserialize_using(options = {}) ⇒ Object
88 89 90 |
# File 'lib/wrest/native/response.rb', line 88 def deserialize_using( = {}) deserialise_using() end |
#expired? ⇒ Boolean
Has this response expired? The expiry is calculated from the Max-Age/Expires header.
232 233 234 235 236 237 |
# File 'lib/wrest/native/response.rb', line 232 def expired? freshness = freshness_lifetime return true if freshness <= 0 freshness <= current_age end |
#expires ⇒ Object
Returns the Expires date from the response headers.
162 163 164 165 166 |
# File 'lib/wrest/native/response.rb', line 162 def expires return @expires if @expires @expires = parse_datefield(headers, 'expires') end |
#expires_not_in_its_past? ⇒ Boolean
Is the Expires of this response earlier than its Date header.
178 179 180 181 182 183 184 185 |
# File 'lib/wrest/native/response.rb', line 178 def expires_not_in_its_past? # Invalid header value for Date or Expires means the response is not cacheable if expires.nil? || response_date.nil? false else expires > response_date end end |
#expires_not_in_our_past? ⇒ Boolean
Returns whether the Expires header of this response is earlier than current time.
169 170 171 172 173 174 175 |
# File 'lib/wrest/native/response.rb', line 169 def expires_not_in_our_past? if expires.nil? false else Utils.datetime_to_i(expires) > Time.now.to_i end end |
#follow(_redirect_request_options = {}) ⇒ Object
A null object implementation - invoking this method on a response simply returns the same response unless the response is Redirection (code 3xx), in which case a get is invoked on the url stored in the response headers under the key ‘location’ and the new Response is returned.
108 109 110 |
# File 'lib/wrest/native/response.rb', line 108 def follow( = {}) self end |
#freshness_lifetime ⇒ Object
How long (in seconds) is this response expected to be fresh
217 218 219 |
# File 'lib/wrest/native/response.rb', line 217 def freshness_lifetime @freshness_lifetime ||= recalculate_freshness_lifetime end |
#hash ⇒ Object
Return the hash of a Wrest::Native::Response object.
71 72 73 |
# File 'lib/wrest/native/response.rb', line 71 def hash [code, , headers, http_version, body].hash end |
#headers ⇒ Object
Gives a hash of the response headers. The keys of the hash are case-insensitive.
93 94 95 96 97 98 99 100 101 |
# File 'lib/wrest/native/response.rb', line 93 def headers return @headers if @headers nethttp_headers_with_string_values = @http_response.to_hash.transform_values do |old_value| old_value.is_a?(Array) ? old_value.join(',') : old_value end @headers = Wrest::HashWithCaseInsensitiveAccess.new(nethttp_headers_with_string_values) end |
#initialize_copy(source) ⇒ Object
57 58 59 |
# File 'lib/wrest/native/response.rb', line 57 def initialize_copy(source) @headers = source.headers.clone end |
#last_modified ⇒ Object
239 240 241 |
# File 'lib/wrest/native/response.rb', line 239 def last_modified headers['last-modified'] end |
#max_age ⇒ Object
:nodoc:
134 135 136 137 138 139 140 |
# File 'lib/wrest/native/response.rb', line 134 def max_age return @max_age if @max_age max_age = cache_control_headers.grep(/max-age/) @max_age = (max_age.first.split('=').last.to_i unless max_age.empty?) end |
#no_cache_flag_not_set? ⇒ Boolean
142 143 144 |
# File 'lib/wrest/native/response.rb', line 142 def no_cache_flag_not_set? !cache_control_headers.include?('no-cache') end |
#no_store_flag_not_set? ⇒ Boolean
146 147 148 |
# File 'lib/wrest/native/response.rb', line 146 def no_store_flag_not_set? !cache_control_headers.include?('no-store') end |
#parse_datefield(hash, key) ⇒ Object
:nodoc: helper function. Used to parse date fields. this function is used and tested by the expires and response_date methods
252 253 254 255 256 257 258 259 260 261 |
# File 'lib/wrest/native/response.rb', line 252 def parse_datefield(hash, key) return unless hash[key] # Can't trust external input. Do not crash even if invalid dates are passed. begin DateTime.parse(hash[key].to_s) rescue ArgumentError nil end end |
#pragma_nocache_not_set? ⇒ Boolean
150 151 152 |
# File 'lib/wrest/native/response.rb', line 150 def pragma_nocache_not_set? headers['pragma'].nil? || (!headers['pragma'].include? 'no-cache') end |
#recalculate_cache_control_headers ⇒ Object
:nodoc:
210 211 212 213 214 |
# File 'lib/wrest/native/response.rb', line 210 def recalculate_cache_control_headers headers['cache-control'].split(',').collect(&:strip) rescue StandardError [] end |
#recalculate_freshness_lifetime ⇒ Object
:nodoc:
222 223 224 225 226 227 228 229 |
# File 'lib/wrest/native/response.rb', line 222 def recalculate_freshness_lifetime return max_age if max_age response_date = Utils.datetime_to_i(DateTime.parse(headers['date'])) expires_date = Utils.datetime_to_i(DateTime.parse(headers['expires'])) (expires_date - response_date) end |
#response_date ⇒ Object
Returns the Date from the response headers.
155 156 157 158 159 |
# File 'lib/wrest/native/response.rb', line 155 def response_date return @response_date if @response_date @response_date = parse_datefield(headers, 'date') end |
#vary_header_valid? ⇒ Boolean
:nodoc:
129 130 131 |
# File 'lib/wrest/native/response.rb', line 129 def vary_header_valid? headers['vary'] != '*' end |