Class: Resourceful::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/resourceful/response.rb

Constant Summary collapse

REDIRECT_RESPONSE_CODES =
[301,302,303,307]
NORMALLY_CACHEABLE_RESPONSE_CODES =
[200, 203, 300, 301, 410]
CODE_NAMES =
{
  100 => "Continue".freeze,
  101 => "Switching Protocols".freeze,

  200 => "OK".freeze,
  201 => "Created".freeze,
  202 => "Accepted".freeze,
  203 => "Non-Authoritative Information".freeze,
  204 => "No Content".freeze,
  205 => "Reset Content".freeze,
  206 => "Partial Content".freeze,

  300 => "Multiple Choices".freeze,
  301 => "Moved Permanently".freeze,
  302 => "Found".freeze,
  303 => "See Other".freeze,
  304 => "Not Modified".freeze,
  305 => "Use Proxy".freeze,
  307 => "Temporary Redirect".freeze,

  400 => "Bad Request".freeze,
  401 => "Unauthorized".freeze,
  402 => "Payment Required".freeze,
  403 => "Forbidden".freeze,
  404 => "Not Found".freeze,
  405 => "Method Not Allowed".freeze,
  406 => "Not Acceptable".freeze,
  407 => "Proxy Authentication Required".freeze,
  408 => "Request Timeout".freeze,
  409 => "Conflict".freeze,
  410 => "Gone".freeze,
  411 => "Length Required".freeze,
  412 => "Precondition Failed".freeze,
  413 => "Request Entity Too Large".freeze,
  414 => "Request-URI Too Long".freeze,
  415 => "Unsupported Media Type".freeze,
  416 => "Requested Range Not Satisfiable".freeze,
  417 => "Expectation Failed".freeze,

  500 => "Internal Server Error".freeze,
  501 => "Not Implemented".freeze,
  502 => "Bad Gateway".freeze,
  503 => "Service Unavailable".freeze,
  504 => "Gateway Timeout".freeze,
  505 => "HTTP Version Not Supported".freeze,
}.freeze
CODES =
CODE_NAMES.keys

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, code, header, body) ⇒ Response

Returns a new instance of Response.



17
18
19
20
# File 'lib/resourceful/response.rb', line 17

def initialize(uri, code, header, body)
  @uri, @code, @header, @body = uri, code, header, body
  @response_time = Time.now
end

Instance Attribute Details

#authoritativeObject Also known as: authoritative?

Returns the value of attribute authoritative.



14
15
16
# File 'lib/resourceful/response.rb', line 14

def authoritative
  @authoritative
end

#bodyObject (readonly)

Returns the value of attribute body.

Raises:

  • (NotImplementedError)


11
12
13
# File 'lib/resourceful/response.rb', line 11

def body
  @body
end

#codeObject (readonly)

Returns the value of attribute code.



11
12
13
# File 'lib/resourceful/response.rb', line 11

def code
  @code
end

#headerObject (readonly) Also known as: headers

Returns the value of attribute header.



11
12
13
# File 'lib/resourceful/response.rb', line 11

def header
  @header
end

#request_timeObject

Returns the value of attribute request_time.



14
15
16
# File 'lib/resourceful/response.rb', line 14

def request_time
  @request_time
end

#response_timeObject (readonly)

Returns the value of attribute response_time.



11
12
13
# File 'lib/resourceful/response.rb', line 11

def response_time
  @response_time
end

#uriObject (readonly)

Returns the value of attribute uri.



11
12
13
# File 'lib/resourceful/response.rb', line 11

def uri
  @uri
end

Instance Method Details

#cacheable?Boolean

Is this response cachable?

Returns:

  • (Boolean)

    true|false



49
50
51
52
53
54
55
56
57
58
# File 'lib/resourceful/response.rb', line 49

def cacheable?
  @cacheable ||= begin
    @cacheable = true  if NORMALLY_CACHEABLE_RESPONSE_CODES.include?(code.to_i)
    @cacheable = false if header.vary && header.vary.include?('*')
    @cacheable = false if header.cache_control && header.cache_control.include?('no-cache')
    @cacheable = true  if header.cache_control && header.cache_control.include?('public')
    @cacheable = true  if header.cache_control && header.cache_control.include?('private')
    @cacheable || false
  end
end

#client_error?Boolean

Is the response the result of a client error? True for 4xx series response codes

Returns:

  • (Boolean)

    true|false



199
200
201
# File 'lib/resourceful/response.rb', line 199

def client_error?
  @code.in? 400..499
end

#current_ageObject

Algorithm taken from RCF2616#13.2.3



74
75
76
77
78
79
80
81
82
# File 'lib/resourceful/response.rb', line 74

def current_age
  age_value   = header.age.to_i
  date_value  = Time.httpdate(header.date)
  now         = Time.now

  apparent_age = [0, response_time - date_value].max
  corrected_received_age = [apparent_age, age_value].max
  current_age = corrected_received_age + (response_time - request_time) + (now - response_time)
end

#error?Boolean

Is the response the result of any kind of error? True for 4xx and 5xx series response codes

Returns:

  • (Boolean)

    true|false



215
216
217
# File 'lib/resourceful/response.rb', line 215

def error?
  server_error? || client_error?
end

#expired?Boolean

Is this a cached response that has expired?

Returns:

  • (Boolean)

    true|false



25
26
27
28
29
30
31
32
33
# File 'lib/resourceful/response.rb', line 25

def expired?
  if header.cache_control and m_age_str = header.cache_control.find{|cc| /^max-age=/ === cc}
    return current_age > m_age_str[/\d+/].to_i
  elsif header.expires
    return Time.httpdate(header.expires) < Time.now
  end

  false
end

#informational?Boolean

Is the response informational? True for 1xx series response codes

Returns:

  • (Boolean)

    true|false



166
167
168
# File 'lib/resourceful/response.rb', line 166

def informational?
  @code.in? 100..199
end

#must_be_revalidated?Boolean

Does this response force revalidation?

Returns:

  • (Boolean)


61
62
63
# File 'lib/resourceful/response.rb', line 61

def must_be_revalidated?
  header.cache_control && header.cache_control.include?('must-revalidate')
end

#redirect?Boolean

Is the response a actual redirect? True for 301, 302, 303, 307 response codes

Returns:

  • (Boolean)

    true|false



191
192
193
# File 'lib/resourceful/response.rb', line 191

def redirect?
  @code.in? REDIRECT_RESPONSE_CODES
end

#redirection?Boolean

Is the response a redirect? True for 3xx series response codes

Returns:

  • (Boolean)

    true|false



183
184
185
# File 'lib/resourceful/response.rb', line 183

def redirection?
  @code.in? 300..399
end

#revalidate!(not_modified_response) ⇒ Object

Update our headers from a later 304 response



66
67
68
69
70
71
# File 'lib/resourceful/response.rb', line 66

def revalidate!(not_modified_response)
  header.merge!(not_modified_response.header)
  @request_time  = not_modified_response.request_time
  @response_time = not_modified_response.response_time
  @authoritative = true
end

#server_error?Boolean

Is the response the result of a server error? True for 5xx series response codes

Returns:

  • (Boolean)

    true|false



207
208
209
# File 'lib/resourceful/response.rb', line 207

def server_error?
  @code.in? 500..599
end

#stale?Boolean

Is this a cached response that is stale?

Returns:

  • (Boolean)

    true|false



38
39
40
41
42
43
44
# File 'lib/resourceful/response.rb', line 38

def stale?
  return true if expired?
  return false unless header.has_field?(Header::CACHE_CONTROL)
  return true if header.cache_control.any?{|cc| /must-revalidate|no-cache/ === cc}

  false
end

#successful?Boolean Also known as: success?

Is the response code sucessful? True for only 2xx series response codes.

Returns:

  • (Boolean)

    true|false



174
175
176
# File 'lib/resourceful/response.rb', line 174

def successful?
  @code.in? 200..299
end