def get_response(uri_or_s, options = {}, &block)
uri = uri_or_s.kind_of?(URI) ? uri_or_s : URI.parse(uri_or_s.to_s)
opts = {
:max_redir => @bot.config['http.max_redir'],
:yield => :final,
:cache => true,
:method => :GET
}.merge(options)
resp = nil
cached = nil
req_class = case opts[:method].to_s.downcase.intern
when :head, "net::http::head""net::http::head"
opts[:max_redir] = -1
Net::HTTP::Head
when :get, "net::http::get""net::http::get"
Net::HTTP::Get
when :post, "net::http::post""net::http::post"
opts[:cache] = false
opts[:body] or raise 'post request w/o a body?'
warning "refusing to cache POST request" if options[:cache]
Net::HTTP::Post
else
warning "unsupported method #{opts[:method]}, doing GET"
Net::HTTP::Get
end
if req_class != Net::HTTP::Get && opts[:range]
warning "can't request ranges for #{req_class}"
opts.delete(:range)
end
cache_key = "#{opts[:range]}|#{req_class}|#{uri.to_s}"
if req_class != Net::HTTP::Get && req_class != Net::HTTP::Head
if opts[:cache]
warning "can't cache #{req_class.inspect} requests, working w/o cache"
opts[:cache] = false
end
end
debug "get_response(#{uri}, #{opts.inspect})"
if opts[:cache] && cached = @cache[cache_key]
debug "got cached"
if !cached.expired?
debug "using cached"
cached.use
return handle_response(uri, cached.response, opts, &block)
end
end
headers = @headers.dup.merge(opts[:headers] || {})
headers['Range'] = opts[:range] if opts[:range]
headers['Authorization'] = opts[:auth_head] if opts[:auth_head]
cached.setup_headers(headers) if cached && (req_class == Net::HTTP::Get)
req = req_class.new(uri.request_uri, headers)
if uri.user && uri.password
req.basic_auth(uri.user, uri.password)
opts[:auth_head] = req['Authorization']
end
req.body = opts[:body] if req_class == Net::HTTP::Post
debug "prepared request: #{req.to_hash.inspect}"
begin
get_proxy(uri, opts).start do |http|
http.request(req) do |resp|
resp['x-rbot-location'] = uri.to_s
if Net::HTTPNotModified === resp
debug "not modified"
begin
cached.revalidate(resp)
rescue Exception => e
error e
end
debug "reusing cached"
resp = cached.response
elsif Net::HTTPServerError === resp || Net::HTTPClientError === resp
debug "http error, deleting cached obj" if cached
@cache.delete(cache_key)
elsif opts[:cache]
begin
return handle_response(uri, resp, opts, &block)
ensure
if cached = CachedObject.maybe_new(resp) rescue nil
debug "storing to cache"
@cache[cache_key] = cached
end
end
return ret
end
return handle_response(uri, resp, opts, &block)
end
end
rescue Exception => e
error e
raise e.message
end
end