Class: MTProto::FileDownloader

Inherits:
Object
  • Object
show all
Defined in:
lib/mtproto/file_downloader.rb

Overview

Downloads a file’s bytes via upload.getFile, handling the case where the file lives on a DC other than the home client’s. For a foreign DC it opens one extra connection to that DC, transfers the home authorization there (auth.exportAuthorization on the home client + auth.importAuthorization on the new connection) and runs getFile on it. A FILE_MIGRATE_X reply is honoured the same way. DC addresses come from help.getConfig — never hardcoded, since test DC addresses and ports differ from prod and change over time.

Constant Summary collapse

CHUNK =
1024 * 1024
DC_OPTION_IPV6 =
1 << 0
DC_OPTION_CDN =
1 << 3

Instance Method Summary collapse

Constructor Details

#initialize(home, dc_options:, public_key:, test_mode: false) ⇒ FileDownloader

home: a connected, authorized Client whose receiver loop is already running. dc_options: help.getConfig dc_options (e.g. Client#init_connection! result). public_key / test_mode: used to handshake fresh connections to other DCs.



22
23
24
25
26
27
28
# File 'lib/mtproto/file_downloader.rb', line 22

def initialize(home, dc_options:, public_key:, test_mode: false)
  @home = home
  @dc_options = dc_options
  @public_key = public_key
  @test_mode = test_mode
  @subs = {}
end

Instance Method Details

#closeObject

Tear down the extra DC connections opened for downloads.



45
46
47
48
# File 'lib/mtproto/file_downloader.rb', line 45

def close
  @subs.each_value(&:disconnect!)
  @subs.clear
end

#download(location, dc_id:, type: :document) ⇒ Object

location: { id:, access_hash:, file_reference:, thumb_size: }. dc_id: the DC that stores the file. type: :photo or :document.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/mtproto/file_downloader.rb', line 32

def download(location, dc_id:, type: :document)
  client = client_for(dc_id)
  read_all(client, location, type)
rescue RpcError => e
  migrate = e.error_message.to_s[/\AFILE_MIGRATE_(\d+)\z/, 1]
  raise unless migrate

  # client_for, not connection_to: a migrate back to the home DC must reuse
  # @home — exporting authorization to your own DC answers DC_ID_INVALID.
  read_all(client_for(migrate.to_i), location, type)
end