Skip to content

Commit

Permalink
core: retry download without continue if byte range not supported
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed Oct 23, 2014
1 parent 2856df7 commit 46b3ea6
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ BUG FIXES:
- core: Don't share `/vagrant` if any "." folder is shared. [GH-4675]
- core: Fix SSH private key permissions more aggressively. [GH-4670]
- core: Custom Vagrant Cloud server URL now respected in more cases.
- core: On downloads, don't continue downloads if the remote server
doesn't support byte ranges. [GH-4479]
- commands/box: `--cert` flag works properly. [GH-4691]
- command/docker-logs: Won't crash if container is removed. [GH-3990]
- command/docker-run: Synced folders will be attached properly. [GH-3873]
Expand Down
34 changes: 28 additions & 6 deletions lib/vagrant/util/downloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,15 @@ def initialize(source, destination, options=nil)
# If this method returns without an exception, the download
# succeeded. An exception will be raised if the download failed.
def download!
options, subprocess_options = self.options
options += ["--output", @destination]
options << @source

# This variable can contain the proc that'll be sent to
# the subprocess execute.
data_proc = nil

extra_subprocess_opts = {}
if @ui
# If we're outputting progress, then setup the subprocess to
# tell us output so we can parse it out.
subprocess_options[:notify] = :stderr
extra_subprocess_opts[:notify] = :stderr

progress_data = ""
progress_regexp = /(\r(.+?))\r/
Expand Down Expand Up @@ -121,8 +118,31 @@ def download!
@logger.info(" -- Source: #{@source}")
@logger.info(" -- Destination: #{@destination}")

retried = false
begin
# Get the command line args and the subprocess opts based
# on our downloader settings.
options, subprocess_options = self.options
options += ["--output", @destination]
options << @source

# Merge in any extra options we set
subprocess_options.merge!(extra_subprocess_opts)

# Go!
execute_curl(options, subprocess_options, &data_proc)
rescue Errors::DownloaderError => e
# If we already retried, raise it.
raise if retried

# If its any error other than 33, it is an error.
raise if e.extra_data[:exit_code].to_i != 33

# Exit code 33 means that the server doesn't support ranges.
# In this case, try again without resume.
@continue = false
retried = true
retry
ensure
# If we're outputting to the UI, clear the output to
# avoid lingering progress meters.
Expand Down Expand Up @@ -177,7 +197,9 @@ def execute_curl(options, subprocess_options, &data_proc)
@logger.warn("Downloader exit code: #{result.exit_code}")
parts = result.stderr.split(/\n*curl:\s+\(\d+\)\s*/, 2)
parts[1] ||= ""
raise Errors::DownloaderError, message: parts[1].chomp
raise Errors::DownloaderError,
code: result.exit_code,
message: parts[1].chomp
end

result
Expand Down

0 comments on commit 46b3ea6

Please sign in to comment.