Class: BSV::Storage::Downloader
- Inherits:
-
Object
- Object
- BSV::Storage::Downloader
- Defined in:
- lib/bsv/storage/downloader.rb
Overview
Downloads UHRP-addressed content from distributed storage hosts.
Resolution: queries the ls_uhrp lookup service via a Overlay::LookupResolver, decodes each PushDrop output to extract the host URL (field) and expiry timestamp (field, varint). Expired entries are silently dropped.
Download: fetches each resolved URL in turn. Any HTTP 4xx/5xx, empty body, or network exception is treated as a failed host and the next URL is tried. This matches the TS SDK contract — no special treatment of 401/402/403.
HTTP redirects are not followed (Net::HTTP default). This is intentional in v1.
Download URLs are taken directly from the overlay; no private-IP filter is applied here. (The LookupResolver applies SSRF filtering to SLAP-discovered infrastructure hosts — content URLs are end-user data and are not subject to the same filter.)
Instance Method Summary collapse
-
#download(uhrp_url) ⇒ BSV::Storage::DownloadResult
Download the content addressed by
uhrp_url. -
#initialize(network_preset: :mainnet, lookup_resolver: nil, http_client: nil, timeout: 30) ⇒ Downloader
constructor
A new instance of Downloader.
-
#resolve(uhrp_url) ⇒ Array<String>
Resolve a UHRP URL to a list of HTTP(S) download URLs.
Constructor Details
#initialize(network_preset: :mainnet, lookup_resolver: nil, http_client: nil, timeout: 30) ⇒ Downloader
Returns a new instance of Downloader.
35 36 37 38 39 |
# File 'lib/bsv/storage/downloader.rb', line 35 def initialize(network_preset: :mainnet, lookup_resolver: nil, http_client: nil, timeout: 30) @lookup_resolver = lookup_resolver || BSV::Overlay::LookupResolver.new(network_preset: network_preset) @http_client = http_client @timeout = timeout end |
Instance Method Details
#download(uhrp_url) ⇒ BSV::Storage::DownloadResult
Download the content addressed by uhrp_url.
Validates the URL, resolves it to a list of hosts, then attempts each host in order. Verifies the SHA-256 hash of the downloaded body against the hash embedded in the UHRP URL. Returns on the first successful match.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/bsv/storage/downloader.rb', line 78 def download(uhrp_url) raise ArgumentError, 'Invalid parameter UHRP url' unless BSV::Storage::Utils.valid_url?(uhrp_url) urls = resolve(uhrp_url) raise DownloadError, 'No one currently hosts this file!' if urls.empty? expected_hash = BSV::Storage::Utils.get_hash_from_url(uhrp_url) urls.each do |url| result = attempt_download(url, expected_hash) return result if result end raise DownloadError, "Unable to download content from #{uhrp_url}" end |
#resolve(uhrp_url) ⇒ Array<String>
Resolve a UHRP URL to a list of HTTP(S) download URLs.
Queries the ls_uhrp lookup service, decodes each PushDrop output, drops expired entries, and returns the remaining URLs.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/bsv/storage/downloader.rb', line 49 def resolve(uhrp_url) question = BSV::Overlay::LookupQuestion.new( service: 'ls_uhrp', query: { 'uhrpUrl' => BSV::Storage::Utils.normalize_url(uhrp_url) } ) answer = @lookup_resolver.query(question) raise DownloadError, 'Lookup answer must be an output list' unless answer.type == 'output-list' current_time = Time.now.to_i urls = [] answer.outputs.each do |output| url = decode_output_url(output, current_time) urls << url if url end urls end |