Handles all the fetching with the rubygems server
Exceptions classes that should bypass retry attempts. If your password didn't work the first time, it's not going to the third time.
fetch a gem specification
# File bundler/fetcher.rb, line 96
def fetch_spec(spec)
spec -= [nil, "ruby", ""]
spec_file_name = "#{spec.join "-"}.gemspec"
uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
if uri.scheme == "file"
path = Bundler.rubygems.correct_for_windows_path(uri.path)
Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
Bundler.load_gemspec(cached_spec_path)
else
Bundler.load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
end
rescue MarshalError
raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
"Your network or your gem server is probably having issues right now."
end
# File bundler/fetcher.rb, line 206
def fetchers
@fetchers ||= FETCHERS.map {|f| f.new(downloader, @remote, uri) }
end
# File bundler/fetcher.rb, line 210
def http_proxy
return unless uri = connection.proxy_uri
uri.to_s
end
# File bundler/fetcher.rb, line 215
def inspect
"#<#{self.class}:0x#{object_id} uri=#{uri}>"
end
return the specs in the bundler format as an index
# File bundler/fetcher.rb, line 122
def specs(gem_names, source)
old = Bundler.rubygems.sources
index = Bundler::Index.new
if Bundler::Fetcher.disable_endpoint
@use_api = false
specs = fetchers.last.specs(gem_names)
else
specs = []
fetchers.shift until fetchers.first.available? || fetchers.empty?
fetchers.dup.each do |f|
break unless f.api_fetcher? && !gem_names || !specs = f.specs(gem_names)
fetchers.delete(f)
end
@use_api = false if fetchers.none?(&:api_fetcher?)
end
specs.each do |name, version, platform, dependencies, metadata|
next if name == "bundler"
spec = if dependencies
EndpointSpecification.new(name, version, platform, dependencies, metadata)
else
RemoteSpecification.new(name, version, platform, self)
end
spec.source = source
spec.remote = @remote
index << spec
end
index
rescue CertificateFailureError
Bundler.ui.info "" if gem_names && use_api # newline after dots
raise
ensure
Bundler.rubygems.sources = old
end
return the specs in the bundler format as an index with retries
# File bundler/fetcher.rb, line 115
def specs_with_retry(gem_names, source)
Bundler::Retry.new("fetcher", FAIL_ERRORS).attempts do
specs(gem_names, source)
end
end
# File bundler/fetcher.rb, line 159
def use_api
return @use_api if defined?(@use_api)
fetchers.shift until fetchers.first.available?
@use_api = if remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
false
else
fetchers.first.api_fetcher?
end
end
# File bundler/fetcher.rb, line 171
def user_agent
@user_agent ||= begin
ruby = Bundler::RubyVersion.system
agent = String.new("bundler/#{Bundler::VERSION}")
agent << " rubygems/#{Gem::VERSION}"
agent << " ruby/#{ruby.versions_string(ruby.versions)}"
agent << " (#{ruby.host})"
agent << " command/#{ARGV.first}"
if ruby.engine != "ruby"
# engine_version raises on unknown engines
engine_version = begin
ruby.engine_versions
rescue RuntimeError
"???"
end
agent << " #{ruby.engine}/#{ruby.versions_string(engine_version)}"
end
agent << " options/#{Bundler.settings.all.join(",")}"
agent << " ci/#{cis.join(",")}" if cis.any?
# add a random ID so we can consolidate runs server-side
agent << " " << SecureRandom.hex(8)
# add any user agent strings set in the config
extra_ua = Bundler.settings[:user_agent]
agent << " " << extra_ua if extra_ua
agent
end
end