Class: CurlDownloadStrategy
- Inherits:
-
AbstractFileDownloadStrategy
- Object
- AbstractDownloadStrategy
- AbstractFileDownloadStrategy
- CurlDownloadStrategy
- Includes:
- Utils::Curl
- Defined in:
- download_strategy.rb
Overview
Strategy for downloading files using curl
.
Direct Known Subclasses
CurlApacheMirrorDownloadStrategy, CurlGitHubPackagesDownloadStrategy, CurlPostDownloadStrategy, Homebrew::API::DownloadStrategy, HomebrewCurlDownloadStrategy, NoUnzipCurlDownloadStrategy
Constant Summary collapse
- URLMetadata =
This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.
url, basename, time, file_size, is_redirection
T.type_alias { [String, String, T.nilable(Time), T.nilable(Integer), T::Boolean] }
Instance Attribute Summary collapse
- #mirrors ⇒ Array<String> readonly private
Attributes inherited from AbstractDownloadStrategy
Instance Method Summary collapse
- #clear_cache ⇒ void private
-
#fetch(timeout: nil) ⇒ void
Download and cache the file at AbstractFileDownloadStrategy#cached_location.
- #initialize(url, name, version, **meta) ⇒ void constructor private
- #resolved_time_file_size(timeout: nil) ⇒ Array<([Time, nil], Integer)> private
Methods included from Utils::Curl
clear_path_cache, curl, curl_args, curl_check_http_content, curl_download, curl_executable, curl_headers, curl_http_content_headers_and_checksum, curl_output, curl_path, curl_response_follow_redirections, curl_response_last_location, curl_supports_fail_with_body?, curl_supports_tls13?, curl_version, curl_with_workarounds, http_status_ok?, parse_curl_output, url_protected_by_cloudflare?, url_protected_by_incapsula?
Methods included from SystemCommand::Mixin
#system_command, #system_command!
Methods inherited from AbstractFileDownloadStrategy
#basename, #cached_location, #symlink_location, #temporary_path
Methods inherited from AbstractDownloadStrategy
#basename, #cached_location, #quiet!, #quiet?, #source_modified_time, #stage
Methods included from Context
current, current=, #debug?, #quiet?, #verbose?, #with_context
Constructor Details
#initialize(url, name, version, **meta) ⇒ void
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'download_strategy.rb', line 437 def initialize(url, name, version, **) @try_partial = T.let(true, T::Boolean) @mirrors = T.let(.fetch(:mirrors, []), T::Array[String]) # Merge `:header` with `:headers`. if (header = .delete(:header)) [:headers] ||= [] [:headers] << header end super end |
Instance Attribute Details
#mirrors ⇒ Array<String> (readonly)
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
434 435 436 |
# File 'download_strategy.rb', line 434 def mirrors @mirrors end |
Instance Method Details
#clear_cache ⇒ void
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
This method returns an undefined value.
523 524 525 526 |
# File 'download_strategy.rb', line 523 def clear_cache super rm_rf(temporary_path) end |
#fetch(timeout: nil) ⇒ void
This method returns an undefined value.
Download and cache the file at AbstractFileDownloadStrategy#cached_location.
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'download_strategy.rb', line 454 def fetch(timeout: nil) end_time = Time.now + timeout if timeout download_lock = DownloadLock.new(temporary_path) begin download_lock.lock urls = [url, *mirrors] begin url = T.must(urls.shift) if (domain = Homebrew::EnvConfig.artifact_domain) url = url.sub(%r{^https?://#{GitHubPackages::URL_DOMAIN}/}o, "#{domain.chomp("/")}/") urls = [] if Homebrew::EnvConfig.artifact_domain_no_fallback? end ohai "Downloading #{url}" cached_location_valid = cached_location.exist? v = version cached_location_valid = false if v.is_a?(Cask::DSL::Version) && v.latest? resolved_url, _, last_modified, file_size, is_redirection = begin resolve_url_basename_time_file_size(url, timeout: Utils::Timer.remaining!(end_time)) rescue ErrorDuringExecution raise unless cached_location_valid end # Authorization is no longer valid after redirects [:headers]&.delete_if { |header| header.start_with?("Authorization") } if is_redirection # The cached location is no longer fresh if either: # - Last-Modified value is newer than the file's timestamp # - Content-Length value is different than the file's size cached_location_valid = if cached_location_valid newer_last_modified = last_modified && last_modified > cached_location.mtime different_file_size = file_size&.nonzero? && file_size != cached_location.size !(newer_last_modified || different_file_size) end if cached_location_valid puts "Already downloaded: #{cached_location}" else begin _fetch(url:, resolved_url: T.must(resolved_url), timeout: Utils::Timer.remaining!(end_time)) rescue ErrorDuringExecution raise CurlDownloadStrategyError, url end cached_location.dirname.mkpath temporary_path.rename(cached_location.to_s) end symlink_location.dirname.mkpath FileUtils.ln_s cached_location.relative_path_from(symlink_location.dirname), symlink_location, force: true rescue CurlDownloadStrategyError raise if urls.empty? puts "Trying a mirror..." retry rescue Timeout::Error => e raise Timeout::Error, "Timed out downloading #{self.url}: #{e}" end ensure download_lock.unlock(unlink: true) end end |
#resolved_time_file_size(timeout: nil) ⇒ Array<([Time, nil], Integer)>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
529 530 531 532 |
# File 'download_strategy.rb', line 529 def resolved_time_file_size(timeout: nil) _, _, time, file_size = resolve_url_basename_time_file_size(url, timeout:) [time, T.must(file_size)] end |