def http_get(path, keep_alive = true)
      uri = safe_parse_http_uri(path)
      history = []
      loop do
        Log.debug("http_get(#{uri})")

        # keep history of live connections for more efficient redirection.
        host = uri.host
        connection = Rightscale::HttpConnection.new(:logger => Log, :exception => QueryFailed)

        # prepare request. ensure path not empty due to Net::HTTP limitation.
        #
        # note that the default for Net::HTTP is to close the connection after
        # each request (contrary to expected conventions). we must be explicit
        # about keep-alive if we want that behavior.
        request = Net::HTTP::Get.new(uri.path)
        request['Connection'] = keep_alive ? 'keep-alive' : 'close'

        # get.
        response = connection.request(:protocol => uri.scheme, :server => uri.host, :port => uri.port, :request => request)
        return response.body if response.kind_of?(Net::HTTPSuccess)
        if response.kind_of?(Net::HTTPServerError) || response.kind_of?(Net::HTTPNotFound)
          Log.debug("Request failed but can retry; #{response.class.name}")
          return nil
        elsif response.kind_of?(Net::HTTPRedirection)
          # keep history of redirects.
          location = response['Location']
          uri = safe_parse_http_uri(location)
        else
          # not retryable.
          #
          # note that the EC2 metadata server is known to give malformed
          # responses on rare occasions, but the right_http_connection will
          # consider these to be 'bananas' and retry automatically (up to a
          # pre-defined limit).
          Log.error("HTTP request failed: #{response.class.name}")
          raise QueryFailed, "HTTP request failed: #{response.class.name}"
        end
      end
    end
def http_get(path, keep_alive = true)
      uri = safe_parse_http_uri(path)
      history = []
      loop do
        Log.debug("http_get(#{uri})")

        # keep history of live connections for more efficient redirection.
        host = uri.host
        connection = Rightscale::HttpConnection.new(:logger => Log, :exception => QueryFailed)

        # prepare request. ensure path not empty due to Net::HTTP limitation.
        #
        # note that the default for Net::HTTP is to close the connection after
        # each request (contrary to expected conventions). we must be explicit
        # about keep-alive if we want that behavior.
        request = Net::HTTP::Get.new(uri.path)
        request['Connection'] = keep_alive ? 'keep-alive' : 'close'

        # get.
        response = connection.request(:protocol => uri.scheme, :server => uri.host, :port => uri.port, :request => request)
        return response.body if response.kind_of?(Net::HTTPSuccess)
        if response.kind_of?(Net::HTTPServerError) || response.kind_of?(Net::HTTPNotFound)
          Log.debug("Request failed but can retry; #{response.class.name}")
          return nil
        elsif response.kind_of?(Net::HTTPRedirection)
          # keep history of redirects.
          location = response['Location']
          uri = safe_parse_http_uri(location)
        else
          # not retryable.
          #
          # note that the EC2 metadata server is known to give malformed
          # responses on rare occasions, but the right_http_connection will
          # consider these to be 'bananas' and retry automatically (up to a
          # pre-defined limit).
          Log.error("HTTP request failed: #{response.class.name}")
          raise QueryFailed, "HTTP request failed: #{response.class.name}"
        end
      end
    end
Performs an HTTP get request with built-in retries and redirection based
 on HTTP responses.

 === Parameters
 attempts(int):: number of attempts

 === Return
 result(String):: body of response or nil