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:
parent
dc8359969e
commit
8cc45aae94
82 changed files with 5776 additions and 2928 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue