class Gem::Request

def perform_request(request) # :nodoc:

:nodoc:
def perform_request(request) # :nodoc:
  connection = connection_for @uri
  retried = false
  bad_response = false
  begin
    @requests[connection] += 1
    verbose "#{request.method} #{Gem::Uri.redact(@uri)}"
    file_name = File.basename(@uri.path)
    # perform download progress reporter only for gems
    if request.response_body_permitted? && file_name =~ /\.gem$/
      reporter = ui.download_reporter
      response = connection.request(request) do |incomplete_response|
        if Gem::Net::HTTPOK === incomplete_response
          reporter.fetch(file_name, incomplete_response.content_length)
          downloaded = 0
          data = String.new
          incomplete_response.read_body do |segment|
            data << segment
            downloaded += segment.length
            reporter.update(downloaded)
          end
          reporter.done
          if incomplete_response.respond_to? :body=
            incomplete_response.body = data
          else
            incomplete_response.instance_variable_set(:@body, data)
          end
        end
      end
    else
      response = connection.request request
    end
    verbose "#{response.code} #{response.message}"
  rescue Gem::Net::HTTPBadResponse
    verbose "bad response"
    reset connection
    raise Gem::RemoteFetcher::FetchError.new("too many bad responses", @uri) if bad_response
    bad_response = true
    retry
  rescue Gem::Net::HTTPFatalError
    verbose "fatal error"
    raise Gem::RemoteFetcher::FetchError.new("fatal error", @uri)
  # HACK: work around EOFError bug in Gem::Net::HTTP
  # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
  # to install gems.
  rescue EOFError, Gem::Timeout::Error,
         Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE
    requests = @requests[connection]
    verbose "connection reset after #{requests} requests, retrying"
    raise Gem::RemoteFetcher::FetchError.new("too many connection resets", @uri) if retried
    reset connection
    retried = true
    retry
  end
  response
ensure
  @connection_pool.checkin connection
end