summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Lapointe <hunter_spawn@hotmail.com>2018-08-21 00:18:23 -0400
committerMaxime Lapointe <hunter_spawn@hotmail.com>2018-08-27 10:14:20 -0400
commit8ddc9ac0fa34a0030c0c1b95bbdcd1e0b4ecfb4d (patch)
tree21b0c4551ed126bbe97a9b56c0bbf7c12c235dc3
parent7667639716d7fecd822265d49c98b459fbecbf87 (diff)
downloadbundler-8ddc9ac0fa34a0030c0c1b95bbdcd1e0b4ecfb4d.tar.gz
Let updater retry on HTTPRequestedRangeNotSatisfiable (416)
Fixes issues when gems get yanked, which leads to the cached infos being longer than what is on the server. Being longer, the compact index api just return a 416, and bundler would fallback to the dependency API. Retrying to the compact index with no range would fix the issue. This is what this fix does.
-rw-r--r--lib/bundler/fetcher/downloader.rb5
-rw-r--r--spec/install/gems/compact_index_spec.rb31
-rw-r--r--spec/support/artifice/compact_index_range_not_satisfiable.rb34
3 files changed, 70 insertions, 0 deletions
diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb
index e77fbba33c..e0e0cbf1c9 100644
--- a/lib/bundler/fetcher/downloader.rb
+++ b/lib/bundler/fetcher/downloader.rb
@@ -27,6 +27,11 @@ module Bundler
new_uri.password = uri.password
end
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
diff --git a/spec/install/gems/compact_index_spec.rb b/spec/install/gems/compact_index_spec.rb
index f633004a3d..02a37a77d5 100644
--- a/spec/install/gems/compact_index_spec.rb
+++ b/spec/install/gems/compact_index_spec.rb
@@ -821,6 +821,37 @@ The checksum of /versions does not match the checksum provided by the server! So
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"
diff --git a/spec/support/artifice/compact_index_range_not_satisfiable.rb b/spec/support/artifice/compact_index_range_not_satisfiable.rb
new file mode 100644
index 0000000000..487be4771a
--- /dev/null
+++ b/spec/support/artifice/compact_index_range_not_satisfiable.rb
@@ -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)