Skip to content
This repository was archived by the owner on Apr 14, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions lib/bundler/fetcher/downloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ def initialize(connection, redirect_limit)
@redirect_limit = redirect_limit
end

def fetch(uri, options = {}, counter = 0)
def fetch(uri, headers = {}, counter = 0)
raise HTTPError, "Too many redirects" if counter >= redirect_limit

response = request(uri, options)
response = request(uri, headers)
Bundler.ui.debug("HTTP #{response.code} #{response.message} #{uri}")

case response
Expand All @@ -26,7 +26,12 @@ def fetch(uri, options = {}, counter = 0)
new_uri.user = uri.user
new_uri.password = uri.password
end
fetch(new_uri, options, counter + 1)
fetch(new_uri, headers, counter + 1)
when Net::HTTPRequestedRangeNotSatisfiable
new_headers = headers.dup
new_headers.delete("Range")
new_headers["Accept-Encoding"] = "gzip"
fetch(uri, new_headers)
when Net::HTTPRequestEntityTooLarge
raise FallbackError, response.body
when Net::HTTPUnauthorized
Expand All @@ -38,11 +43,11 @@ def fetch(uri, options = {}, counter = 0)
end
end

def request(uri, options)
def request(uri, headers)
validate_uri_scheme!(uri)

Bundler.ui.debug "HTTP GET #{uri}"
req = Net::HTTP::Get.new uri.request_uri, options
req = Net::HTTP::Get.new uri.request_uri, headers
if uri.user
user = CGI.unescape(uri.user)
password = uri.password ? CGI.unescape(uri.password) : nil
Expand Down
31 changes: 31 additions & 0 deletions spec/install/gems/compact_index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,37 @@ def start
expect(the_bundle).to include_gems "rack 1.0.0"
end

it "performs full update of compact index info cache if range is not satisfiable" do
gemfile <<-G
source "#{source_uri}"
gem 'rack', '0.9.1'
G

rake_info_path = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index",
"localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "info", "rack")

bundle! :install, :artifice => "compact_index"

expected_rack_info_content = File.read(rake_info_path)

# Modify the cache files. We expect them to be reset to the normal ones when we re-run :install
File.open(rake_info_path, "w") {|f| f << (expected_rack_info_content + "this is different") }

# Update the Gemfile so the next install does its normal things
gemfile <<-G
source "#{source_uri}"
gem 'rack', '1.0.0'
G

# The cache files now being longer means the requested range is going to be not satisfiable
# Bundler must end up requesting the whole file to fix things up.
bundle! :install, :artifice => "compact_index_range_not_satisfiable"

resulting_rack_info_content = File.read(rake_info_path)

expect(resulting_rack_info_content).to eq(expected_rack_info_content)
end

it "fails gracefully when the source URI has an invalid scheme" do
install_gemfile <<-G
source "htps://rubygems.org"
Expand Down
34 changes: 34 additions & 0 deletions spec/support/artifice/compact_index_range_not_satisfiable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

require File.expand_path("../compact_index", __FILE__)

Artifice.deactivate

class CompactIndexRangeNotSatisfiable < CompactIndexAPI
get "/versions" do
if env["HTTP_RANGE"]
status 416
else
etag_response do
file = tmp("versions.list")
file.delete if file.file?
file = CompactIndex::VersionsFile.new(file.to_s)
file.create(gems)
file.contents
end
end
end

get "/info/:name" do
if env["HTTP_RANGE"]
status 416
else
etag_response do
gem = gems.find {|g| g.name == params[:name] }
CompactIndex.info(gem ? gem.versions : [])
end
end
end
end

Artifice.activate_with(CompactIndexRangeNotSatisfiable)