def request(uri, request_class, last_modified = nil)
request = request_class.new uri.request_uri
unless uri.nil? || uri.user.nil? || uri.user.empty? then
request.basic_auth uri.user, uri.password
end
ua = "RubyGems/#{Gem::RubyGemsVersion} #{Gem::Platform.local}"
ua << " Ruby/#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}"
ua << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
ua << ")"
request.add_field 'User-Agent', ua
request.add_field 'Connection', 'keep-alive'
request.add_field 'Keep-Alive', '30'
if last_modified then
last_modified = last_modified.utc
request.add_field 'If-Modified-Since', last_modified.rfc2822
end
connection = connection_for uri
retried = false
bad_response = false
begin
@requests[connection.object_id] += 1
response = connection.request request
say "#{request.method} #{response.code} #{response.message}: #{uri}" if
Gem.configuration.really_verbose
rescue Net::HTTPBadResponse
reset connection
raise FetchError.new('too many bad responses', uri) if bad_response
bad_response = true
retry
rescue EOFError, Errno::ECONNABORTED, Errno::ECONNRESET
requests = @requests[connection.object_id]
say "connection reset after #{requests} requests, retrying" if
Gem.configuration.really_verbose
raise FetchError.new('too many connection resets', uri) if retried
reset connection
retried = true
retry
end
response
end