def fetch(url, body=nil, headers=nil, redirect_limit=REDIRECT_LIMIT)
unparsed_url = url.dup
url = URI::parse(url)
if url.nil?
raise FetchingError, "Invalid URL: #{unparsed_url}"
end
headers ||= {}
headers['User-agent'] ||= USER_AGENT
begin
conn = make_connection(url)
response = nil
response = conn.start {
if supports_ssl?(conn) and conn.use_ssl?
conn.post_connection_check(url.host)
end
if body.nil?
conn.request_get(url.request_uri, headers)
else
headers["Content-type"] ||= "application/x-www-form-urlencoded"
conn.request_post(url.request_uri, body, headers)
end
}
rescue RuntimeError => why
raise why
rescue OpenSSL::SSL::SSLError => why
raise SSLFetchingError, "Error connecting to SSL URL #{url}: #{why}"
rescue FetchingError => why
raise why
rescue Exception => why
raise FetchingError, "Error fetching #{url}: #{why}"
end
case response
when Net::HTTPRedirection
if redirect_limit <= 0
raise HTTPRedirectLimitReached.new(
"Too many redirects, not fetching #{response['location']}")
end
begin
return fetch(response['location'], body, headers, redirect_limit - 1)
rescue HTTPRedirectLimitReached => e
raise e
rescue FetchingError => why
raise FetchingError, "Error encountered in redirect from #{url}: #{why}"
end
else
return HTTPResponse._from_net_response(response, unparsed_url)
end
end