1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Import RubyGems 1.1.0

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15873 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2008-03-31 22:40:06 +00:00
parent dc8359969e
commit 8cc45aae94
82 changed files with 5776 additions and 2928 deletions

View file

@ -2,7 +2,6 @@ require 'net/http'
require 'uri'
require 'rubygems'
require 'rubygems/gem_open_uri'
##
# RemoteFetcher handles the details of fetching gems and gem information from
@ -10,6 +9,8 @@ require 'rubygems/gem_open_uri'
class Gem::RemoteFetcher
include Gem::UserInteraction
class FetchError < Gem::Exception; end
@fetcher = nil
@ -29,6 +30,10 @@ class Gem::RemoteFetcher
# HTTP_PROXY_PASS)
# * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy
def initialize(proxy)
Socket.do_not_reverse_lookup = true
@connections = {}
@requests = Hash.new 0
@proxy_uri =
case proxy
when :no_proxy then nil
@ -38,6 +43,65 @@ class Gem::RemoteFetcher
end
end
##
# Moves the gem +spec+ from +source_uri+ to the cache dir unless it is
# already there. If the source_uri is local the gem cache dir copy is
# always replaced.
def download(spec, source_uri, install_dir = Gem.dir)
gem_file_name = "#{spec.full_name}.gem"
local_gem_path = File.join install_dir, 'cache', gem_file_name
Gem.ensure_gem_subdirectories install_dir
source_uri = URI.parse source_uri unless URI::Generic === source_uri
scheme = source_uri.scheme
# URI.parse gets confused by MS Windows paths with forward slashes.
scheme = nil if scheme =~ /^[a-z]$/i
case scheme
when 'http' then
unless File.exist? local_gem_path then
begin
say "Downloading gem #{gem_file_name}" if
Gem.configuration.really_verbose
remote_gem_path = source_uri + "gems/#{gem_file_name}"
gem = Gem::RemoteFetcher.fetcher.fetch_path remote_gem_path
rescue Gem::RemoteFetcher::FetchError
raise if spec.original_platform == spec.platform
alternate_name = "#{spec.original_name}.gem"
say "Failed, downloading gem #{alternate_name}" if
Gem.configuration.really_verbose
remote_gem_path = source_uri + "gems/#{alternate_name}"
gem = Gem::RemoteFetcher.fetcher.fetch_path remote_gem_path
end
File.open local_gem_path, 'wb' do |fp|
fp.write gem
end
end
when nil, 'file' then # TODO test for local overriding cache
begin
FileUtils.cp source_uri.to_s, local_gem_path
rescue Errno::EACCES
local_gem_path = source_uri.to_s
end
say "Using local gem #{local_gem_path}" if
Gem.configuration.really_verbose
else
raise Gem::InstallError, "unsupported URI scheme #{source_uri.scheme}"
end
local_gem_path
end
# Downloads +uri+.
def fetch_path(uri)
open_uri_or_path(uri) do |input|
@ -47,9 +111,8 @@ class Gem::RemoteFetcher
raise FetchError, "timed out fetching #{uri}"
rescue IOError, SocketError, SystemCallError => e
raise FetchError, "#{e.class}: #{e} reading #{uri}"
rescue OpenURI::HTTPError => e
body = e.io.readlines.join "\n\t"
message = "#{e.class}: #{e} reading #{uri}\n\t#{body}"
rescue => e
message = "#{e.class}: #{e} reading #{uri}"
raise FetchError, message
end
@ -83,7 +146,8 @@ class Gem::RemoteFetcher
end
rescue SocketError, SystemCallError, Timeout::Error => e
raise FetchError, "#{e.message} (#{e.class})\n\tgetting size of #{uri}"
raise Gem::RemoteFetcher::FetchError,
"#{e.message} (#{e.class})\n\tgetting size of #{uri}"
end
private
@ -131,26 +195,77 @@ class Gem::RemoteFetcher
# Read the data from the (source based) URI, but if it is a file:// URI,
# read from the filesystem instead.
def open_uri_or_path(uri, &block)
def open_uri_or_path(uri, depth = 0, &block)
if file_uri?(uri)
open(get_file_uri_path(uri), &block)
else
connection_options = {
"User-Agent" => "RubyGems/#{Gem::RubyGemsVersion} #{Gem::Platform.local}"
}
if @proxy_uri
http_proxy_url = "#{@proxy_uri.scheme}://#{@proxy_uri.host}:#{@proxy_uri.port}"
connection_options[:proxy_http_basic_authentication] = [http_proxy_url, unescape(@proxy_uri.user)||'', unescape(@proxy_uri.password)||'']
end
uri = URI.parse uri unless URI::Generic === uri
unless uri.nil? || uri.user.nil? || uri.user.empty? then
connection_options[:http_basic_authentication] =
[unescape(uri.user), unescape(uri.password)]
net_http_args = [uri.host, uri.port]
if @proxy_uri then
net_http_args += [ @proxy_uri.host,
@proxy_uri.port,
@proxy_uri.user,
@proxy_uri.password
]
end
open(uri, connection_options, &block)
connection_id = net_http_args.join ':'
@connections[connection_id] ||= Net::HTTP.new(*net_http_args)
connection = @connections[connection_id]
if uri.scheme == 'https' && ! connection.started?
http_obj.use_ssl = true
http_obj.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
connection.start unless connection.started?
request = Net::HTTP::Get.new(uri.request_uri)
unless uri.nil? || uri.user.nil? || uri.user.empty? then
request.basic_auth(uri.user, uri.password)
end
ua = "RubyGems/#{Gem::RubyGemsVersion} #{Gem::Platform.local}"
ua << " Ruby/#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}"
ua << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
ua << ")"
request.add_field 'User-Agent', ua
request.add_field 'Connection', 'keep-alive'
request.add_field 'Keep-Alive', '30'
# HACK work around EOFError bug in Net::HTTP
retried = false
begin
@requests[connection_id] += 1
response = connection.request(request)
rescue EOFError
requests = @requests[connection_id]
say "connection reset after #{requests} requests, retrying" if
Gem.configuration.really_verbose
raise Gem::RemoteFetcher::FetchError, 'too many connection resets' if
retried
@requests[connection_id] = 0
connection.finish
connection.start
retried = true
retry
end
case response
when Net::HTTPOK then
block.call(StringIO.new(response.body)) if block
when Net::HTTPRedirection then
raise Gem::RemoteFetcher::FetchError, "too many redirects" if depth > 10
open_uri_or_path(response['Location'], depth + 1, &block)
else
raise Gem::RemoteFetcher::FetchError,
"bad response #{response.message} #{response.code}"
end
end
end