Properly download boxes from HTTPS sources. [closes GH-84]

This commit is contained in:
Mitchell Hashimoto 2010-05-29 10:54:27 -07:00
parent ced200e256
commit ad96f0090a
4 changed files with 50 additions and 26 deletions

View File

@ -2,7 +2,7 @@ libdir = File.join(File.dirname(__FILE__), "vagrant")
PROJECT_ROOT = File.join(libdir, '..', "..") unless defined?(PROJECT_ROOT)
# First, load the various libs which Vagrant requires
%w{tempfile open-uri json pathname logger uri net/http virtualbox net/ssh archive/tar/minitar
%w{tempfile json pathname logger virtualbox net/ssh archive/tar/minitar
net/scp fileutils mario}.each do |lib|
require lib
end

View File

@ -1,3 +1,8 @@
require 'net/http'
require 'net/https'
require 'open-uri'
require 'uri'
module Vagrant
module Downloaders
# Downloads a file from an HTTP URL to a temporary file. This
@ -11,25 +16,34 @@ module Vagrant
end
def download!(source_url, destination_file)
Net::HTTP.get_response(URI.parse(source_url)) do |response|
total = response.content_length
progress = 0
segment_count = 0
uri = URI.parse(source_url)
http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == "https"
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
response.read_body do |segment|
# Report the progress out
progress += segment.length
segment_count += 1
http.start do |h|
h.request_get(uri.request_uri) do |response|
total = response.content_length
progress = 0
segment_count = 0
# Progress reporting is limited to every 25 segments just so
# we're not constantly updating
if segment_count % 25 == 0
env.logger.report_progress(progress, total)
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
env.logger.report_progress(progress, total)
segment_count = 0
end
# Store the segment
destination_file.write(segment)
end
# Store the segment
destination_file.write(segment)
end
end

View File

@ -5,28 +5,38 @@ class HttpDownloaderTest < Test::Unit::TestCase
@downloader, @tempfile = mock_downloader(Vagrant::Downloaders::HTTP)
@downloader.stubs(:report_progress)
@downloader.stubs(:complete_progress)
@uri = "foo.box"
@uri = "http://google.com/"
end
context "downloading" do
setup do
@parsed_uri = mock("parsed")
URI.stubs(:parse).with(@uri).returns(@parsed_uri)
@parsed_uri = URI.parse(@uri)
@http = Net::HTTP.new(@parsed_uri.host, @parsed_uri.port)
Net::HTTP.stubs(:new).returns(@http)
@http.stubs(:start)
end
should "parse the URI and use that parsed URI for Net::HTTP" do
URI.expects(:parse).with(@uri).returns(@parsed_uri).once
Net::HTTP.expects(:get_response).with(@parsed_uri).once
should "create a proper net/http object" do
Net::HTTP.expects(:new).with(@parsed_uri.host, @parsed_uri.port).once.returns(@http)
@http.expects(:start)
@downloader.download!(@uri, @tempfile)
end
should "enable SSL if scheme is https" do
@uri = "https://google.com/"
@http.expects(:use_ssl=).with(true).once
@downloader.download!(@uri, @tempfile)
end
should "read the body of the response and place each segment into the file" do
h = mock("http")
response = mock("response")
response.stubs(:content_length)
segment = mock("segment")
segment.stubs(:length).returns(7)
Net::HTTP.stubs(:get_response).yields(response)
@http.stubs(:start).yields(h)
h.expects(:request_get).with(@parsed_uri.request_uri).once.yields(response)
response.expects(:read_body).once.yields(segment)
@tempfile.expects(:write).with(segment).once
@ -43,7 +53,7 @@ class HttpDownloaderTest < Test::Unit::TestCase
should "return false if there are no extract results" do
URI.expects(:extract).returns([])
assert !Vagrant::Downloaders::HTTP.match?('foo')
end
end
end
context "reporting progress" do

View File

@ -9,7 +9,7 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
s.authors = ["Mitchell Hashimoto", "John Bender"]
s.date = %q{2010-05-28}
s.date = %q{2010-05-29}
s.default_executable = %q{vagrant}
s.description = %q{Vagrant is a tool for building and distributing virtualized development environments.}
s.email = ["mitchell.hashimoto@gmail.com", "john.m.bender@gmail.com"]