def request uri, req = nil, &block
    retried      = false
    bad_response = false

    uri      = URI uri
    req      = request_setup req || uri
    response = nil

    connection_for uri do |connection|
      http = connection.http

      begin
        connection.requests += 1

        response = http.request req, &block

        if req.connection_close? or
           (response.http_version <= '1.0' and
            not response.connection_keep_alive?) or
           response.connection_close? then
          finish connection
        end
      rescue Net::HTTPBadResponse => e
        message = error_message connection

        finish connection

        raise Error, "too many bad responses #{message}" if
        bad_response or not can_retry? req

        bad_response = true
        retry
      rescue *RETRIED_EXCEPTIONS => e
        request_failed e, req, connection if
          retried or not can_retry? req

        reset connection

        retried = true
        retry
      rescue Errno::EINVAL, Errno::ETIMEDOUT => e # not retried on ruby 2
        request_failed e, req, connection if retried or not can_retry? req

        reset connection

        retried = true
        retry
      rescue Exception => e
        finish connection

        raise
      ensure
        connection.last_use = Time.now
      end
    end

    @http_versions["#{uri.host}:#{uri.port}"] ||= response.http_version

    response
  end
def request uri, req = nil, &block
    retried      = false
    bad_response = false

    uri      = URI uri
    req      = request_setup req || uri
    response = nil

    connection_for uri do |connection|
      http = connection.http

      begin
        connection.requests += 1

        response = http.request req, &block

        if req.connection_close? or
           (response.http_version <= '1.0' and
            not response.connection_keep_alive?) or
           response.connection_close? then
          finish connection
        end
      rescue Net::HTTPBadResponse => e
        message = error_message connection

        finish connection

        raise Error, "too many bad responses #{message}" if
        bad_response or not can_retry? req

        bad_response = true
        retry
      rescue *RETRIED_EXCEPTIONS => e
        request_failed e, req, connection if
          retried or not can_retry? req

        reset connection

        retried = true
        retry
      rescue Errno::EINVAL, Errno::ETIMEDOUT => e # not retried on ruby 2
        request_failed e, req, connection if retried or not can_retry? req

        reset connection

        retried = true
        retry
      rescue Exception => e
        finish connection

        raise
      ensure
        connection.last_use = Time.now
      end
    end

    @http_versions["#{uri.host}:#{uri.port}"] ||= response.http_version

    response
  end
Makes a request on +uri+.  If +req+ is nil a Net::HTTP::Get is performed
 against +uri+.

 If a block is passed #request behaves like Net::HTTP#request (the body of
 the response will not have been read).

 +req+ must be a Net::HTTPRequest subclass (see Net::HTTP for a list).

 If there is an error and the request is idempotent according to RFC 2616
 it will be retried automatically.