2010-04-30 20:31:24 +02:00
|
|
|
require 'cgi'
|
|
|
|
|
2010-01-25 22:04:59 +01:00
|
|
|
module RestClient
|
|
|
|
|
2010-03-29 19:38:23 +02:00
|
|
|
module AbstractResponse
|
2010-01-25 22:04:59 +01:00
|
|
|
|
2010-02-10 21:31:59 +01:00
|
|
|
attr_reader :net_http_res, :args
|
2010-01-25 22:04:59 +01:00
|
|
|
|
|
|
|
# HTTP status code
|
|
|
|
def code
|
|
|
|
@code ||= @net_http_res.code.to_i
|
|
|
|
end
|
|
|
|
|
|
|
|
# A hash of the headers, beautified with symbols and underscores.
|
|
|
|
# e.g. "Content-type" will become :content_type.
|
|
|
|
def headers
|
2010-03-29 19:38:23 +02:00
|
|
|
@headers ||= AbstractResponse.beautify_headers(@net_http_res.to_hash)
|
2010-01-25 22:04:59 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# The raw headers.
|
|
|
|
def raw_headers
|
|
|
|
@raw_headers ||= @net_http_res.to_hash
|
|
|
|
end
|
|
|
|
|
|
|
|
# Hash of cookies extracted from response headers
|
|
|
|
def cookies
|
2010-04-30 20:31:24 +02:00
|
|
|
@cookies ||= (self.headers[:set_cookie] || {}).inject({}) do |out, cookie_content|
|
|
|
|
CGI::Cookie::parse(cookie_content).each do |key, cookie|
|
|
|
|
unless ['expires', 'path'].include? key
|
|
|
|
out[key] = cookie.value[0] || ''
|
|
|
|
end
|
2010-01-25 22:04:59 +01:00
|
|
|
end
|
|
|
|
out
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Return the default behavior corresponding to the response code:
|
2010-02-10 21:48:46 +01:00
|
|
|
# the response itself for code in 200..206, redirection for 301 and 302 in get and head cases, redirection for 303 and an exception in other cases
|
2010-05-25 18:43:18 +02:00
|
|
|
def return! request = nil, &block
|
2010-01-25 22:04:59 +01:00
|
|
|
if (200..206).include? code
|
|
|
|
self
|
2010-02-10 21:48:46 +01:00
|
|
|
elsif [301, 302].include? code
|
2010-02-10 21:31:59 +01:00
|
|
|
unless [:get, :head].include? args[:method]
|
|
|
|
raise Exceptions::EXCEPTIONS_MAP[code], self
|
|
|
|
else
|
2010-05-25 18:43:18 +02:00
|
|
|
follow_redirection(request, &block)
|
2010-02-10 21:31:59 +01:00
|
|
|
end
|
2010-02-10 21:48:46 +01:00
|
|
|
elsif code == 303
|
|
|
|
args[:method] = :get
|
|
|
|
args.delete :payload
|
2010-05-25 18:43:18 +02:00
|
|
|
follow_redirection(request, &block)
|
2010-01-25 22:04:59 +01:00
|
|
|
elsif Exceptions::EXCEPTIONS_MAP[code]
|
|
|
|
raise Exceptions::EXCEPTIONS_MAP[code], self
|
|
|
|
else
|
|
|
|
raise RequestFailed, self
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-03-19 20:30:26 +01:00
|
|
|
def to_i
|
|
|
|
code
|
|
|
|
end
|
|
|
|
|
2010-04-23 19:40:49 +02:00
|
|
|
def description
|
2010-02-10 21:31:59 +01:00
|
|
|
"#{code} #{STATUSES[code]} | #{(headers[:content_type] || '').gsub(/;.*$/, '')} #{size} bytes\n"
|
2010-01-26 19:41:53 +01:00
|
|
|
end
|
|
|
|
|
2010-02-10 21:31:59 +01:00
|
|
|
# Follow a redirection
|
2010-05-25 18:43:18 +02:00
|
|
|
def follow_redirection request = nil, &block
|
2010-02-10 21:31:59 +01:00
|
|
|
url = headers[:location]
|
|
|
|
if url !~ /^http/
|
|
|
|
url = URI.parse(args[:url]).merge(url).to_s
|
|
|
|
end
|
2010-02-10 21:48:46 +01:00
|
|
|
args[:url] = url
|
2010-05-25 18:43:18 +02:00
|
|
|
if request
|
|
|
|
args[:password] = request.password
|
|
|
|
args[:user] = request.user
|
|
|
|
args[:headers] = request.headers
|
|
|
|
end
|
|
|
|
Request.execute args, &block
|
2010-02-10 21:31:59 +01:00
|
|
|
end
|
2010-01-26 19:41:53 +01:00
|
|
|
|
2010-01-25 22:04:59 +01:00
|
|
|
def AbstractResponse.beautify_headers(headers)
|
|
|
|
headers.inject({}) do |out, (key, value)|
|
2010-05-18 20:00:09 +02:00
|
|
|
out[key.gsub(/-/, '_').downcase.to_sym] = %w{ set-cookie }.include?(key.downcase) ? value : value.first
|
2010-01-25 22:04:59 +01:00
|
|
|
out
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|