diff --git a/Library/Homebrew/test/cask/cmd/info_spec.rb b/Library/Homebrew/test/cask/cmd/info_spec.rb index 1685b22483..ae5ad215ef 100644 --- a/Library/Homebrew/test/cask/cmd/info_spec.rb +++ b/Library/Homebrew/test/cask/cmd/info_spec.rb @@ -136,4 +136,32 @@ describe Cask::Cmd::Info, :cask do Caffeine.app (App) EOS end + + it "can run be run with a url twice" do + expect { + described_class.run("https://raw.githubusercontent.com/Homebrew/homebrew-cask" \ + "/d0b2c58652ae5eff20a7a4ac93292a08b250912b/Casks/docker.rb") + described_class.run("https://raw.githubusercontent.com/Homebrew/homebrew-cask" \ + "/d0b2c58652ae5eff20a7a4ac93292a08b250912b/Casks/docker.rb") + }.to output(<<~EOS).to_stdout + ==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/d0b2c58652ae5eff20a7a4ac93292a08b250912b/Casks/docker.rb. + docker: 2.0.0.2-ce-mac81,30215 (auto_updates) + https://www.docker.com/community-edition + Not installed + ==> Names + Docker Community Edition + Docker CE + ==> Artifacts + Docker.app (App) + ==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/d0b2c58652ae5eff20a7a4ac93292a08b250912b/Casks/docker.rb. + docker: 2.0.0.2-ce-mac81,30215 (auto_updates) + https://www.docker.com/community-edition + Not installed + ==> Names + Docker Community Edition + Docker CE + ==> Artifacts + Docker.app (App) + EOS + end end diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb index 5b0c5a66db..bcc47d4394 100644 --- a/Library/Homebrew/utils/curl.rb +++ b/Library/Homebrew/utils/curl.rb @@ -51,10 +51,20 @@ def curl_download(*args, to: nil, **options) destination = Pathname(to) destination.dirname.mkpath - continue_at = if destination.exist? && - curl_output("--location", "--range", "0-1", - "--write-out", "%{http_code}", - "--output", "/dev/null", *args, **options).stdout.to_i == 206 # Partial Content + range_stdout = curl_output("--location", "--range", "0-1", + "--dump-header", "-", + "--write-out", "%{http_code}", + "--output", "/dev/null", *args, **options).stdout + headers, _, http_status = range_stdout.partition("\r\n\r\n") + + supports_partial_download = http_status.to_i == 206 # Partial Content + if supports_partial_download && + destination.exist? && + destination.size == %r{^.*Content-Range: bytes \d+-\d+/(\d+)\r\n.*$}m.match(headers)[1].to_i + return # We've already downloaded all the bytes + end + + continue_at = if destination.exist? && supports_partial_download "-" else 0