mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Update to RubyGems 1.1.1 r1701.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15980 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									0ae6c7f816
								
							
						
					
					
						commit
						e72b71d56a
					
				
					 31 changed files with 272 additions and 888 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,7 @@
 | 
			
		|||
Sat Apr 12 05:55:57 2008  Eric Hodel  <drbrain@segment7.net>
 | 
			
		||||
 | 
			
		||||
	* lib/rubygems*, test/rubygems*:  Update to RubyGems 1.1.1 r1701.
 | 
			
		||||
 | 
			
		||||
Sat Apr 12 03:13:38 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* file.c (file_expand_path): set external encoding.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,7 +97,7 @@ module Gem
 | 
			
		|||
 | 
			
		||||
  @configuration = nil
 | 
			
		||||
  @loaded_specs = {}
 | 
			
		||||
  @platforms = nil
 | 
			
		||||
  @platforms = []
 | 
			
		||||
  @ruby = nil
 | 
			
		||||
  @sources = []
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +215,7 @@ module Gem
 | 
			
		|||
 | 
			
		||||
  def self.bindir(install_dir=Gem.dir)
 | 
			
		||||
    return File.join(install_dir, 'bin') unless
 | 
			
		||||
    install_dir.to_s == Gem.default_dir
 | 
			
		||||
      install_dir.to_s == Gem.default_dir
 | 
			
		||||
    Gem.default_bindir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -451,10 +451,21 @@ module Gem
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Array of platforms this RubyGems supports.
 | 
			
		||||
  # Set array of platforms this RubyGems supports (primarily for testing).
 | 
			
		||||
 | 
			
		||||
  def self.platforms=(platforms)
 | 
			
		||||
    @platforms = platforms
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Array of platforms this RubyGems supports.
 | 
			
		||||
  
 | 
			
		||||
  def self.platforms
 | 
			
		||||
    @platforms ||= [Gem::Platform::RUBY, Gem::Platform.local]
 | 
			
		||||
    @platforms ||= []
 | 
			
		||||
    if @platforms.empty?
 | 
			
		||||
      @platforms = [Gem::Platform::RUBY, Gem::Platform.local]
 | 
			
		||||
    end
 | 
			
		||||
    @platforms
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -463,13 +474,26 @@ module Gem
 | 
			
		|||
  def self.prefix
 | 
			
		||||
    prefix = File.dirname File.expand_path(__FILE__)
 | 
			
		||||
 | 
			
		||||
    if prefix == File.expand_path(ConfigMap[:sitelibdir]) then
 | 
			
		||||
    if File.dirname(prefix) == File.expand_path(ConfigMap[:sitelibdir]) or
 | 
			
		||||
       File.dirname(prefix) == File.expand_path(ConfigMap[:libdir]) or
 | 
			
		||||
       'lib' != File.basename(prefix) then
 | 
			
		||||
      nil
 | 
			
		||||
    else
 | 
			
		||||
      File.dirname prefix
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Refresh source_index from disk and clear searcher.
 | 
			
		||||
 | 
			
		||||
  def self.refresh
 | 
			
		||||
    source_index.refresh!
 | 
			
		||||
 | 
			
		||||
    MUTEX.synchronize do
 | 
			
		||||
      @searcher = nil
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Safely read a file in binary mode on all platforms.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,7 +93,7 @@ module Gem
 | 
			
		|||
        say Gem::Command::HELP
 | 
			
		||||
        terminate_interaction(0)
 | 
			
		||||
      when '-v', '--version'
 | 
			
		||||
        say Gem::RubyGemsPackageVersion
 | 
			
		||||
        say Gem::RubyGemsVersion
 | 
			
		||||
        terminate_interaction(0)
 | 
			
		||||
      when /^-/
 | 
			
		||||
        alert_error "Invalid option: #{args[0]}.  See 'gem --help'."
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ class Gem::Commands::EnvironmentCommand < Gem::Command
 | 
			
		|||
    when nil then
 | 
			
		||||
      out = "RubyGems Environment:\n"
 | 
			
		||||
 | 
			
		||||
      out << "  - RUBYGEMS VERSION: #{Gem::RubyGemsVersion} (#{Gem::RubyGemsPackageVersion})\n"
 | 
			
		||||
      out << "  - RUBYGEMS VERSION: #{Gem::RubyGemsVersion}\n"
 | 
			
		||||
 | 
			
		||||
      out << "  - RUBY VERSION: #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}"
 | 
			
		||||
      out << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,6 +126,7 @@ revert the gem.
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
      installer.generate_bin
 | 
			
		||||
      installer.build_extensions
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,13 +82,15 @@ class Gem::Commands::QueryCommand < Gem::Command
 | 
			
		|||
      say "*** REMOTE GEMS ***"
 | 
			
		||||
      say
 | 
			
		||||
 | 
			
		||||
      all = options[:all]
 | 
			
		||||
 | 
			
		||||
      begin
 | 
			
		||||
        Gem::SourceInfoCache.cache.refresh options[:all]
 | 
			
		||||
        Gem::SourceInfoCache.cache all
 | 
			
		||||
      rescue Gem::RemoteFetcher::FetchError
 | 
			
		||||
        # no network
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      output_query_results Gem::SourceInfoCache.search(name, false, true)
 | 
			
		||||
      output_query_results Gem::SourceInfoCache.search(name, false, all)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ class Gem::Commands::SourcesCommand < Gem::Command
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    if options[:update] then
 | 
			
		||||
      Gem::SourceInfoCache.cache.refresh true
 | 
			
		||||
      Gem::SourceInfoCache.cache true
 | 
			
		||||
      Gem::SourceInfoCache.cache.flush
 | 
			
		||||
 | 
			
		||||
      say "source cache successfully updated"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
 | 
			
		|||
      say "Updating installed gems"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    hig = {}
 | 
			
		||||
    hig = {} # highest installed gems
 | 
			
		||||
 | 
			
		||||
    Gem::SourceIndex.from_installed_gems.each do |name, spec|
 | 
			
		||||
      if hig[spec.name].nil? or hig[spec.name].version < spec.version then
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    pattern = if options[:args].empty? then
 | 
			
		||||
             //
 | 
			
		||||
                //
 | 
			
		||||
              else
 | 
			
		||||
                Regexp.union(*options[:args])
 | 
			
		||||
              end
 | 
			
		||||
| 
						 | 
				
			
			@ -78,12 +78,14 @@ class Gem::Commands::UpdateCommand < Gem::Command
 | 
			
		|||
 | 
			
		||||
    updated = []
 | 
			
		||||
 | 
			
		||||
    # HACK use the real API
 | 
			
		||||
    installer = Gem::DependencyInstaller.new options
 | 
			
		||||
 | 
			
		||||
    gems_to_update.uniq.sort.each do |name|
 | 
			
		||||
      next if updated.any? { |spec| spec.name == name }
 | 
			
		||||
 | 
			
		||||
      say "Updating #{name}"
 | 
			
		||||
      installer = Gem::DependencyInstaller.new options
 | 
			
		||||
      installer.install name
 | 
			
		||||
 | 
			
		||||
      installer.installed_gems.each do |spec|
 | 
			
		||||
        updated << spec
 | 
			
		||||
        say "Successfully installed #{spec.full_name}"
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +117,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
 | 
			
		|||
    args.push '--prefix', Gem.prefix unless Gem.prefix.nil?
 | 
			
		||||
    args << '--no-rdoc' unless options[:generate_rdoc]
 | 
			
		||||
    args << '--no-ri' unless options[:generate_ri]
 | 
			
		||||
    args << '--no-format-executable' if options[:no_format_executable]
 | 
			
		||||
 | 
			
		||||
    update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ class Gem::DependencyInstaller
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        all = requirements.length > 1 ||
 | 
			
		||||
                requirements.first != ">=" || requirements.first != ">"
 | 
			
		||||
                (requirements.first != ">=" and requirements.first != ">")
 | 
			
		||||
 | 
			
		||||
        found = Gem::SourceInfoCache.search_with_source dep, true, all
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +189,13 @@ class Gem::DependencyInstaller
 | 
			
		|||
      say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose
 | 
			
		||||
 | 
			
		||||
      _, source_uri = @specs_and_sources.assoc spec
 | 
			
		||||
      local_gem_path = Gem::RemoteFetcher.fetcher.download spec, source_uri
 | 
			
		||||
      begin
 | 
			
		||||
        local_gem_path = Gem::RemoteFetcher.fetcher.download spec, source_uri,
 | 
			
		||||
                                                             @install_dir
 | 
			
		||||
      rescue Gem::RemoteFetcher::FetchError
 | 
			
		||||
        next if @force
 | 
			
		||||
        raise
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      inst = Gem::Installer.new local_gem_path,
 | 
			
		||||
                                :env_shebang => @env_shebang,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,12 @@ module Gem
 | 
			
		|||
 | 
			
		||||
      FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
 | 
			
		||||
 | 
			
		||||
      begin
 | 
			
		||||
        gem 'rdoc'
 | 
			
		||||
      rescue Gem::LoadError
 | 
			
		||||
        # use built-in RDoc
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      begin
 | 
			
		||||
        require 'rdoc/rdoc'
 | 
			
		||||
      rescue LoadError => e
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +0,0 @@
 | 
			
		|||
#!/usr/bin/env ruby
 | 
			
		||||
 | 
			
		||||
if RUBY_VERSION > '1.9' then
 | 
			
		||||
  require 'open-uri'
 | 
			
		||||
else
 | 
			
		||||
  require 'rubygems/open-uri'
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ class Gem::Indexer
 | 
			
		|||
                progress.updated spec.original_name
 | 
			
		||||
 | 
			
		||||
              rescue SignalException => e
 | 
			
		||||
                alert_error "Recieved signal, exiting"
 | 
			
		||||
                alert_error "Received signal, exiting"
 | 
			
		||||
                raise
 | 
			
		||||
              rescue Exception => e
 | 
			
		||||
                alert_error "Unable to process #{gemfile}\n#{e.message} (#{e.class})\n\t#{e.backtrace.join "\n\t"}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,773 +0,0 @@
 | 
			
		|||
require 'uri'
 | 
			
		||||
require 'stringio'
 | 
			
		||||
require 'time'
 | 
			
		||||
 | 
			
		||||
# :stopdoc:
 | 
			
		||||
module Kernel
 | 
			
		||||
  private
 | 
			
		||||
  alias rubygems_open_uri_original_open open # :nodoc:
 | 
			
		||||
 | 
			
		||||
  # makes possible to open various resources including URIs.
 | 
			
		||||
  # If the first argument respond to `open' method,
 | 
			
		||||
  # the method is called with the rest arguments.
 | 
			
		||||
  #
 | 
			
		||||
  # If the first argument is a string which begins with xxx://,
 | 
			
		||||
  # it is parsed by URI.parse.  If the parsed object respond to `open' method,
 | 
			
		||||
  # the method is called with the rest arguments.
 | 
			
		||||
  #
 | 
			
		||||
  # Otherwise original open is called.
 | 
			
		||||
  #
 | 
			
		||||
  # Since open-uri.rb provides URI::HTTP#open, URI::HTTPS#open and
 | 
			
		||||
  # URI::FTP#open,
 | 
			
		||||
  # Kernel[#.]open can accepts such URIs and strings which begins with
 | 
			
		||||
  # http://, https:// and ftp://.
 | 
			
		||||
  # In these case, the opened file object is extended by OpenURI::Meta.
 | 
			
		||||
  def open(name, *rest, &block) # :doc:
 | 
			
		||||
    if name.respond_to?(:open)
 | 
			
		||||
      name.open(*rest, &block)
 | 
			
		||||
    elsif name.respond_to?(:to_str) &&
 | 
			
		||||
          %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
 | 
			
		||||
          (uri = URI.parse(name)).respond_to?(:open)
 | 
			
		||||
      uri.open(*rest, &block)
 | 
			
		||||
    else
 | 
			
		||||
      rubygems_open_uri_original_open(name, *rest, &block)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  module_function :open
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp.
 | 
			
		||||
#
 | 
			
		||||
#== Example
 | 
			
		||||
#
 | 
			
		||||
# It is possible to open http/https/ftp URL as usual like opening a file:
 | 
			
		||||
#
 | 
			
		||||
#   open("http://www.ruby-lang.org/") {|f|
 | 
			
		||||
#     f.each_line {|line| p line}
 | 
			
		||||
#   }
 | 
			
		||||
#
 | 
			
		||||
# The opened file has several methods for meta information as follows since
 | 
			
		||||
# it is extended by OpenURI::Meta.
 | 
			
		||||
#
 | 
			
		||||
#   open("http://www.ruby-lang.org/en") {|f|
 | 
			
		||||
#     f.each_line {|line| p line}
 | 
			
		||||
#     p f.base_uri         # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
 | 
			
		||||
#     p f.content_type     # "text/html"
 | 
			
		||||
#     p f.charset          # "iso-8859-1"
 | 
			
		||||
#     p f.content_encoding # []
 | 
			
		||||
#     p f.last_modified    # Thu Dec 05 02:45:02 UTC 2002
 | 
			
		||||
#   }
 | 
			
		||||
#
 | 
			
		||||
# Additional header fields can be specified by an optional hash argument.
 | 
			
		||||
#
 | 
			
		||||
#   open("http://www.ruby-lang.org/en/",
 | 
			
		||||
#     "User-Agent" => "Ruby/#{RUBY_VERSION}",
 | 
			
		||||
#     "From" => "foo@bar.invalid",
 | 
			
		||||
#     "Referer" => "http://www.ruby-lang.org/") {|f|
 | 
			
		||||
#     # ...
 | 
			
		||||
#   }
 | 
			
		||||
#
 | 
			
		||||
# The environment variables such as http_proxy, https_proxy and ftp_proxy
 | 
			
		||||
# are in effect by default.  :proxy => nil disables proxy.
 | 
			
		||||
#
 | 
			
		||||
#   open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f|
 | 
			
		||||
#     # ...
 | 
			
		||||
#   }
 | 
			
		||||
#
 | 
			
		||||
# URI objects can be opened in a similar way.
 | 
			
		||||
#
 | 
			
		||||
#   uri = URI.parse("http://www.ruby-lang.org/en/")
 | 
			
		||||
#   uri.open {|f|
 | 
			
		||||
#     # ...
 | 
			
		||||
#   }
 | 
			
		||||
#
 | 
			
		||||
# URI objects can be read directly. The returned string is also extended by
 | 
			
		||||
# OpenURI::Meta.
 | 
			
		||||
#
 | 
			
		||||
#   str = uri.read
 | 
			
		||||
#   p str.base_uri
 | 
			
		||||
#
 | 
			
		||||
# Author:: Tanaka Akira <akr@m17n.org>
 | 
			
		||||
 | 
			
		||||
module OpenURI
 | 
			
		||||
  Options = {
 | 
			
		||||
    :proxy => true,
 | 
			
		||||
    :proxy_http_basic_authentication => true,
 | 
			
		||||
    :progress_proc => true,
 | 
			
		||||
    :content_length_proc => true,
 | 
			
		||||
    :http_basic_authentication => true,
 | 
			
		||||
    :read_timeout => true,
 | 
			
		||||
    :ssl_ca_cert => nil,
 | 
			
		||||
    :ssl_verify_mode => nil,
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def OpenURI.check_options(options) # :nodoc:
 | 
			
		||||
    options.each {|k, v|
 | 
			
		||||
      next unless Symbol === k
 | 
			
		||||
      unless Options.include? k
 | 
			
		||||
        raise ArgumentError, "unrecognized option: #{k}"
 | 
			
		||||
      end
 | 
			
		||||
    }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def OpenURI.scan_open_optional_arguments(*rest) # :nodoc:
 | 
			
		||||
    if !rest.empty? && (String === rest.first || Integer === rest.first)
 | 
			
		||||
      mode = rest.shift
 | 
			
		||||
      if !rest.empty? && Integer === rest.first
 | 
			
		||||
        perm = rest.shift
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    return mode, perm, rest
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def OpenURI.open_uri(name, *rest) # :nodoc:
 | 
			
		||||
    uri = URI::Generic === name ? name : URI.parse(name)
 | 
			
		||||
    mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest)
 | 
			
		||||
    options = rest.shift if !rest.empty? && Hash === rest.first
 | 
			
		||||
    raise ArgumentError.new("extra arguments") if !rest.empty?
 | 
			
		||||
    options ||= {}
 | 
			
		||||
    OpenURI.check_options(options)
 | 
			
		||||
 | 
			
		||||
    unless mode == nil ||
 | 
			
		||||
           mode == 'r' || mode == 'rb' ||
 | 
			
		||||
           mode == File::RDONLY
 | 
			
		||||
      raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    io = open_loop(uri, options)
 | 
			
		||||
    if block_given?
 | 
			
		||||
      begin
 | 
			
		||||
        yield io
 | 
			
		||||
      ensure
 | 
			
		||||
        io.close
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      io
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def OpenURI.open_loop(uri, options) # :nodoc:
 | 
			
		||||
    proxy_opts = []
 | 
			
		||||
    proxy_opts << :proxy_http_basic_authentication if options.include? :proxy_http_basic_authentication
 | 
			
		||||
    proxy_opts << :proxy if options.include? :proxy
 | 
			
		||||
    proxy_opts.compact!
 | 
			
		||||
    if 1 < proxy_opts.length
 | 
			
		||||
      raise ArgumentError, "multiple proxy options specified"
 | 
			
		||||
    end
 | 
			
		||||
    case proxy_opts.first
 | 
			
		||||
    when :proxy_http_basic_authentication
 | 
			
		||||
      opt_proxy, proxy_user, proxy_pass = options.fetch(:proxy_http_basic_authentication)
 | 
			
		||||
      proxy_user = proxy_user.to_str
 | 
			
		||||
      proxy_pass = proxy_pass.to_str
 | 
			
		||||
      if opt_proxy == true
 | 
			
		||||
        raise ArgumentError.new("Invalid authenticated proxy option: #{options[:proxy_http_basic_authentication].inspect}")
 | 
			
		||||
      end
 | 
			
		||||
    when :proxy
 | 
			
		||||
      opt_proxy = options.fetch(:proxy)
 | 
			
		||||
      proxy_user = nil
 | 
			
		||||
      proxy_pass = nil
 | 
			
		||||
    when nil
 | 
			
		||||
      opt_proxy = true
 | 
			
		||||
      proxy_user = nil
 | 
			
		||||
      proxy_pass = nil
 | 
			
		||||
    end
 | 
			
		||||
    case opt_proxy
 | 
			
		||||
    when true
 | 
			
		||||
      find_proxy = lambda {|u| pxy = u.find_proxy; pxy ? [pxy, nil, nil] : nil}
 | 
			
		||||
    when nil, false
 | 
			
		||||
      find_proxy = lambda {|u| nil}
 | 
			
		||||
    when String
 | 
			
		||||
      opt_proxy = URI.parse(opt_proxy)
 | 
			
		||||
      find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
 | 
			
		||||
    when URI::Generic
 | 
			
		||||
      find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
 | 
			
		||||
    else
 | 
			
		||||
      raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    uri_set = {}
 | 
			
		||||
    buf = nil
 | 
			
		||||
    while true
 | 
			
		||||
      redirect = catch(:open_uri_redirect) {
 | 
			
		||||
        buf = Buffer.new
 | 
			
		||||
        uri.buffer_open(buf, find_proxy.call(uri), options)
 | 
			
		||||
        nil
 | 
			
		||||
      }
 | 
			
		||||
      if redirect
 | 
			
		||||
        if redirect.relative?
 | 
			
		||||
          # Although it violates RFC2616, Location: field may have relative
 | 
			
		||||
          # URI.  It is converted to absolute URI using uri as a base URI.
 | 
			
		||||
          redirect = uri + redirect
 | 
			
		||||
        end
 | 
			
		||||
        unless OpenURI.redirectable?(uri, redirect)
 | 
			
		||||
          raise "redirection forbidden: #{uri} -> #{redirect}"
 | 
			
		||||
        end
 | 
			
		||||
        if options.include? :http_basic_authentication
 | 
			
		||||
          # send authentication only for the URI directly specified.
 | 
			
		||||
          options = options.dup
 | 
			
		||||
          options.delete :http_basic_authentication
 | 
			
		||||
        end
 | 
			
		||||
        uri = redirect
 | 
			
		||||
        raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
 | 
			
		||||
        uri_set[uri.to_s] = true
 | 
			
		||||
      else
 | 
			
		||||
        break
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    io = buf.io
 | 
			
		||||
    io.base_uri = uri
 | 
			
		||||
    io
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def OpenURI.redirectable?(uri1, uri2) # :nodoc:
 | 
			
		||||
    # This test is intended to forbid a redirection from http://... to
 | 
			
		||||
    # file:///etc/passwd.
 | 
			
		||||
    # However this is ad hoc.  It should be extensible/configurable.
 | 
			
		||||
    uri1.scheme.downcase == uri2.scheme.downcase ||
 | 
			
		||||
    (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
 | 
			
		||||
    if proxy
 | 
			
		||||
      proxy_uri, proxy_user, proxy_pass = proxy
 | 
			
		||||
      raise "Non-HTTP proxy URI: #{proxy_uri}" if proxy_uri.class != URI::HTTP
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if target.userinfo && "1.9.0" <= RUBY_VERSION
 | 
			
		||||
      # don't raise for 1.8 because compatibility.
 | 
			
		||||
      raise ArgumentError, "userinfo not supported.  [RFC3986]"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    header = {}
 | 
			
		||||
    options.each {|k, v| header[k] = v if String === k }
 | 
			
		||||
 | 
			
		||||
    require 'net/http'
 | 
			
		||||
    klass = Net::HTTP
 | 
			
		||||
    if URI::HTTP === target
 | 
			
		||||
      # HTTP or HTTPS
 | 
			
		||||
      if proxy
 | 
			
		||||
        if proxy_user && proxy_pass
 | 
			
		||||
          klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_user, proxy_pass)
 | 
			
		||||
        else
 | 
			
		||||
          klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      target_host = target.host
 | 
			
		||||
      target_port = target.port
 | 
			
		||||
      request_uri = target.request_uri
 | 
			
		||||
    else
 | 
			
		||||
      # FTP over HTTP proxy
 | 
			
		||||
      target_host = proxy_uri.host
 | 
			
		||||
      target_port = proxy_uri.port
 | 
			
		||||
      request_uri = target.to_s
 | 
			
		||||
      if proxy_user && proxy_pass
 | 
			
		||||
        header["Proxy-Authorization"] = 'Basic ' + ["#{proxy_user}:#{proxy_pass}"].pack('m').delete("\r\n")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    http = klass.new(target_host, target_port)
 | 
			
		||||
    if target.class == URI::HTTPS
 | 
			
		||||
      require 'net/https'
 | 
			
		||||
      http.use_ssl = true
 | 
			
		||||
      http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER
 | 
			
		||||
      store = OpenSSL::X509::Store.new
 | 
			
		||||
      if options[:ssl_ca_cert]
 | 
			
		||||
        if File.directory? options[:ssl_ca_cert]
 | 
			
		||||
          store.add_path options[:ssl_ca_cert]
 | 
			
		||||
        else
 | 
			
		||||
          store.add_file options[:ssl_ca_cert]
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        store.set_default_paths
 | 
			
		||||
      end
 | 
			
		||||
      store.set_default_paths
 | 
			
		||||
      http.cert_store = store
 | 
			
		||||
    end
 | 
			
		||||
    if options.include? :read_timeout
 | 
			
		||||
      http.read_timeout = options[:read_timeout]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    resp = nil
 | 
			
		||||
    http.start {
 | 
			
		||||
      if target.class == URI::HTTPS
 | 
			
		||||
        # xxx: information hiding violation
 | 
			
		||||
        sock = http.instance_variable_get(:@socket)
 | 
			
		||||
        if sock.respond_to?(:io)
 | 
			
		||||
          sock = sock.io # 1.9
 | 
			
		||||
        else
 | 
			
		||||
          sock = sock.instance_variable_get(:@socket) # 1.8
 | 
			
		||||
        end
 | 
			
		||||
        sock.post_connection_check(target_host)
 | 
			
		||||
      end
 | 
			
		||||
      req = Net::HTTP::Get.new(request_uri, header)
 | 
			
		||||
      if options.include? :http_basic_authentication
 | 
			
		||||
        user, pass = options[:http_basic_authentication]
 | 
			
		||||
        req.basic_auth user, pass
 | 
			
		||||
      end
 | 
			
		||||
      http.request(req) {|response|
 | 
			
		||||
        resp = response
 | 
			
		||||
        if options[:content_length_proc] && Net::HTTPSuccess === resp
 | 
			
		||||
          if resp.key?('Content-Length')
 | 
			
		||||
            options[:content_length_proc].call(resp['Content-Length'].to_i)
 | 
			
		||||
          else
 | 
			
		||||
            options[:content_length_proc].call(nil)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        resp.read_body {|str|
 | 
			
		||||
          buf << str
 | 
			
		||||
          if options[:progress_proc] && Net::HTTPSuccess === resp
 | 
			
		||||
            options[:progress_proc].call(buf.size)
 | 
			
		||||
          end
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    io = buf.io
 | 
			
		||||
    io.rewind
 | 
			
		||||
    io.status = [resp.code, resp.message]
 | 
			
		||||
    resp.each {|name,value| buf.io.meta_add_field name, value }
 | 
			
		||||
    case resp
 | 
			
		||||
    when Net::HTTPSuccess
 | 
			
		||||
    when Net::HTTPMovedPermanently, # 301
 | 
			
		||||
         Net::HTTPFound, # 302
 | 
			
		||||
         Net::HTTPSeeOther, # 303
 | 
			
		||||
         Net::HTTPTemporaryRedirect # 307
 | 
			
		||||
      throw :open_uri_redirect, URI.parse(resp['location'])
 | 
			
		||||
    else
 | 
			
		||||
      raise OpenURI::HTTPError.new(io.status.join(' '), io)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class HTTPError < StandardError
 | 
			
		||||
    def initialize(message, io)
 | 
			
		||||
      super(message)
 | 
			
		||||
      @io = io
 | 
			
		||||
    end
 | 
			
		||||
    attr_reader :io
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class Buffer # :nodoc:
 | 
			
		||||
    def initialize
 | 
			
		||||
      @io = StringIO.new
 | 
			
		||||
      @size = 0
 | 
			
		||||
    end
 | 
			
		||||
    attr_reader :size
 | 
			
		||||
 | 
			
		||||
    StringMax = 10240
 | 
			
		||||
    def <<(str)
 | 
			
		||||
      @io << str
 | 
			
		||||
      @size += str.length
 | 
			
		||||
      if StringIO === @io && StringMax < @size
 | 
			
		||||
        require 'tempfile'
 | 
			
		||||
        io = Tempfile.new('open-uri')
 | 
			
		||||
        io.binmode
 | 
			
		||||
        Meta.init io, @io if @io.respond_to? :meta
 | 
			
		||||
        io << @io.string
 | 
			
		||||
        @io = io
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def io
 | 
			
		||||
      Meta.init @io unless @io.respond_to? :meta
 | 
			
		||||
      @io
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Mixin for holding meta-information.
 | 
			
		||||
  module Meta
 | 
			
		||||
    def Meta.init(obj, src=nil) # :nodoc:
 | 
			
		||||
      obj.extend Meta
 | 
			
		||||
      obj.instance_eval {
 | 
			
		||||
        @base_uri = nil
 | 
			
		||||
        @meta = {}
 | 
			
		||||
      }
 | 
			
		||||
      if src
 | 
			
		||||
        obj.status = src.status
 | 
			
		||||
        obj.base_uri = src.base_uri
 | 
			
		||||
        src.meta.each {|name, value|
 | 
			
		||||
          obj.meta_add_field(name, value)
 | 
			
		||||
        }
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # returns an Array which consists status code and message.
 | 
			
		||||
    attr_accessor :status
 | 
			
		||||
 | 
			
		||||
    # returns a URI which is base of relative URIs in the data.
 | 
			
		||||
    # It may differ from the URI supplied by a user because redirection.
 | 
			
		||||
    attr_accessor :base_uri
 | 
			
		||||
 | 
			
		||||
    # returns a Hash which represents header fields.
 | 
			
		||||
    # The Hash keys are downcased for canonicalization.
 | 
			
		||||
    attr_reader :meta
 | 
			
		||||
 | 
			
		||||
    def meta_add_field(name, value) # :nodoc:
 | 
			
		||||
      @meta[name.downcase] = value
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # returns a Time which represents Last-Modified field.
 | 
			
		||||
    def last_modified
 | 
			
		||||
      if v = @meta['last-modified']
 | 
			
		||||
        Time.httpdate(v)
 | 
			
		||||
      else
 | 
			
		||||
        nil
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    RE_LWS = /[\r\n\t ]+/n
 | 
			
		||||
    RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
 | 
			
		||||
    RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
 | 
			
		||||
    RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n
 | 
			
		||||
 | 
			
		||||
    def content_type_parse # :nodoc:
 | 
			
		||||
      v = @meta['content-type']
 | 
			
		||||
      # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
 | 
			
		||||
      if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v
 | 
			
		||||
        type = $1.downcase
 | 
			
		||||
        subtype = $2.downcase
 | 
			
		||||
        parameters = []
 | 
			
		||||
        $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
 | 
			
		||||
          val = qval.gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/n) { $1 ? $1[1,1] : $& } if qval
 | 
			
		||||
          parameters << [att.downcase, val]
 | 
			
		||||
        }
 | 
			
		||||
        ["#{type}/#{subtype}", *parameters]
 | 
			
		||||
      else
 | 
			
		||||
        nil
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # returns "type/subtype" which is MIME Content-Type.
 | 
			
		||||
    # It is downcased for canonicalization.
 | 
			
		||||
    # Content-Type parameters are stripped.
 | 
			
		||||
    def content_type
 | 
			
		||||
      type, *parameters = content_type_parse
 | 
			
		||||
      type || 'application/octet-stream'
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # returns a charset parameter in Content-Type field.
 | 
			
		||||
    # It is downcased for canonicalization.
 | 
			
		||||
    #
 | 
			
		||||
    # If charset parameter is not given but a block is given,
 | 
			
		||||
    # the block is called and its result is returned.
 | 
			
		||||
    # It can be used to guess charset.
 | 
			
		||||
    #
 | 
			
		||||
    # If charset parameter and block is not given,
 | 
			
		||||
    # nil is returned except text type in HTTP.
 | 
			
		||||
    # In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1.
 | 
			
		||||
    def charset
 | 
			
		||||
      type, *parameters = content_type_parse
 | 
			
		||||
      if pair = parameters.assoc('charset')
 | 
			
		||||
        pair.last.downcase
 | 
			
		||||
      elsif block_given?
 | 
			
		||||
        yield
 | 
			
		||||
      elsif type && %r{\Atext/} =~ type &&
 | 
			
		||||
            @base_uri && /\Ahttp\z/i =~ @base_uri.scheme
 | 
			
		||||
        "iso-8859-1" # RFC2616 3.7.1
 | 
			
		||||
      else
 | 
			
		||||
        nil
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # returns a list of encodings in Content-Encoding field
 | 
			
		||||
    # as an Array of String.
 | 
			
		||||
    # The encodings are downcased for canonicalization.
 | 
			
		||||
    def content_encoding
 | 
			
		||||
      v = @meta['content-encoding']
 | 
			
		||||
      if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v
 | 
			
		||||
        v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
 | 
			
		||||
      else
 | 
			
		||||
        []
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Mixin for HTTP and FTP URIs.
 | 
			
		||||
  module OpenRead
 | 
			
		||||
    # OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.
 | 
			
		||||
    #
 | 
			
		||||
    # OpenURI::OpenRead#open takes optional 3 arguments as:
 | 
			
		||||
    # OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
 | 
			
		||||
    #
 | 
			
		||||
    # `mode', `perm' is same as Kernel#open.
 | 
			
		||||
    #
 | 
			
		||||
    # However, `mode' must be read mode because OpenURI::OpenRead#open doesn't
 | 
			
		||||
    # support write mode (yet).
 | 
			
		||||
    # Also `perm' is just ignored because it is meaningful only for file
 | 
			
		||||
    # creation.
 | 
			
		||||
    #
 | 
			
		||||
    # `options' must be a hash.
 | 
			
		||||
    #
 | 
			
		||||
    # Each pairs which key is a string in the hash specify a extra header
 | 
			
		||||
    # field for HTTP.
 | 
			
		||||
    # I.e. it is ignored for FTP without HTTP proxy.
 | 
			
		||||
    #
 | 
			
		||||
    # The hash may include other options which key is a symbol:
 | 
			
		||||
    #
 | 
			
		||||
    # [:proxy]
 | 
			
		||||
    #  Synopsis:
 | 
			
		||||
    #    :proxy => "http://proxy.foo.com:8000/"
 | 
			
		||||
    #    :proxy => URI.parse("http://proxy.foo.com:8000/")
 | 
			
		||||
    #    :proxy => true
 | 
			
		||||
    #    :proxy => false
 | 
			
		||||
    #    :proxy => nil
 | 
			
		||||
    #   
 | 
			
		||||
    #  If :proxy option is specified, the value should be String, URI,
 | 
			
		||||
    #  boolean or nil.
 | 
			
		||||
    #  When String or URI is given, it is treated as proxy URI.
 | 
			
		||||
    #  When true is given or the option itself is not specified,
 | 
			
		||||
    #  environment variable `scheme_proxy' is examined.
 | 
			
		||||
    #  `scheme' is replaced by `http', `https' or `ftp'.
 | 
			
		||||
    #  When false or nil is given, the environment variables are ignored and
 | 
			
		||||
    #  connection will be made to a server directly.
 | 
			
		||||
    #
 | 
			
		||||
    # [:proxy_http_basic_authentication]
 | 
			
		||||
    #  Synopsis:
 | 
			
		||||
    #    :proxy_http_basic_authentication => ["http://proxy.foo.com:8000/", "proxy-user", "proxy-password"]
 | 
			
		||||
    #    :proxy_http_basic_authentication => [URI.parse("http://proxy.foo.com:8000/"), "proxy-user", "proxy-password"]
 | 
			
		||||
    #   
 | 
			
		||||
    #  If :proxy option is specified, the value should be an Array with 3 elements.
 | 
			
		||||
    #  It should contain a proxy URI, a proxy user name and a proxy password.
 | 
			
		||||
    #  The proxy URI should be a String, an URI or nil.
 | 
			
		||||
    #  The proxy user name and password should be a String.
 | 
			
		||||
    #
 | 
			
		||||
    #  If nil is given for the proxy URI, this option is just ignored.
 | 
			
		||||
    #
 | 
			
		||||
    #  If :proxy and :proxy_http_basic_authentication is specified, 
 | 
			
		||||
    #  ArgumentError is raised.
 | 
			
		||||
    #
 | 
			
		||||
    # [:http_basic_authentication]
 | 
			
		||||
    #  Synopsis:
 | 
			
		||||
    #    :http_basic_authentication=>[user, password]
 | 
			
		||||
    #
 | 
			
		||||
    #  If :http_basic_authentication is specified,
 | 
			
		||||
    #  the value should be an array which contains 2 strings:
 | 
			
		||||
    #  username and password.
 | 
			
		||||
    #  It is used for HTTP Basic authentication defined by RFC 2617.
 | 
			
		||||
    #
 | 
			
		||||
    # [:content_length_proc]
 | 
			
		||||
    #  Synopsis:
 | 
			
		||||
    #    :content_length_proc => lambda {|content_length| ... }
 | 
			
		||||
    # 
 | 
			
		||||
    #  If :content_length_proc option is specified, the option value procedure
 | 
			
		||||
    #  is called before actual transfer is started.
 | 
			
		||||
    #  It takes one argument which is expected content length in bytes.
 | 
			
		||||
    # 
 | 
			
		||||
    #  If two or more transfer is done by HTTP redirection, the procedure
 | 
			
		||||
    #  is called only one for a last transfer.
 | 
			
		||||
    # 
 | 
			
		||||
    #  When expected content length is unknown, the procedure is called with
 | 
			
		||||
    #  nil.
 | 
			
		||||
    #  It is happen when HTTP response has no Content-Length header.
 | 
			
		||||
    #
 | 
			
		||||
    # [:progress_proc]
 | 
			
		||||
    #  Synopsis:
 | 
			
		||||
    #    :progress_proc => lambda {|size| ...}
 | 
			
		||||
    #
 | 
			
		||||
    #  If :progress_proc option is specified, the proc is called with one
 | 
			
		||||
    #  argument each time when `open' gets content fragment from network.
 | 
			
		||||
    #  The argument `size' `size' is a accumulated transfered size in bytes.
 | 
			
		||||
    #
 | 
			
		||||
    #  If two or more transfer is done by HTTP redirection, the procedure
 | 
			
		||||
    #  is called only one for a last transfer.
 | 
			
		||||
    #
 | 
			
		||||
    #  :progress_proc and :content_length_proc are intended to be used for
 | 
			
		||||
    #  progress bar.
 | 
			
		||||
    #  For example, it can be implemented as follows using Ruby/ProgressBar.
 | 
			
		||||
    #
 | 
			
		||||
    #    pbar = nil
 | 
			
		||||
    #    open("http://...",
 | 
			
		||||
    #      :content_length_proc => lambda {|t|
 | 
			
		||||
    #        if t && 0 < t
 | 
			
		||||
    #          pbar = ProgressBar.new("...", t)
 | 
			
		||||
    #          pbar.file_transfer_mode
 | 
			
		||||
    #        end
 | 
			
		||||
    #      },
 | 
			
		||||
    #      :progress_proc => lambda {|s|
 | 
			
		||||
    #        pbar.set s if pbar
 | 
			
		||||
    #      }) {|f| ... }
 | 
			
		||||
    #
 | 
			
		||||
    # [:read_timeout]
 | 
			
		||||
    #  Synopsis:
 | 
			
		||||
    #    :read_timeout=>nil     (no timeout)
 | 
			
		||||
    #    :read_timeout=>10      (10 second)
 | 
			
		||||
    #
 | 
			
		||||
    #  :read_timeout option specifies a timeout of read for http connections.
 | 
			
		||||
    #
 | 
			
		||||
    # [:ssl_ca_cert]
 | 
			
		||||
    #  Synopsis:
 | 
			
		||||
    #    :ssl_ca_cert=>filename
 | 
			
		||||
    #
 | 
			
		||||
    #  :ssl_ca_cert is used to specify CA certificate for SSL.
 | 
			
		||||
    #  If it is given, default certificates are not used.
 | 
			
		||||
    #
 | 
			
		||||
    # [:ssl_verify_mode]
 | 
			
		||||
    #  Synopsis:
 | 
			
		||||
    #    :ssl_verify_mode=>mode
 | 
			
		||||
    #
 | 
			
		||||
    #  :ssl_verify_mode is used to specify openssl verify mode.
 | 
			
		||||
    #
 | 
			
		||||
    # OpenURI::OpenRead#open returns an IO like object if block is not given.
 | 
			
		||||
    # Otherwise it yields the IO object and return the value of the block.
 | 
			
		||||
    # The IO object is extended with OpenURI::Meta.
 | 
			
		||||
    def open(*rest, &block)
 | 
			
		||||
      OpenURI.open_uri(self, *rest, &block)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # OpenURI::OpenRead#read([options]) reads a content referenced by self and
 | 
			
		||||
    # returns the content as string.
 | 
			
		||||
    # The string is extended with OpenURI::Meta.
 | 
			
		||||
    # The argument `options' is same as OpenURI::OpenRead#open.
 | 
			
		||||
    def read(options={})
 | 
			
		||||
      self.open(options) {|f|
 | 
			
		||||
        str = f.read
 | 
			
		||||
        Meta.init str, f
 | 
			
		||||
        str
 | 
			
		||||
      }
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module URI
 | 
			
		||||
  class Generic
 | 
			
		||||
    # returns a proxy URI.
 | 
			
		||||
    # The proxy URI is obtained from environment variables such as http_proxy,
 | 
			
		||||
    # ftp_proxy, no_proxy, etc.
 | 
			
		||||
    # If there is no proper proxy, nil is returned.
 | 
			
		||||
    #
 | 
			
		||||
    # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
 | 
			
		||||
    # are examined too.
 | 
			
		||||
    #
 | 
			
		||||
    # But http_proxy and HTTP_PROXY is treated specially under CGI environment.
 | 
			
		||||
    # It's because HTTP_PROXY may be set by Proxy: header.
 | 
			
		||||
    # So HTTP_PROXY is not used.
 | 
			
		||||
    # http_proxy is not used too if the variable is case insensitive.
 | 
			
		||||
    # CGI_HTTP_PROXY can be used instead.
 | 
			
		||||
    def find_proxy
 | 
			
		||||
      name = self.scheme.downcase + '_proxy'
 | 
			
		||||
      proxy_uri = nil
 | 
			
		||||
      if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
 | 
			
		||||
        # HTTP_PROXY conflicts with *_proxy for proxy settings and
 | 
			
		||||
        # HTTP_* for header information in CGI.
 | 
			
		||||
        # So it should be careful to use it.
 | 
			
		||||
        pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
 | 
			
		||||
        case pairs.length
 | 
			
		||||
        when 0 # no proxy setting anyway.
 | 
			
		||||
          proxy_uri = nil
 | 
			
		||||
        when 1
 | 
			
		||||
          k, v = pairs.shift
 | 
			
		||||
          if k == 'http_proxy' && ENV[k.upcase] == nil
 | 
			
		||||
            # http_proxy is safe to use because ENV is case sensitive.
 | 
			
		||||
            proxy_uri = ENV[name]
 | 
			
		||||
          else
 | 
			
		||||
            proxy_uri = nil
 | 
			
		||||
          end
 | 
			
		||||
        else # http_proxy is safe to use because ENV is case sensitive.
 | 
			
		||||
          proxy_uri = ENV[name]
 | 
			
		||||
        end
 | 
			
		||||
        if !proxy_uri
 | 
			
		||||
          # Use CGI_HTTP_PROXY.  cf. libwww-perl.
 | 
			
		||||
          proxy_uri = ENV["CGI_#{name.upcase}"]
 | 
			
		||||
        end
 | 
			
		||||
      elsif name == 'http_proxy'
 | 
			
		||||
        unless proxy_uri = ENV[name]
 | 
			
		||||
          if proxy_uri = ENV[name.upcase]
 | 
			
		||||
            warn 'The environment variable HTTP_PROXY is discouraged.  Use http_proxy.'
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        proxy_uri = ENV[name] || ENV[name.upcase]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if proxy_uri && self.host
 | 
			
		||||
        require 'socket'
 | 
			
		||||
        begin
 | 
			
		||||
          addr = IPSocket.getaddress(self.host)
 | 
			
		||||
          proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
 | 
			
		||||
        rescue SocketError
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if proxy_uri
 | 
			
		||||
        proxy_uri = URI.parse(proxy_uri)
 | 
			
		||||
        name = 'no_proxy'
 | 
			
		||||
        if no_proxy = ENV[name] || ENV[name.upcase]
 | 
			
		||||
          no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
 | 
			
		||||
            if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
 | 
			
		||||
               (!port || self.port == port.to_i)
 | 
			
		||||
              proxy_uri = nil
 | 
			
		||||
              break
 | 
			
		||||
            end
 | 
			
		||||
          }
 | 
			
		||||
        end
 | 
			
		||||
        proxy_uri
 | 
			
		||||
      else
 | 
			
		||||
        nil
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class HTTP
 | 
			
		||||
    def buffer_open(buf, proxy, options) # :nodoc:
 | 
			
		||||
      OpenURI.open_http(buf, self, proxy, options)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    include OpenURI::OpenRead
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class FTP
 | 
			
		||||
    def buffer_open(buf, proxy, options) # :nodoc:
 | 
			
		||||
      if proxy
 | 
			
		||||
        OpenURI.open_http(buf, self, proxy, options)
 | 
			
		||||
        return
 | 
			
		||||
      end
 | 
			
		||||
      require 'net/ftp'
 | 
			
		||||
 | 
			
		||||
      directories = self.path.split(%r{/}, -1)
 | 
			
		||||
      directories.shift if directories[0] == '' # strip a field before leading slash
 | 
			
		||||
      directories.each {|d|
 | 
			
		||||
        d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
 | 
			
		||||
      }
 | 
			
		||||
      unless filename = directories.pop
 | 
			
		||||
        raise ArgumentError, "no filename: #{self.inspect}"
 | 
			
		||||
      end
 | 
			
		||||
      directories.each {|d|
 | 
			
		||||
        if /[\r\n]/ =~ d
 | 
			
		||||
          raise ArgumentError, "invalid directory: #{d.inspect}"
 | 
			
		||||
        end
 | 
			
		||||
      }
 | 
			
		||||
      if /[\r\n]/ =~ filename
 | 
			
		||||
        raise ArgumentError, "invalid filename: #{filename.inspect}"
 | 
			
		||||
      end
 | 
			
		||||
      typecode = self.typecode
 | 
			
		||||
      if typecode && /\A[aid]\z/ !~ typecode
 | 
			
		||||
        raise ArgumentError, "invalid typecode: #{typecode.inspect}"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # The access sequence is defined by RFC 1738
 | 
			
		||||
      ftp = Net::FTP.open(self.host)
 | 
			
		||||
      # todo: extract user/passwd from .netrc.
 | 
			
		||||
      user = 'anonymous'
 | 
			
		||||
      passwd = nil
 | 
			
		||||
      user, passwd = self.userinfo.split(/:/) if self.userinfo
 | 
			
		||||
      ftp.login(user, passwd)
 | 
			
		||||
      directories.each {|cwd|
 | 
			
		||||
        ftp.voidcmd("CWD #{cwd}")
 | 
			
		||||
      }
 | 
			
		||||
      if typecode
 | 
			
		||||
        # xxx: typecode D is not handled.
 | 
			
		||||
        ftp.voidcmd("TYPE #{typecode.upcase}")
 | 
			
		||||
      end
 | 
			
		||||
      if options[:content_length_proc]
 | 
			
		||||
        options[:content_length_proc].call(ftp.size(filename))
 | 
			
		||||
      end
 | 
			
		||||
      ftp.retrbinary("RETR #{filename}", 4096) { |str|
 | 
			
		||||
        buf << str
 | 
			
		||||
        options[:progress_proc].call(buf.size) if options[:progress_proc]
 | 
			
		||||
      }
 | 
			
		||||
      ftp.close
 | 
			
		||||
      buf.io.rewind
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    include OpenURI::OpenRead
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
# :startdoc:
 | 
			
		||||
| 
						 | 
				
			
			@ -236,11 +236,13 @@ class Gem::RemoteFetcher
 | 
			
		|||
      request.add_field 'Keep-Alive', '30'
 | 
			
		||||
 | 
			
		||||
      # HACK work around EOFError bug in Net::HTTP
 | 
			
		||||
      # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
 | 
			
		||||
      # to install gems.
 | 
			
		||||
      retried = false
 | 
			
		||||
      begin
 | 
			
		||||
        @requests[connection_id] += 1
 | 
			
		||||
        response = connection.request(request)
 | 
			
		||||
      rescue EOFError
 | 
			
		||||
      rescue EOFError, Errno::ECONNABORTED
 | 
			
		||||
        requests = @requests[connection_id]
 | 
			
		||||
        say "connection reset after #{requests} requests, retrying" if
 | 
			
		||||
          Gem.configuration.really_verbose
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,5 +2,5 @@
 | 
			
		|||
# This file is auto-generated by build scripts.
 | 
			
		||||
# See:  rake update_version
 | 
			
		||||
module Gem
 | 
			
		||||
  RubyGemsVersion = '1.1.0'
 | 
			
		||||
  RubyGemsVersion = '1.1.1'
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ class Gem::Server
 | 
			
		|||
 | 
			
		||||
  DOC_TEMPLATE = <<-'WEBPAGE'
 | 
			
		||||
  <?xml version="1.0" encoding="iso-8859-1"?>
 | 
			
		||||
  <!DOCTYPE html 
 | 
			
		||||
  <!DOCTYPE html
 | 
			
		||||
       PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 | 
			
		||||
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ class Gem::Server
 | 
			
		|||
        <h1>Summary</h1>
 | 
			
		||||
  <p>There are <%=values["gem_count"]%> gems installed:</p>
 | 
			
		||||
  <p>
 | 
			
		||||
  <%= values["specs"].map { |v| "<a href=\"#{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>. 
 | 
			
		||||
  <%= values["specs"].map { |v| "<a href=\"##{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
 | 
			
		||||
  <h1>Gems</h1>
 | 
			
		||||
 | 
			
		||||
  <dl>
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ class Gem::Server
 | 
			
		|||
 | 
			
		||||
  	<% if  spec["has_deps"] then %>
 | 
			
		||||
  	 - depends on
 | 
			
		||||
  		<%= spec["dependencies"].map { |v| "<a href=\"#{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>. 
 | 
			
		||||
  		<%= spec["dependencies"].map { |v| "<a href=\"##{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
 | 
			
		||||
  	<% end  %>
 | 
			
		||||
  	</dt>
 | 
			
		||||
  	<dd>
 | 
			
		||||
| 
						 | 
				
			
			@ -91,8 +91,8 @@ class Gem::Server
 | 
			
		|||
  		    Executables are
 | 
			
		||||
  		<%end%>
 | 
			
		||||
 | 
			
		||||
  		<%= spec["executables"].map { |v| "<span class=\"context-item-name\">#{v["executable"]}</span>"}.join ', ' %>. 
 | 
			
		||||
  		
 | 
			
		||||
  		<%= spec["executables"].map { |v| "<span class=\"context-item-name\">#{v["executable"]}</span>"}.join ', ' %>.
 | 
			
		||||
 | 
			
		||||
  	<%end%>
 | 
			
		||||
  	<br/>
 | 
			
		||||
  	<br/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,8 @@ class Gem::SourceIndex
 | 
			
		|||
 | 
			
		||||
  include Gem::UserInteraction
 | 
			
		||||
 | 
			
		||||
  attr_reader :gems # :nodoc:
 | 
			
		||||
 | 
			
		||||
  class << self
 | 
			
		||||
    include Gem::UserInteraction
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -50,14 +52,10 @@ class Gem::SourceIndex
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    ##
 | 
			
		||||
    # Return a list of directories in the current gem path that
 | 
			
		||||
    # contain specifications.
 | 
			
		||||
    # 
 | 
			
		||||
    # return::
 | 
			
		||||
    #   List of directory paths (all ending in "../specifications").
 | 
			
		||||
    # Returns a list of directories from Gem.path that contain specifications.
 | 
			
		||||
 | 
			
		||||
    def installed_spec_directories
 | 
			
		||||
      Gem.path.collect { |dir| File.join(dir, "specifications") }        
 | 
			
		||||
      Gem.path.collect { |dir| File.join(dir, "specifications") }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    ##
 | 
			
		||||
| 
						 | 
				
			
			@ -272,12 +270,11 @@ class Gem::SourceIndex
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Refresh the source index from the local file system.
 | 
			
		||||
  #
 | 
			
		||||
  # return:: Returns a pointer to itself.
 | 
			
		||||
  # Replaces the gems in the source index from specifications in the
 | 
			
		||||
  # installed_spec_directories,
 | 
			
		||||
 | 
			
		||||
  def refresh!
 | 
			
		||||
    load_gems_in(self.class.installed_spec_directories)
 | 
			
		||||
    load_gems_in(*self.class.installed_spec_directories)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -347,10 +344,6 @@ class Gem::SourceIndex
 | 
			
		|||
    Marshal.dump(self)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
 | 
			
		||||
  attr_reader :gems
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def fetcher
 | 
			
		||||
| 
						 | 
				
			
			@ -430,15 +423,22 @@ class Gem::SourceIndex
 | 
			
		|||
  # Make a list of full names for all the missing gemspecs.
 | 
			
		||||
 | 
			
		||||
  def find_missing(spec_names)
 | 
			
		||||
    unless defined? @originals then
 | 
			
		||||
      @originals = {}
 | 
			
		||||
      each do |full_name, spec|
 | 
			
		||||
        @originals[spec.original_name] = spec
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    spec_names.find_all { |full_name|
 | 
			
		||||
      specification(full_name).nil?
 | 
			
		||||
      @originals[full_name].nil?
 | 
			
		||||
    }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def remove_extra(spec_names)
 | 
			
		||||
    dictionary = spec_names.inject({}) { |h, k| h[k] = true; h }
 | 
			
		||||
    each do |name, spec|
 | 
			
		||||
      remove_spec name unless dictionary.include? name
 | 
			
		||||
      remove_spec name unless dictionary.include? spec.original_name
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,8 +22,8 @@ require 'rubygems/user_interaction'
 | 
			
		|||
#   Gem::SourceInfoCache
 | 
			
		||||
#     @cache_data = {
 | 
			
		||||
#       source_uri => Gem::SourceInfoCacheEntry
 | 
			
		||||
#         @size => source index size
 | 
			
		||||
#         @source_index => Gem::SourceIndex
 | 
			
		||||
#         @size = source index size
 | 
			
		||||
#         @source_index = Gem::SourceIndex
 | 
			
		||||
#       ...
 | 
			
		||||
#     }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,14 +31,14 @@ class Gem::SourceInfoCache
 | 
			
		|||
 | 
			
		||||
  include Gem::UserInteraction
 | 
			
		||||
 | 
			
		||||
  @cache = nil
 | 
			
		||||
  @system_cache_file = nil
 | 
			
		||||
  @user_cache_file = nil
 | 
			
		||||
  ##
 | 
			
		||||
  # The singleton Gem::SourceInfoCache.  If +all+ is true, a full refresh will
 | 
			
		||||
  # be performed if the singleton instance is being initialized.
 | 
			
		||||
 | 
			
		||||
  def self.cache
 | 
			
		||||
  def self.cache(all = false)
 | 
			
		||||
    return @cache if @cache
 | 
			
		||||
    @cache = new
 | 
			
		||||
    @cache.refresh false if Gem.configuration.update_sources
 | 
			
		||||
    @cache.refresh all if Gem.configuration.update_sources
 | 
			
		||||
    @cache
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -62,6 +62,15 @@ class Gem::SourceInfoCache
 | 
			
		|||
              "latest_#{File.basename user_cache_file}"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Reset all singletons, discarding any changes.
 | 
			
		||||
 | 
			
		||||
  def self.reset
 | 
			
		||||
    @cache = nil
 | 
			
		||||
    @system_cache_file = nil
 | 
			
		||||
    @user_cache_file = nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Search all source indexes.  See Gem::SourceInfoCache#search.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -122,13 +131,6 @@ class Gem::SourceInfoCache
 | 
			
		|||
      try_file(user_cache_file) or
 | 
			
		||||
      raise "unable to locate a writable cache file")
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  ##
 | 
			
		||||
  # Force cache file to be reset, useful for integration testing of rubygems
 | 
			
		||||
  
 | 
			
		||||
  def reset_cache_file
 | 
			
		||||
    @cache_file = nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Write the cache to a local file (if it is dirty).
 | 
			
		||||
| 
						 | 
				
			
			@ -175,13 +177,30 @@ class Gem::SourceInfoCache
 | 
			
		|||
    self.class.latest_user_cache_file
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Merges the complete cache file into this Gem::SourceInfoCache.
 | 
			
		||||
 | 
			
		||||
  def read_all_cache_data
 | 
			
		||||
    if @only_latest then
 | 
			
		||||
      @only_latest = false
 | 
			
		||||
      @cache_data = read_cache_data cache_file
 | 
			
		||||
      all_data = read_cache_data cache_file
 | 
			
		||||
 | 
			
		||||
      cache_data.update all_data do |source_uri, latest_sice, all_sice|
 | 
			
		||||
        all_sice.source_index.gems.update latest_sice.source_index.gems
 | 
			
		||||
 | 
			
		||||
        Gem::SourceInfoCacheEntry.new all_sice.source_index, latest_sice.size
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      begin
 | 
			
		||||
        refresh true
 | 
			
		||||
      rescue Gem::RemoteFetcher::FetchError
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Reads cached data from +file+.
 | 
			
		||||
 | 
			
		||||
  def read_cache_data(file)
 | 
			
		||||
    # Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small
 | 
			
		||||
    data = open file, 'rb' do |fp| fp.read end
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +222,8 @@ class Gem::SourceInfoCache
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    cache_data
 | 
			
		||||
  rescue Errno::ENOENT
 | 
			
		||||
    {}
 | 
			
		||||
  rescue => e
 | 
			
		||||
    if Gem.configuration.really_verbose then
 | 
			
		||||
      say "Exception during cache_data handling: #{e.class} - #{e}"
 | 
			
		||||
| 
						 | 
				
			
			@ -243,6 +264,14 @@ class Gem::SourceInfoCache
 | 
			
		|||
 | 
			
		||||
  def reset_cache_data
 | 
			
		||||
    @cache_data = nil
 | 
			
		||||
    @only_latest = true
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Force cache file to be reset, useful for integration testing of rubygems
 | 
			
		||||
 | 
			
		||||
  def reset_cache_file
 | 
			
		||||
    @cache_file = nil
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
| 
						 | 
				
			
			@ -315,10 +344,7 @@ class Gem::SourceInfoCache
 | 
			
		|||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if File.writable? dir then
 | 
			
		||||
      open path, "wb" do |io| io.write Marshal.dump({}) end
 | 
			
		||||
      return path
 | 
			
		||||
    end
 | 
			
		||||
    return path if File.writable? dir
 | 
			
		||||
 | 
			
		||||
    nil
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -338,11 +364,13 @@ class Gem::SourceInfoCache
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  ##
 | 
			
		||||
  # Write data to the proper cache.
 | 
			
		||||
  # Write data to the proper cache files.
 | 
			
		||||
 | 
			
		||||
  def write_cache
 | 
			
		||||
    open cache_file, 'wb' do |io|
 | 
			
		||||
      io.write Marshal.dump(cache_data)
 | 
			
		||||
    if not File.exist?(cache_file) or not @only_latest then
 | 
			
		||||
      open cache_file, 'wb' do |io|
 | 
			
		||||
        io.write Marshal.dump(cache_data)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    open latest_cache_file, 'wb' do |io|
 | 
			
		||||
| 
						 | 
				
			
			@ -350,5 +378,7 @@ class Gem::SourceInfoCache
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  reset
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,8 +23,7 @@ module Gem::VersionOption
 | 
			
		|||
               "Specify the platform of gem to #{task}", *wrap) do
 | 
			
		||||
                 |value, options|
 | 
			
		||||
      unless options[:added_platform] then
 | 
			
		||||
        Gem.platforms.clear
 | 
			
		||||
        Gem.platforms << Gem::Platform::RUBY
 | 
			
		||||
        Gem.platforms = [Gem::Platform::RUBY]
 | 
			
		||||
        options[:added_platform] = true
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,6 +61,8 @@ class FakeFetcher
 | 
			
		|||
    name = "#{spec.full_name}.gem"
 | 
			
		||||
    path = File.join(install_dir, 'cache', name)
 | 
			
		||||
 | 
			
		||||
    Gem.ensure_gem_subdirectories install_dir
 | 
			
		||||
 | 
			
		||||
    if source_uri =~ /^http/ then
 | 
			
		||||
      File.open(path, "wb") do |f|
 | 
			
		||||
        f.write fetch_path(File.join(source_uri, "gems", name))
 | 
			
		||||
| 
						 | 
				
			
			@ -369,6 +371,17 @@ class RubyGemTestCase < Test::Unit::TestCase
 | 
			
		|||
    Gem.win_platform?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # NOTE Allow tests to use a random (but controlled) port number instead of
 | 
			
		||||
  # a hardcoded one. This helps CI tools when running parallels builds on
 | 
			
		||||
  # the same builder slave.
 | 
			
		||||
  def self.process_based_port
 | 
			
		||||
    @@process_based_port ||= 8000 + $$ % 1000
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def process_based_port
 | 
			
		||||
    self.class.process_based_port
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class TempIO
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -237,23 +237,25 @@ class TestGem < RubyGemTestCase
 | 
			
		|||
    assert_equal [Gem.dir], Gem.path
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_path_APPLE_GEM_HOME
 | 
			
		||||
    Gem.clear_paths
 | 
			
		||||
    Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home'
 | 
			
		||||
 | 
			
		||||
    assert Gem.path.include?('/tmp/apple_gem_home')
 | 
			
		||||
  ensure
 | 
			
		||||
    Gem.send :remove_const, :APPLE_GEM_HOME
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_path_APPLE_GEM_HOME_GEM_PATH
 | 
			
		||||
    Gem.clear_paths
 | 
			
		||||
    ENV['GEM_PATH'] = @gemhome
 | 
			
		||||
    Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home'
 | 
			
		||||
 | 
			
		||||
    assert !Gem.path.include?('/tmp/apple_gem_home')
 | 
			
		||||
  ensure
 | 
			
		||||
    Gem.send :remove_const, :APPLE_GEM_HOME
 | 
			
		||||
  unless win_platform?
 | 
			
		||||
    def test_self_path_APPLE_GEM_HOME
 | 
			
		||||
      Gem.clear_paths
 | 
			
		||||
      Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home'
 | 
			
		||||
  
 | 
			
		||||
      assert Gem.path.include?('/tmp/apple_gem_home')
 | 
			
		||||
    ensure
 | 
			
		||||
      Gem.send :remove_const, :APPLE_GEM_HOME
 | 
			
		||||
    end
 | 
			
		||||
  
 | 
			
		||||
    def test_self_path_APPLE_GEM_HOME_GEM_PATH
 | 
			
		||||
      Gem.clear_paths
 | 
			
		||||
      ENV['GEM_PATH'] = @gemhome
 | 
			
		||||
      Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home'
 | 
			
		||||
  
 | 
			
		||||
      assert !Gem.path.include?('/tmp/apple_gem_home')
 | 
			
		||||
    ensure
 | 
			
		||||
      Gem.send :remove_const, :APPLE_GEM_HOME
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_path_ENV_PATH
 | 
			
		||||
| 
						 | 
				
			
			@ -303,21 +305,56 @@ class TestGem < RubyGemTestCase
 | 
			
		|||
 | 
			
		||||
  def test_self_prefix
 | 
			
		||||
    file_name = File.expand_path __FILE__
 | 
			
		||||
    assert_equal File.dirname(File.dirname(file_name)), Gem.prefix
 | 
			
		||||
 | 
			
		||||
    prefix = File.dirname File.dirname(file_name)
 | 
			
		||||
    prefix = File.dirname prefix if File.basename(prefix) == 'test'
 | 
			
		||||
 | 
			
		||||
    assert_equal prefix, Gem.prefix
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_prefix_odd
 | 
			
		||||
  def test_self_prefix_libdir
 | 
			
		||||
    orig_libdir = Gem::ConfigMap[:libdir]
 | 
			
		||||
 | 
			
		||||
    file_name = File.expand_path __FILE__
 | 
			
		||||
    prefix = File.dirname File.dirname(file_name)
 | 
			
		||||
 | 
			
		||||
    Gem::ConfigMap[:libdir] = prefix
 | 
			
		||||
 | 
			
		||||
    assert_nil Gem.prefix
 | 
			
		||||
  ensure
 | 
			
		||||
    Gem::ConfigMap[:libdir] = orig_libdir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_prefix_sitelibdir
 | 
			
		||||
    orig_sitelibdir = Gem::ConfigMap[:sitelibdir]
 | 
			
		||||
 | 
			
		||||
    file_name = File.expand_path __FILE__
 | 
			
		||||
    prefix = File.join File.dirname(File.dirname(file_name)), 'lib'
 | 
			
		||||
    Gem::ConfigMap[:sitelibdir] = prefix.sub(/[\w]\//, '\&/')
 | 
			
		||||
    prefix = File.dirname File.dirname(file_name)
 | 
			
		||||
 | 
			
		||||
    Gem::ConfigMap[:sitelibdir] = prefix
 | 
			
		||||
 | 
			
		||||
    assert_nil Gem.prefix
 | 
			
		||||
  ensure
 | 
			
		||||
    Gem::ConfigMap[:sitelibdir] = orig_sitelibdir
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_refresh
 | 
			
		||||
    util_make_gems
 | 
			
		||||
 | 
			
		||||
    a1_spec = File.join @gemhome, "specifications", "#{@a1.full_name}.gemspec" 
 | 
			
		||||
 | 
			
		||||
    FileUtils.mv a1_spec, @tempdir
 | 
			
		||||
 | 
			
		||||
    assert !Gem.source_index.gems.include?(@a1.full_name)
 | 
			
		||||
 | 
			
		||||
    FileUtils.mv File.join(@tempdir, "#{@a1.full_name}.gemspec"), a1_spec
 | 
			
		||||
 | 
			
		||||
    Gem.refresh
 | 
			
		||||
 | 
			
		||||
    assert Gem.source_index.gems.include?(@a1.full_name)
 | 
			
		||||
    assert_equal nil, Gem.instance_variable_get(:@searcher)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_self_required_location
 | 
			
		||||
    util_make_gems
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ class TestGemCommandsEnvironmentCommand < RubyGemTestCase
 | 
			
		|||
      @cmd.execute
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assert_match %r|RUBYGEMS VERSION: (\d\.)+\d \((\d\.)+\d\)|, @ui.output
 | 
			
		||||
    assert_match %r|RUBYGEMS VERSION: (\d\.)+\d|, @ui.output
 | 
			
		||||
    assert_match %r|RUBY VERSION: \d\.\d\.\d \(.*\) \[.*\]|, @ui.output
 | 
			
		||||
    assert_match %r|INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}|,
 | 
			
		||||
                 @ui.output
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,7 @@ class TestGemCommandsQueryCommand < RubyGemTestCase
 | 
			
		|||
    cache.update
 | 
			
		||||
    cache.write_cache
 | 
			
		||||
    cache.reset_cache_data
 | 
			
		||||
    Gem::SourceInfoCache.reset
 | 
			
		||||
 | 
			
		||||
    a2_name = @a2.full_name
 | 
			
		||||
    @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = util_zip a2_name
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +44,9 @@ class TestGemCommandsQueryCommand < RubyGemTestCase
 | 
			
		|||
 | 
			
		||||
*** REMOTE GEMS ***
 | 
			
		||||
 | 
			
		||||
Updating metadata for 1 gems from http://gems.example.com/
 | 
			
		||||
.
 | 
			
		||||
complete
 | 
			
		||||
a (2)
 | 
			
		||||
    EOF
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +59,7 @@ a (2)
 | 
			
		|||
    cache.update
 | 
			
		||||
    cache.write_cache
 | 
			
		||||
    cache.reset_cache_data
 | 
			
		||||
    Gem::SourceInfoCache.reset
 | 
			
		||||
 | 
			
		||||
    a1_name = @a1.full_name
 | 
			
		||||
    a2_name = @a2.full_name
 | 
			
		||||
| 
						 | 
				
			
			@ -76,8 +81,8 @@ a (2)
 | 
			
		|||
 | 
			
		||||
*** REMOTE GEMS ***
 | 
			
		||||
 | 
			
		||||
Updating metadata for 1 gems from http://gems.example.com/
 | 
			
		||||
.
 | 
			
		||||
Updating metadata for 2 gems from http://gems.example.com/
 | 
			
		||||
..
 | 
			
		||||
complete
 | 
			
		||||
a (2, 1)
 | 
			
		||||
    EOF
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +102,7 @@ a (2, 1)
 | 
			
		|||
 | 
			
		||||
*** REMOTE GEMS ***
 | 
			
		||||
 | 
			
		||||
a (2, 1)
 | 
			
		||||
a (2)
 | 
			
		||||
    This is a lot of text. This is a lot of text. This is a lot of text.
 | 
			
		||||
    This is a lot of text.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -181,6 +181,8 @@ beta-gems.example.com is not a URI
 | 
			
		|||
    @cmd.handle_options %w[--update]
 | 
			
		||||
 | 
			
		||||
    util_setup_source_info_cache
 | 
			
		||||
    Gem::SourceInfoCache.reset
 | 
			
		||||
 | 
			
		||||
    util_setup_fake_fetcher
 | 
			
		||||
    si = Gem::SourceIndex.new
 | 
			
		||||
    si.add_spec @a1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,6 +97,7 @@ class TestGemCommandsUpdateCommand < RubyGemTestCase
 | 
			
		|||
    assert_equal "Updating installed gems", out.shift
 | 
			
		||||
    assert_match %r|Bulk updating|, out.shift
 | 
			
		||||
    assert_equal "Updating #{@a2.name}", out.shift
 | 
			
		||||
    assert_match %r|Bulk updating|, out.shift
 | 
			
		||||
    assert_equal "Successfully installed #{@c2.full_name}", out.shift
 | 
			
		||||
    assert_equal "Successfully installed #{@b2.full_name}", out.shift
 | 
			
		||||
    assert_equal "Successfully installed #{@a2.full_name}", out.shift
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -216,6 +216,8 @@ class TestGemDependencyInstaller < RubyGemTestCase
 | 
			
		|||
 | 
			
		||||
    assert File.exist?(File.join(gemhome2, 'specifications',
 | 
			
		||||
                                 "#{@a1.full_name}.gemspec"))
 | 
			
		||||
    assert File.exist?(File.join(gemhome2, 'cache',
 | 
			
		||||
                                 "#{@a1.full_name}.gem"))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_install_domain_both
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,8 +76,9 @@ gems:
 | 
			
		|||
 | 
			
		||||
  # don't let 1.8 and 1.9 autotest collide
 | 
			
		||||
  RUBY_VERSION =~ /(\d+)\.(\d+)\.(\d+)/
 | 
			
		||||
  PROXY_PORT = 12345 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
 | 
			
		||||
  SERVER_PORT = 23456 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
 | 
			
		||||
  # don't let parallel runners collide
 | 
			
		||||
  PROXY_PORT = process_based_port + 100 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
 | 
			
		||||
  SERVER_PORT = process_based_port + 200 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i
 | 
			
		||||
 | 
			
		||||
  def setup
 | 
			
		||||
    super
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ class TestGemServer < RubyGemTestCase
 | 
			
		|||
 | 
			
		||||
    @a1 = quick_gem 'a', '1'
 | 
			
		||||
 | 
			
		||||
    @server = Gem::Server.new Gem.dir, 8809, false
 | 
			
		||||
    @server = Gem::Server.new Gem.dir, process_based_port, false
 | 
			
		||||
    @req = WEBrick::HTTPRequest.new :Logger => nil
 | 
			
		||||
    @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -395,13 +395,31 @@ class TestGemSourceIndex < RubyGemTestCase
 | 
			
		|||
    assert_equal [updated_platform.name], @source_index.outdated
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_refresh_bang
 | 
			
		||||
    a1_spec = File.join @gemhome, "specifications", "#{@a1.full_name}.gemspec" 
 | 
			
		||||
 | 
			
		||||
    FileUtils.mv a1_spec, @tempdir
 | 
			
		||||
 | 
			
		||||
    source_index = Gem::SourceIndex.from_installed_gems
 | 
			
		||||
 | 
			
		||||
    assert !source_index.gems.include?(@a1.full_name)
 | 
			
		||||
 | 
			
		||||
    FileUtils.mv File.join(@tempdir, "#{@a1.full_name}.gemspec"), a1_spec
 | 
			
		||||
 | 
			
		||||
    source_index.refresh!
 | 
			
		||||
 | 
			
		||||
    assert source_index.gems.include?(@a1.full_name)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_remove_extra
 | 
			
		||||
    @source_index.add_spec @a1
 | 
			
		||||
    @source_index.add_spec @a2
 | 
			
		||||
    @source_index.add_spec @pl1
 | 
			
		||||
 | 
			
		||||
    @source_index.remove_extra [@a1.full_name]
 | 
			
		||||
    @source_index.remove_extra [@a1.full_name, @pl1.full_name]
 | 
			
		||||
 | 
			
		||||
    assert_equal [@a1.full_name], @source_index.gems.map { |n,s| n }
 | 
			
		||||
    assert_equal [@a1.full_name],
 | 
			
		||||
                 @source_index.gems.map { |n,s| n }.sort
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_remove_extra_no_changes
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -287,6 +287,7 @@ class TestGemSourceInfoCache < RubyGemTestCase
 | 
			
		|||
 | 
			
		||||
    @sic.set_cache_data @gem_repo => sice
 | 
			
		||||
    @sic.update
 | 
			
		||||
    @sic.instance_variable_set :@only_latest, false
 | 
			
		||||
    @sic.write_cache
 | 
			
		||||
    @sic.reset_cache_data
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -358,6 +359,7 @@ class TestGemSourceInfoCache < RubyGemTestCase
 | 
			
		|||
    @sic.set_cache_data({@gem_repo => @sice_new})
 | 
			
		||||
    @sic.update
 | 
			
		||||
    @sic.write_cache
 | 
			
		||||
    @sic.instance_variable_set :@only_latest, false
 | 
			
		||||
 | 
			
		||||
    assert File.exist?(@sic.user_cache_file), 'user_cache_file'
 | 
			
		||||
    assert File.exist?(@sic.latest_user_cache_file),
 | 
			
		||||
| 
						 | 
				
			
			@ -383,6 +385,7 @@ class TestGemSourceInfoCache < RubyGemTestCase
 | 
			
		|||
 | 
			
		||||
    @sic.set_cache_data({ @gem_repo => @sice })
 | 
			
		||||
    @sic.update
 | 
			
		||||
 | 
			
		||||
    @sic.write_cache
 | 
			
		||||
 | 
			
		||||
    assert File.exist?(@sic.user_cache_file), 'system_cache_file'
 | 
			
		||||
| 
						 | 
				
			
			@ -390,7 +393,7 @@ class TestGemSourceInfoCache < RubyGemTestCase
 | 
			
		|||
           'latest_system_cache_file'
 | 
			
		||||
 | 
			
		||||
    user_cache_data = read_cache(@sic.user_cache_file).to_a.sort
 | 
			
		||||
    assert_equal 1, user_cache_data.length
 | 
			
		||||
    assert_equal 1, user_cache_data.length, 'user_cache_data length'
 | 
			
		||||
    user_cache_data = user_cache_data.first
 | 
			
		||||
 | 
			
		||||
    assert_equal @gem_repo, user_cache_data.first
 | 
			
		||||
| 
						 | 
				
			
			@ -415,6 +418,24 @@ class TestGemSourceInfoCache < RubyGemTestCase
 | 
			
		|||
    @sic.update
 | 
			
		||||
    @sic.write_cache
 | 
			
		||||
 | 
			
		||||
    assert_equal [[@gem_repo, @sys_sice]],
 | 
			
		||||
                 read_cache(@sic.system_cache_file).to_a.sort
 | 
			
		||||
    assert_equal [[@gem_repo, @sys_sice]],
 | 
			
		||||
                 read_cache(@sic.user_cache_file).to_a.sort
 | 
			
		||||
    assert_equal [[@gem_repo, @sice_new]],
 | 
			
		||||
                 read_cache(@sic.latest_user_cache_file).to_a.sort
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_write_cache_user_only_latest
 | 
			
		||||
    FileUtils.chmod 0444, @sic.system_cache_file
 | 
			
		||||
    @sic.set_cache_data({@gem_repo => @sice_new})
 | 
			
		||||
    @sic.update
 | 
			
		||||
    @sic.write_cache
 | 
			
		||||
 | 
			
		||||
    assert File.exist?(@sic.user_cache_file), 'user_cache_file'
 | 
			
		||||
    assert File.exist?(@sic.latest_user_cache_file),
 | 
			
		||||
           'latest_user_cache_file exists'
 | 
			
		||||
 | 
			
		||||
    assert_equal [[@gem_repo, @sys_sice]],
 | 
			
		||||
                 read_cache(@sic.system_cache_file).to_a.sort
 | 
			
		||||
    assert_equal [[@gem_repo, @sice_new]],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +0,0 @@
 | 
			
		|||
require 'test/unit'
 | 
			
		||||
require 'rubygems/gem_open_uri'
 | 
			
		||||
 | 
			
		||||
class TestOpenURI < Test::Unit::TestCase
 | 
			
		||||
 | 
			
		||||
  def test_open_uri_not_broken
 | 
			
		||||
    assert_nothing_raised do
 | 
			
		||||
      open __FILE__ do end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue