def open_uri_or_path(uri, last_modified = nil, head = false, depth = 0)
raise "block is dead" if block_given?
uri = URI.parse uri unless URI::Generic === uri
unless ['http', 'https', 'file'].include?(uri.scheme)
raise ArgumentError, 'uri scheme is invalid'
end
if uri.scheme == 'file'
path = uri.path
if path[0].chr == '/' && path[1].chr =~ /[a-zA-Z]/ && path[2].chr == ':'
path = path[1..-1]
end
return Gem.read_binary(path)
end
fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
response = request uri, fetch_type, last_modified
case response
when Net::HTTPOK, Net::HTTPNotModified then
head ? response : response.body
when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
Net::HTTPTemporaryRedirect then
raise FetchError.new('too many redirects', uri) if depth > 10
open_uri_or_path(response['Location'], last_modified, head, depth + 1)
else
raise FetchError.new("bad response #{response.message} #{response.code}", uri)
end
end