diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 8c8c8689096..48cdf26e1df 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -226,6 +226,12 @@ def fetch_remote_specs(gem_names, full_dependency_list = [], last_spec_list = [] end def use_api + _use_api(true) + rescue AuthenticationRequiredError + retry_with_auth{_use_api(false)} + end + + def _use_api(reraise_auth_error = false) return @use_api if defined?(@use_api) if @remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint @@ -233,6 +239,9 @@ def use_api elsif fetch(dependency_api_uri) @use_api = true end + rescue AuthenticationRequiredError => e + raise e if reraise_auth_error + false rescue HTTPError @use_api = false end @@ -268,6 +277,8 @@ def fetch(uri, counter = 0) response.body when Net::HTTPRequestEntityTooLarge raise FallbackError, response.body + when Net::HTTPUnauthorized + raise AuthenticationRequiredError, "#{response.class}: #{response.body}" else raise HTTPError, "#{response.class}: #{response.body}" end @@ -282,8 +293,6 @@ def request(uri) req.basic_auth(user, password) end connection.request(uri, req) - rescue Net::HTTPUnauthorized, Net::HTTPForbidden - retry_with_auth { request(uri) } rescue OpenSSL::SSL::SSLError raise CertificateFailureError.new(uri) rescue *HTTP_ERRORS => e diff --git a/spec/install/gems/dependency_api_spec.rb b/spec/install/gems/dependency_api_spec.rb index b3e5edf4687..b8f8011f99d 100644 --- a/spec/install/gems/dependency_api_spec.rb +++ b/spec/install/gems/dependency_api_spec.rb @@ -467,6 +467,8 @@ def require(*args) bundle "config #{source_uri}/ #{user}:#{password}" bundle :install, :artifice => "endpoint_strict_basic_authentication" + + expect(out).to include("Fetching gem metadata from #{source_uri}") should_be_installed "rack 1.0.0" end