diff options
author | Maxime Lapointe <hunter_spawn@hotmail.com> | 2018-08-21 00:18:23 -0400 |
---|---|---|
committer | Maxime Lapointe <hunter_spawn@hotmail.com> | 2018-08-27 10:14:20 -0400 |
commit | 8ddc9ac0fa34a0030c0c1b95bbdcd1e0b4ecfb4d (patch) | |
tree | 21b0c4551ed126bbe97a9b56c0bbf7c12c235dc3 | |
parent | 7667639716d7fecd822265d49c98b459fbecbf87 (diff) | |
download | bundler-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.rb | 5 | ||||
-rw-r--r-- | spec/install/gems/compact_index_spec.rb | 31 | ||||
-rw-r--r-- | spec/support/artifice/compact_index_range_not_satisfiable.rb | 34 |
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) |