Class: Vagrant::Downloaders::HTTP
- Inherits:
-
Base
- Object
- Base
- Vagrant::Downloaders::HTTP
- Defined in:
- lib/vagrant/downloaders/http.rb
Overview
Downloads a file from an HTTP URL to a temporary file. This downloader reports its progress to stdout while downloading.
Class Method Summary (collapse)
Instance Method Summary (collapse)
Methods inherited from Base
Constructor Details
This class inherits a constructor from Vagrant::Downloaders::Base
Class Method Details
+ (Boolean) match?(uri)
11 12 13 14 15 |
# File 'lib/vagrant/downloaders/http.rb', line 11 def self.match?(uri) # URI.parse barfs on '<drive letter>:\\files \on\ windows' extracted = URI.extract(uri, ['http', 'https']).first extracted && extracted.include?(uri) end |
Instance Method Details
- (Object) download!(source_url, destination_file)
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/vagrant/downloaders/http.rb', line 17 def download!(source_url, destination_file) uri = URI.parse(source_url) proxy_uri = resolve_proxy(uri) http = Net::HTTP.new(uri.host, uri.port, proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password) http.read_timeout = nil # Disable the read timeout, just let it try to download if uri.scheme == "https" http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE end http.start do |h| @ui.info I18n.t("vagrant.downloaders.http.download", :url => source_url) headers = nil if uri.user && uri.password headers = {'Authorization' => 'Basic ' + Base64.encode64(uri.user + ':' + uri.password)} end h.request_get(uri.request_uri, headers) do |response| if response.is_a?(Net::HTTPRedirection) # Follow the HTTP redirect. # TODO: Error on some redirect limit download!(response["Location"], destination_file) return elsif !response.is_a?(Net::HTTPOK) raise Errors::DownloaderHTTPStatusError, :status => response.code end total = response.content_length progress = 0 segment_count = 0 response.read_body do |segment| # Report the progress out progress += segment.length segment_count += 1 # Progress reporting is limited to every 25 segments just so # we're not constantly updating if segment_count % 25 == 0 @ui.clear_line @ui.report_progress(progress, total) segment_count = 0 end # Store the segment destination_file.write(segment) end # Clear the line one last time so that the progress meter disappears @ui.clear_line end end rescue Errno::ECONNRESET raise Errors::DownloaderHTTPConnectReset rescue Errno::ETIMEDOUT raise Errors::DownloaderHTTPConnectTimeout rescue SocketError raise Errors::DownloaderHTTPSocketError end |