Class: NVX::SDS::HttpDownload

Inherits:
Object
  • Object
show all
Defined in:
lib/nvx/sds/httpdownload.rb

Overview

Overview

Retrieves a file from the remote server and saves it to the local file system.

Constant Summary collapse

USERAGENT =
"Nirvanix Ruby SDK"
Newline =
"\r\n"
BLOCKSIZE =
1024*1024 * 4

Class Method Summary collapse

Class Method Details

.DownloadChunk(node, path, offset, length, is_secure) ⇒ Object

Overview

Downloads a single chunk from a remote server.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/nvx/sds/httpdownload.rb', line 112

def HttpDownload.DownloadChunk(node, path, offset, length, is_secure)

  port = is_secure ? 443 : 80
      
  # Create the first http(s) object.
  if @h.nil?
    @h = Net::HTTP.new(node, port)
  end
  
  # if you are just testing and do not have a SSL certificate setup properly you can
  # disable warnings with the below line.  Just uncomment to ignore SSL session warnings.
  @h.verify_mode = OpenSSL::SSL::VERIFY_NONE if is_secure

  # put the SSL in the correct mode based on the apicommand
  @h.use_ssl = is_secure
  headers = {
          'Range' => "bytes=#{offset}-#{length + offset}",
          'User-Agent' => USERAGENT,
          'Content-Length' => "4"
  }

  # do the command and return the response.
  return @h.post(path, "\r\n\r\n", headers)
end

.DownloadFile(path, local_path, account_login, callback = nil) ⇒ Object

Overview

Retrieves a file from the remote server and saves it to the local file system The path can be relative or absolute, if you are a master account you can pass the absolute path to retrieve a child accounts file.

Parameters

path

A path on the Nirvanix file system this can be absolute or regular

local_path

The local path where the file will be saved

account_login

the account information from the Session.new that was created with valid login information.

callback

The callback is an object with two methods for recieving updates while the download is in progress.

def percent(percent, bytes_downloaded)
   print "Percent: #{percent} - Bytes: #{bytes_downloaded}\r\n"
end

Returns a the percentage complete along with the number of bytes downloaded so far.

def warning(message)
  print "Warning: #{message}\r\n"
end

Returns a warning message when there is an internal connectivity issue with the download.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/nvx/sds/httpdownload.rb', line 59

def HttpDownload.DownloadFile(path, local_path, , callback = nil)
            # Get the download node this will get the proper node for a path.
  doc = Transport.execute_command_post(APICommand.GetOptimalURLs, [APIParam.new("filePath", path), APIParam.new("expiration", "#{60*60*24}")], )
  url = URI.parse(doc.root.elements["//Response/Download/DownloadURL"].get_text.value)

  file = open(local_path, "wb")
  offset = 0
  percent_downloaded = 0
  total_length = 1
  while offset < total_length
    begin
      # download a portion of the file up to blocksize long.
      response = DownloadChunk(url.host, url.path, offset, BLOCKSIZE, false)
      # if this is the first request get the total file length based on the Content-Range.
      if offset == 0
        range = response['Content-Range']
        total_length = range[range.index("/") + 1, range.length].to_i
      end
      # reset retry_count since this was a successful download.
      retry_count = 0
    rescue SocketError, Timeout::Error, Errno::ETIMEDOUT, Errno::EPIPE, IOError, RetryException
      retry_count += 1
      if retry_count > 10
        raise RetryException.new("Connection failure at offset: #{offset}")
      end

      # If the callback object is available pass a warning specifying the retry count.
      if !callback.nil? 
        callback.warning("Connection failure at offset: #{offset}  Retry count: #{retry_count}") 
      end

      redo
    end
    # write the body to the open file.
    file.write(response.body)
    # increment the offset by how much was downloaded.
    offset += response.body.length

    # get percentage complete
    new_percentage = (offset * 100) / total_length
    # if the percentage has changed update the callback.
    if new_percentage > percent_downloaded
      percent_downloaded = new_percentage
      if !callback.nil? 
        callback.percent(percent_downloaded, offset) 
      end
    end
  end
  file.close
end