def download(url, dest, username=nil, password=nil, max_retries=DEFAULT_MAX_DOWNLOAD_RETRIES)
      @errors = []
      retry_count = error_code = 0
      success = false
      reset_wait_time_span

      @errors << 'curl is not installed' unless @found_curl

      @errors << "destination file '#{dest}' is a directory" if File.directory?(dest)
      begin
        FileUtils.mkdir_p(File.dirname(dest)) unless File.directory?(File.dirname(dest))
      rescue Exception => e
        @errors << e.message
      end

      return false unless @errors.empty?

      # format curl command and redirect stderr away.
      #
      # note: ensure we use double-quotes (") to surround arguments on command
      # line because single-quotes (') are literals in windows.
      platform = RightScale::Platform
      user_opt = username && password ? "--user \"#{username}:#{password}\"" : ""
      dest = platform.filesystem.long_path_to_short_path(dest)
      cmd = "curl --fail --silent --show-error --insecure --location --connect-timeout 300 --max-time 3600 --write-out \"%{http_code} %{size_download} %{speed_download}\" #{user_opt} --output \"#{dest}\" \"#{url}\""
      cmd = platform.shell.format_redirect_stderr(cmd)
      begin
        out = `#{cmd}`
        out = out.split
        success = $?.success? && out.size == 3
        if success
          @size = out[1].to_i
          @speed = out[2].to_i
          @last_url = url
          return true
        else
          retry_count += 1
          error_code = out[0].to_i
          yield error_code if block_given?
          sleep wait_time_span
        end
      end until success || retry_count >= max_retries
      unless success
        @errors << "#{retry_count} download attempts failed, last HTTP response code was #{error_code}"
        return false
      end
      true
    end
def download(url, dest, username=nil, password=nil, max_retries=DEFAULT_MAX_DOWNLOAD_RETRIES)
      @errors = []
      retry_count = error_code = 0
      success = false
      reset_wait_time_span

      @errors << 'curl is not installed' unless @found_curl

      @errors << "destination file '#{dest}' is a directory" if File.directory?(dest)
      begin
        FileUtils.mkdir_p(File.dirname(dest)) unless File.directory?(File.dirname(dest))
      rescue Exception => e
        @errors << e.message
      end

      return false unless @errors.empty?

      # format curl command and redirect stderr away.
      #
      # note: ensure we use double-quotes (") to surround arguments on command
      # line because single-quotes (') are literals in windows.
      platform = RightScale::Platform
      user_opt = username && password ? "--user \"#{username}:#{password}\"" : ""
      dest = platform.filesystem.long_path_to_short_path(dest)
      cmd = "curl --fail --silent --show-error --insecure --location --connect-timeout 300 --max-time 3600 --write-out \"%{http_code} %{size_download} %{speed_download}\" #{user_opt} --output \"#{dest}\" \"#{url}\""
      cmd = platform.shell.format_redirect_stderr(cmd)
      begin
        out = `#{cmd}`
        out = out.split
        success = $?.success? && out.size == 3
        if success
          @size = out[1].to_i
          @speed = out[2].to_i
          @last_url = url
          return true
        else
          retry_count += 1
          error_code = out[0].to_i
          yield error_code if block_given?
          sleep wait_time_span
        end
      end until success || retry_count >= max_retries
      unless success
        @errors << "#{retry_count} download attempts failed, last HTTP response code was #{error_code}"
        return false
      end
      true
    end
Download file synchronously and report on success, download size and download speed.
 Use successful, size and speed to query about last download.
 If last download failed, use error to retrieve error message.
 Requires 'curl' to be available on PATH.

 === Parameters
 url(String):: URL to downloaded file
 dest(String):: Path where file should be saved on disk
 username(String):: Optional HTTP basic authentication username
 password(String):: Optional HTTP basic authentication password
 max_retries(Integer):: Maximum number of retries - defaults to DEFAULT_MAX_DOWNLOAD_RETRIES

 === Block
 Call (optional) passed in block after each unsuccessful download attempt.
 Block must accept one argument corresponding to the last returned http code.

 === Return
 true:: Download was successful
 false:: Download failed