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> | Sat Apr 12 03:13:38 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org> | ||||||
| 
 | 
 | ||||||
| 	* file.c (file_expand_path): set external encoding. | 	* file.c (file_expand_path): set external encoding. | ||||||
|  |  | ||||||
|  | @ -97,7 +97,7 @@ module Gem | ||||||
| 
 | 
 | ||||||
|   @configuration = nil |   @configuration = nil | ||||||
|   @loaded_specs = {} |   @loaded_specs = {} | ||||||
|   @platforms = nil |   @platforms = [] | ||||||
|   @ruby = nil |   @ruby = nil | ||||||
|   @sources = [] |   @sources = [] | ||||||
| 
 | 
 | ||||||
|  | @ -215,7 +215,7 @@ module Gem | ||||||
| 
 | 
 | ||||||
|   def self.bindir(install_dir=Gem.dir) |   def self.bindir(install_dir=Gem.dir) | ||||||
|     return File.join(install_dir, 'bin') unless |     return File.join(install_dir, 'bin') unless | ||||||
|     install_dir.to_s == Gem.default_dir |       install_dir.to_s == Gem.default_dir | ||||||
|     Gem.default_bindir |     Gem.default_bindir | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  | @ -451,10 +451,21 @@ module Gem | ||||||
|   end |   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 |   def self.platforms | ||||||
|     @platforms ||= [Gem::Platform::RUBY, Gem::Platform.local] |     @platforms ||= [] | ||||||
|  |     if @platforms.empty? | ||||||
|  |       @platforms = [Gem::Platform::RUBY, Gem::Platform.local] | ||||||
|  |     end | ||||||
|  |     @platforms | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   ## |   ## | ||||||
|  | @ -463,13 +474,26 @@ module Gem | ||||||
|   def self.prefix |   def self.prefix | ||||||
|     prefix = File.dirname File.expand_path(__FILE__) |     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 |       nil | ||||||
|     else |     else | ||||||
|       File.dirname prefix |       File.dirname prefix | ||||||
|     end |     end | ||||||
|   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. |   # Safely read a file in binary mode on all platforms. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -93,7 +93,7 @@ module Gem | ||||||
|         say Gem::Command::HELP |         say Gem::Command::HELP | ||||||
|         terminate_interaction(0) |         terminate_interaction(0) | ||||||
|       when '-v', '--version' |       when '-v', '--version' | ||||||
|         say Gem::RubyGemsPackageVersion |         say Gem::RubyGemsVersion | ||||||
|         terminate_interaction(0) |         terminate_interaction(0) | ||||||
|       when /^-/ |       when /^-/ | ||||||
|         alert_error "Invalid option: #{args[0]}.  See 'gem --help'." |         alert_error "Invalid option: #{args[0]}.  See 'gem --help'." | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ class Gem::Commands::EnvironmentCommand < Gem::Command | ||||||
|     when nil then |     when nil then | ||||||
|       out = "RubyGems Environment:\n" |       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 << "  - RUBY VERSION: #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}" | ||||||
|       out << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL |       out << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL | ||||||
|  |  | ||||||
|  | @ -126,6 +126,7 @@ revert the gem. | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       installer.generate_bin |       installer.generate_bin | ||||||
|  |       installer.build_extensions | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -82,13 +82,15 @@ class Gem::Commands::QueryCommand < Gem::Command | ||||||
|       say "*** REMOTE GEMS ***" |       say "*** REMOTE GEMS ***" | ||||||
|       say |       say | ||||||
| 
 | 
 | ||||||
|  |       all = options[:all] | ||||||
|  | 
 | ||||||
|       begin |       begin | ||||||
|         Gem::SourceInfoCache.cache.refresh options[:all] |         Gem::SourceInfoCache.cache all | ||||||
|       rescue Gem::RemoteFetcher::FetchError |       rescue Gem::RemoteFetcher::FetchError | ||||||
|         # no network |         # no network | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       output_query_results Gem::SourceInfoCache.search(name, false, true) |       output_query_results Gem::SourceInfoCache.search(name, false, all) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -69,7 +69,7 @@ class Gem::Commands::SourcesCommand < Gem::Command | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     if options[:update] then |     if options[:update] then | ||||||
|       Gem::SourceInfoCache.cache.refresh true |       Gem::SourceInfoCache.cache true | ||||||
|       Gem::SourceInfoCache.cache.flush |       Gem::SourceInfoCache.cache.flush | ||||||
| 
 | 
 | ||||||
|       say "source cache successfully updated" |       say "source cache successfully updated" | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ class Gem::Commands::UpdateCommand < Gem::Command | ||||||
|       say "Updating installed gems" |       say "Updating installed gems" | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     hig = {} |     hig = {} # highest installed gems | ||||||
| 
 | 
 | ||||||
|     Gem::SourceIndex.from_installed_gems.each do |name, spec| |     Gem::SourceIndex.from_installed_gems.each do |name, spec| | ||||||
|       if hig[spec.name].nil? or hig[spec.name].version < spec.version then |       if hig[spec.name].nil? or hig[spec.name].version < spec.version then | ||||||
|  | @ -67,7 +67,7 @@ class Gem::Commands::UpdateCommand < Gem::Command | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     pattern = if options[:args].empty? then |     pattern = if options[:args].empty? then | ||||||
|              // |                 // | ||||||
|               else |               else | ||||||
|                 Regexp.union(*options[:args]) |                 Regexp.union(*options[:args]) | ||||||
|               end |               end | ||||||
|  | @ -78,12 +78,14 @@ class Gem::Commands::UpdateCommand < Gem::Command | ||||||
| 
 | 
 | ||||||
|     updated = [] |     updated = [] | ||||||
| 
 | 
 | ||||||
|     # HACK use the real API |     installer = Gem::DependencyInstaller.new options | ||||||
|  | 
 | ||||||
|     gems_to_update.uniq.sort.each do |name| |     gems_to_update.uniq.sort.each do |name| | ||||||
|       next if updated.any? { |spec| spec.name == name } |       next if updated.any? { |spec| spec.name == name } | ||||||
|  | 
 | ||||||
|       say "Updating #{name}" |       say "Updating #{name}" | ||||||
|       installer = Gem::DependencyInstaller.new options |  | ||||||
|       installer.install name |       installer.install name | ||||||
|  | 
 | ||||||
|       installer.installed_gems.each do |spec| |       installer.installed_gems.each do |spec| | ||||||
|         updated << spec |         updated << spec | ||||||
|         say "Successfully installed #{spec.full_name}" |         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.push '--prefix', Gem.prefix unless Gem.prefix.nil? | ||||||
|     args << '--no-rdoc' unless options[:generate_rdoc] |     args << '--no-rdoc' unless options[:generate_rdoc] | ||||||
|     args << '--no-ri' unless options[:generate_ri] |     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}" |     update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -72,7 +72,7 @@ class Gem::DependencyInstaller | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         all = requirements.length > 1 || |         all = requirements.length > 1 || | ||||||
|                 requirements.first != ">=" || requirements.first != ">" |                 (requirements.first != ">=" and requirements.first != ">") | ||||||
| 
 | 
 | ||||||
|         found = Gem::SourceInfoCache.search_with_source dep, true, all |         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 |       say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose | ||||||
| 
 | 
 | ||||||
|       _, source_uri = @specs_and_sources.assoc spec |       _, 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, |       inst = Gem::Installer.new local_gem_path, | ||||||
|                                 :env_shebang => @env_shebang, |                                 :env_shebang => @env_shebang, | ||||||
|  |  | ||||||
|  | @ -64,6 +64,12 @@ module Gem | ||||||
| 
 | 
 | ||||||
|       FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir) |       FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir) | ||||||
| 
 | 
 | ||||||
|  |       begin | ||||||
|  |         gem 'rdoc' | ||||||
|  |       rescue Gem::LoadError | ||||||
|  |         # use built-in RDoc | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|       begin |       begin | ||||||
|         require 'rdoc/rdoc' |         require 'rdoc/rdoc' | ||||||
|       rescue LoadError => e |       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 |                 progress.updated spec.original_name | ||||||
| 
 | 
 | ||||||
|               rescue SignalException => e |               rescue SignalException => e | ||||||
|                 alert_error "Recieved signal, exiting" |                 alert_error "Received signal, exiting" | ||||||
|                 raise |                 raise | ||||||
|               rescue Exception => e |               rescue Exception => e | ||||||
|                 alert_error "Unable to process #{gemfile}\n#{e.message} (#{e.class})\n\t#{e.backtrace.join "\n\t"}" |                 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' |       request.add_field 'Keep-Alive', '30' | ||||||
| 
 | 
 | ||||||
|       # HACK work around EOFError bug in Net::HTTP |       # HACK work around EOFError bug in Net::HTTP | ||||||
|  |       # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible | ||||||
|  |       # to install gems. | ||||||
|       retried = false |       retried = false | ||||||
|       begin |       begin | ||||||
|         @requests[connection_id] += 1 |         @requests[connection_id] += 1 | ||||||
|         response = connection.request(request) |         response = connection.request(request) | ||||||
|       rescue EOFError |       rescue EOFError, Errno::ECONNABORTED | ||||||
|         requests = @requests[connection_id] |         requests = @requests[connection_id] | ||||||
|         say "connection reset after #{requests} requests, retrying" if |         say "connection reset after #{requests} requests, retrying" if | ||||||
|           Gem.configuration.really_verbose |           Gem.configuration.really_verbose | ||||||
|  |  | ||||||
|  | @ -2,5 +2,5 @@ | ||||||
| # This file is auto-generated by build scripts. | # This file is auto-generated by build scripts. | ||||||
| # See:  rake update_version | # See:  rake update_version | ||||||
| module Gem | module Gem | ||||||
|   RubyGemsVersion = '1.1.0' |   RubyGemsVersion = '1.1.1' | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ class Gem::Server | ||||||
| 
 | 
 | ||||||
|   DOC_TEMPLATE = <<-'WEBPAGE' |   DOC_TEMPLATE = <<-'WEBPAGE' | ||||||
|   <?xml version="1.0" encoding="iso-8859-1"?> |   <?xml version="1.0" encoding="iso-8859-1"?> | ||||||
|   <!DOCTYPE html  |   <!DOCTYPE html | ||||||
|        PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |        PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||||
|        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||||
| 
 | 
 | ||||||
|  | @ -51,7 +51,7 @@ class Gem::Server | ||||||
|         <h1>Summary</h1> |         <h1>Summary</h1> | ||||||
|   <p>There are <%=values["gem_count"]%> gems installed:</p> |   <p>There are <%=values["gem_count"]%> gems installed:</p> | ||||||
|   <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> |   <h1>Gems</h1> | ||||||
| 
 | 
 | ||||||
|   <dl> |   <dl> | ||||||
|  | @ -77,7 +77,7 @@ class Gem::Server | ||||||
| 
 | 
 | ||||||
|   	<% if  spec["has_deps"] then %> |   	<% if  spec["has_deps"] then %> | ||||||
|   	 - depends on |   	 - 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  %> |   	<% end  %> | ||||||
|   	</dt> |   	</dt> | ||||||
|   	<dd> |   	<dd> | ||||||
|  | @ -91,8 +91,8 @@ class Gem::Server | ||||||
|   		    Executables are |   		    Executables are | ||||||
|   		<%end%> |   		<%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%> |   	<%end%> | ||||||
|   	<br/> |   	<br/> | ||||||
|   	<br/> |   	<br/> | ||||||
|  |  | ||||||
|  | @ -25,6 +25,8 @@ class Gem::SourceIndex | ||||||
| 
 | 
 | ||||||
|   include Gem::UserInteraction |   include Gem::UserInteraction | ||||||
| 
 | 
 | ||||||
|  |   attr_reader :gems # :nodoc: | ||||||
|  | 
 | ||||||
|   class << self |   class << self | ||||||
|     include Gem::UserInteraction |     include Gem::UserInteraction | ||||||
| 
 | 
 | ||||||
|  | @ -50,14 +52,10 @@ class Gem::SourceIndex | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     ## |     ## | ||||||
|     # Return a list of directories in the current gem path that |     # Returns a list of directories from Gem.path that contain specifications. | ||||||
|     # contain specifications. |  | ||||||
|     #  |  | ||||||
|     # return:: |  | ||||||
|     #   List of directory paths (all ending in "../specifications"). |  | ||||||
| 
 | 
 | ||||||
|     def installed_spec_directories |     def installed_spec_directories | ||||||
|       Gem.path.collect { |dir| File.join(dir, "specifications") }         |       Gem.path.collect { |dir| File.join(dir, "specifications") } | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     ## |     ## | ||||||
|  | @ -272,12 +270,11 @@ class Gem::SourceIndex | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   ## |   ## | ||||||
|   # Refresh the source index from the local file system. |   # Replaces the gems in the source index from specifications in the | ||||||
|   # |   # installed_spec_directories, | ||||||
|   # return:: Returns a pointer to itself. |  | ||||||
| 
 | 
 | ||||||
|   def refresh! |   def refresh! | ||||||
|     load_gems_in(self.class.installed_spec_directories) |     load_gems_in(*self.class.installed_spec_directories) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   ## |   ## | ||||||
|  | @ -347,10 +344,6 @@ class Gem::SourceIndex | ||||||
|     Marshal.dump(self) |     Marshal.dump(self) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   protected |  | ||||||
| 
 |  | ||||||
|   attr_reader :gems |  | ||||||
| 
 |  | ||||||
|   private |   private | ||||||
| 
 | 
 | ||||||
|   def fetcher |   def fetcher | ||||||
|  | @ -430,15 +423,22 @@ class Gem::SourceIndex | ||||||
|   # Make a list of full names for all the missing gemspecs. |   # Make a list of full names for all the missing gemspecs. | ||||||
| 
 | 
 | ||||||
|   def find_missing(spec_names) |   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| |     spec_names.find_all { |full_name| | ||||||
|       specification(full_name).nil? |       @originals[full_name].nil? | ||||||
|     } |     } | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def remove_extra(spec_names) |   def remove_extra(spec_names) | ||||||
|     dictionary = spec_names.inject({}) { |h, k| h[k] = true; h } |     dictionary = spec_names.inject({}) { |h, k| h[k] = true; h } | ||||||
|     each do |name, spec| |     each do |name, spec| | ||||||
|       remove_spec name unless dictionary.include? name |       remove_spec name unless dictionary.include? spec.original_name | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,8 +22,8 @@ require 'rubygems/user_interaction' | ||||||
| #   Gem::SourceInfoCache | #   Gem::SourceInfoCache | ||||||
| #     @cache_data = { | #     @cache_data = { | ||||||
| #       source_uri => Gem::SourceInfoCacheEntry | #       source_uri => Gem::SourceInfoCacheEntry | ||||||
| #         @size => source index size | #         @size = source index size | ||||||
| #         @source_index => Gem::SourceIndex | #         @source_index = Gem::SourceIndex | ||||||
| #       ... | #       ... | ||||||
| #     } | #     } | ||||||
| 
 | 
 | ||||||
|  | @ -31,14 +31,14 @@ class Gem::SourceInfoCache | ||||||
| 
 | 
 | ||||||
|   include Gem::UserInteraction |   include Gem::UserInteraction | ||||||
| 
 | 
 | ||||||
|   @cache = nil |   ## | ||||||
|   @system_cache_file = nil |   # The singleton Gem::SourceInfoCache.  If +all+ is true, a full refresh will | ||||||
|   @user_cache_file = nil |   # be performed if the singleton instance is being initialized. | ||||||
| 
 | 
 | ||||||
|   def self.cache |   def self.cache(all = false) | ||||||
|     return @cache if @cache |     return @cache if @cache | ||||||
|     @cache = new |     @cache = new | ||||||
|     @cache.refresh false if Gem.configuration.update_sources |     @cache.refresh all if Gem.configuration.update_sources | ||||||
|     @cache |     @cache | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  | @ -62,6 +62,15 @@ class Gem::SourceInfoCache | ||||||
|               "latest_#{File.basename user_cache_file}" |               "latest_#{File.basename user_cache_file}" | ||||||
|   end |   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. |   # Search all source indexes.  See Gem::SourceInfoCache#search. | ||||||
| 
 | 
 | ||||||
|  | @ -122,13 +131,6 @@ class Gem::SourceInfoCache | ||||||
|       try_file(user_cache_file) or |       try_file(user_cache_file) or | ||||||
|       raise "unable to locate a writable cache file") |       raise "unable to locate a writable cache file") | ||||||
|   end |   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). |   # Write the cache to a local file (if it is dirty). | ||||||
|  | @ -175,13 +177,30 @@ class Gem::SourceInfoCache | ||||||
|     self.class.latest_user_cache_file |     self.class.latest_user_cache_file | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   ## | ||||||
|  |   # Merges the complete cache file into this Gem::SourceInfoCache. | ||||||
|  | 
 | ||||||
|   def read_all_cache_data |   def read_all_cache_data | ||||||
|     if @only_latest then |     if @only_latest then | ||||||
|       @only_latest = false |       @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 | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   ## | ||||||
|  |   # Reads cached data from +file+. | ||||||
|  | 
 | ||||||
|   def read_cache_data(file) |   def read_cache_data(file) | ||||||
|     # Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small |     # Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small | ||||||
|     data = open file, 'rb' do |fp| fp.read end |     data = open file, 'rb' do |fp| fp.read end | ||||||
|  | @ -203,6 +222,8 @@ class Gem::SourceInfoCache | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     cache_data |     cache_data | ||||||
|  |   rescue Errno::ENOENT | ||||||
|  |     {} | ||||||
|   rescue => e |   rescue => e | ||||||
|     if Gem.configuration.really_verbose then |     if Gem.configuration.really_verbose then | ||||||
|       say "Exception during cache_data handling: #{e.class} - #{e}" |       say "Exception during cache_data handling: #{e.class} - #{e}" | ||||||
|  | @ -243,6 +264,14 @@ class Gem::SourceInfoCache | ||||||
| 
 | 
 | ||||||
|   def reset_cache_data |   def reset_cache_data | ||||||
|     @cache_data = nil |     @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 |   end | ||||||
| 
 | 
 | ||||||
|   ## |   ## | ||||||
|  | @ -315,10 +344,7 @@ class Gem::SourceInfoCache | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     if File.writable? dir then |     return path if File.writable? dir | ||||||
|       open path, "wb" do |io| io.write Marshal.dump({}) end |  | ||||||
|       return path |  | ||||||
|     end |  | ||||||
| 
 | 
 | ||||||
|     nil |     nil | ||||||
|   end |   end | ||||||
|  | @ -338,11 +364,13 @@ class Gem::SourceInfoCache | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   ## |   ## | ||||||
|   # Write data to the proper cache. |   # Write data to the proper cache files. | ||||||
| 
 | 
 | ||||||
|   def write_cache |   def write_cache | ||||||
|     open cache_file, 'wb' do |io| |     if not File.exist?(cache_file) or not @only_latest then | ||||||
|       io.write Marshal.dump(cache_data) |       open cache_file, 'wb' do |io| | ||||||
|  |         io.write Marshal.dump(cache_data) | ||||||
|  |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     open latest_cache_file, 'wb' do |io| |     open latest_cache_file, 'wb' do |io| | ||||||
|  | @ -350,5 +378,7 @@ class Gem::SourceInfoCache | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   reset | ||||||
|  | 
 | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,8 +23,7 @@ module Gem::VersionOption | ||||||
|                "Specify the platform of gem to #{task}", *wrap) do |                "Specify the platform of gem to #{task}", *wrap) do | ||||||
|                  |value, options| |                  |value, options| | ||||||
|       unless options[:added_platform] then |       unless options[:added_platform] then | ||||||
|         Gem.platforms.clear |         Gem.platforms = [Gem::Platform::RUBY] | ||||||
|         Gem.platforms << Gem::Platform::RUBY |  | ||||||
|         options[:added_platform] = true |         options[:added_platform] = true | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -61,6 +61,8 @@ class FakeFetcher | ||||||
|     name = "#{spec.full_name}.gem" |     name = "#{spec.full_name}.gem" | ||||||
|     path = File.join(install_dir, 'cache', name) |     path = File.join(install_dir, 'cache', name) | ||||||
| 
 | 
 | ||||||
|  |     Gem.ensure_gem_subdirectories install_dir | ||||||
|  | 
 | ||||||
|     if source_uri =~ /^http/ then |     if source_uri =~ /^http/ then | ||||||
|       File.open(path, "wb") do |f| |       File.open(path, "wb") do |f| | ||||||
|         f.write fetch_path(File.join(source_uri, "gems", name)) |         f.write fetch_path(File.join(source_uri, "gems", name)) | ||||||
|  | @ -369,6 +371,17 @@ class RubyGemTestCase < Test::Unit::TestCase | ||||||
|     Gem.win_platform? |     Gem.win_platform? | ||||||
|   end |   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 | end | ||||||
| 
 | 
 | ||||||
| class TempIO | class TempIO | ||||||
|  |  | ||||||
|  | @ -237,23 +237,25 @@ class TestGem < RubyGemTestCase | ||||||
|     assert_equal [Gem.dir], Gem.path |     assert_equal [Gem.dir], Gem.path | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_self_path_APPLE_GEM_HOME |   unless win_platform? | ||||||
|     Gem.clear_paths |     def test_self_path_APPLE_GEM_HOME | ||||||
|     Gem.const_set :APPLE_GEM_HOME, '/tmp/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 |       assert Gem.path.include?('/tmp/apple_gem_home') | ||||||
|     Gem.send :remove_const, :APPLE_GEM_HOME |     ensure | ||||||
|   end |       Gem.send :remove_const, :APPLE_GEM_HOME | ||||||
| 
 |     end | ||||||
|   def test_self_path_APPLE_GEM_HOME_GEM_PATH |    | ||||||
|     Gem.clear_paths |     def test_self_path_APPLE_GEM_HOME_GEM_PATH | ||||||
|     ENV['GEM_PATH'] = @gemhome |       Gem.clear_paths | ||||||
|     Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home' |       ENV['GEM_PATH'] = @gemhome | ||||||
| 
 |       Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home' | ||||||
|     assert !Gem.path.include?('/tmp/apple_gem_home') |    | ||||||
|   ensure |       assert !Gem.path.include?('/tmp/apple_gem_home') | ||||||
|     Gem.send :remove_const, :APPLE_GEM_HOME |     ensure | ||||||
|  |       Gem.send :remove_const, :APPLE_GEM_HOME | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_self_path_ENV_PATH |   def test_self_path_ENV_PATH | ||||||
|  | @ -303,21 +305,56 @@ class TestGem < RubyGemTestCase | ||||||
| 
 | 
 | ||||||
|   def test_self_prefix |   def test_self_prefix | ||||||
|     file_name = File.expand_path __FILE__ |     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 |   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] |     orig_sitelibdir = Gem::ConfigMap[:sitelibdir] | ||||||
| 
 | 
 | ||||||
|     file_name = File.expand_path __FILE__ |     file_name = File.expand_path __FILE__ | ||||||
|     prefix = File.join File.dirname(File.dirname(file_name)), 'lib' |     prefix = File.dirname File.dirname(file_name) | ||||||
|     Gem::ConfigMap[:sitelibdir] = prefix.sub(/[\w]\//, '\&/') | 
 | ||||||
|  |     Gem::ConfigMap[:sitelibdir] = prefix | ||||||
| 
 | 
 | ||||||
|     assert_nil Gem.prefix |     assert_nil Gem.prefix | ||||||
|   ensure |   ensure | ||||||
|     Gem::ConfigMap[:sitelibdir] = orig_sitelibdir |     Gem::ConfigMap[:sitelibdir] = orig_sitelibdir | ||||||
|   end |   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 |   def test_self_required_location | ||||||
|     util_make_gems |     util_make_gems | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ class TestGemCommandsEnvironmentCommand < RubyGemTestCase | ||||||
|       @cmd.execute |       @cmd.execute | ||||||
|     end |     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|RUBY VERSION: \d\.\d\.\d \(.*\) \[.*\]|, @ui.output | ||||||
|     assert_match %r|INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}|, |     assert_match %r|INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}|, | ||||||
|                  @ui.output |                  @ui.output | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ class TestGemCommandsQueryCommand < RubyGemTestCase | ||||||
|     cache.update |     cache.update | ||||||
|     cache.write_cache |     cache.write_cache | ||||||
|     cache.reset_cache_data |     cache.reset_cache_data | ||||||
|  |     Gem::SourceInfoCache.reset | ||||||
| 
 | 
 | ||||||
|     a2_name = @a2.full_name |     a2_name = @a2.full_name | ||||||
|     @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = util_zip a2_name |     @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = util_zip a2_name | ||||||
|  | @ -43,6 +44,9 @@ class TestGemCommandsQueryCommand < RubyGemTestCase | ||||||
| 
 | 
 | ||||||
| *** REMOTE GEMS *** | *** REMOTE GEMS *** | ||||||
| 
 | 
 | ||||||
|  | Updating metadata for 1 gems from http://gems.example.com/ | ||||||
|  | . | ||||||
|  | complete | ||||||
| a (2) | a (2) | ||||||
|     EOF |     EOF | ||||||
| 
 | 
 | ||||||
|  | @ -55,6 +59,7 @@ a (2) | ||||||
|     cache.update |     cache.update | ||||||
|     cache.write_cache |     cache.write_cache | ||||||
|     cache.reset_cache_data |     cache.reset_cache_data | ||||||
|  |     Gem::SourceInfoCache.reset | ||||||
| 
 | 
 | ||||||
|     a1_name = @a1.full_name |     a1_name = @a1.full_name | ||||||
|     a2_name = @a2.full_name |     a2_name = @a2.full_name | ||||||
|  | @ -76,8 +81,8 @@ a (2) | ||||||
| 
 | 
 | ||||||
| *** REMOTE GEMS *** | *** REMOTE GEMS *** | ||||||
| 
 | 
 | ||||||
| Updating metadata for 1 gems from http://gems.example.com/ | Updating metadata for 2 gems from http://gems.example.com/ | ||||||
| . | .. | ||||||
| complete | complete | ||||||
| a (2, 1) | a (2, 1) | ||||||
|     EOF |     EOF | ||||||
|  | @ -97,7 +102,7 @@ a (2, 1) | ||||||
| 
 | 
 | ||||||
| *** REMOTE GEMS *** | *** 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. 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] |     @cmd.handle_options %w[--update] | ||||||
| 
 | 
 | ||||||
|     util_setup_source_info_cache |     util_setup_source_info_cache | ||||||
|  |     Gem::SourceInfoCache.reset | ||||||
|  | 
 | ||||||
|     util_setup_fake_fetcher |     util_setup_fake_fetcher | ||||||
|     si = Gem::SourceIndex.new |     si = Gem::SourceIndex.new | ||||||
|     si.add_spec @a1 |     si.add_spec @a1 | ||||||
|  |  | ||||||
|  | @ -97,6 +97,7 @@ class TestGemCommandsUpdateCommand < RubyGemTestCase | ||||||
|     assert_equal "Updating installed gems", out.shift |     assert_equal "Updating installed gems", out.shift | ||||||
|     assert_match %r|Bulk updating|, out.shift |     assert_match %r|Bulk updating|, out.shift | ||||||
|     assert_equal "Updating #{@a2.name}", 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 #{@c2.full_name}", out.shift | ||||||
|     assert_equal "Successfully installed #{@b2.full_name}", out.shift |     assert_equal "Successfully installed #{@b2.full_name}", out.shift | ||||||
|     assert_equal "Successfully installed #{@a2.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', |     assert File.exist?(File.join(gemhome2, 'specifications', | ||||||
|                                  "#{@a1.full_name}.gemspec")) |                                  "#{@a1.full_name}.gemspec")) | ||||||
|  |     assert File.exist?(File.join(gemhome2, 'cache', | ||||||
|  |                                  "#{@a1.full_name}.gem")) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def test_install_domain_both |   def test_install_domain_both | ||||||
|  |  | ||||||
|  | @ -76,8 +76,9 @@ gems: | ||||||
| 
 | 
 | ||||||
|   # don't let 1.8 and 1.9 autotest collide |   # don't let 1.8 and 1.9 autotest collide | ||||||
|   RUBY_VERSION =~ /(\d+)\.(\d+)\.(\d+)/ |   RUBY_VERSION =~ /(\d+)\.(\d+)\.(\d+)/ | ||||||
|   PROXY_PORT = 12345 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i |   # don't let parallel runners collide | ||||||
|   SERVER_PORT = 23456 + $1.to_i * 100 + $2.to_i * 10 + $3.to_i |   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 |   def setup | ||||||
|     super |     super | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ class TestGemServer < RubyGemTestCase | ||||||
| 
 | 
 | ||||||
|     @a1 = quick_gem 'a', '1' |     @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 |     @req = WEBrick::HTTPRequest.new :Logger => nil | ||||||
|     @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0' |     @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0' | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -395,13 +395,31 @@ class TestGemSourceIndex < RubyGemTestCase | ||||||
|     assert_equal [updated_platform.name], @source_index.outdated |     assert_equal [updated_platform.name], @source_index.outdated | ||||||
|   end |   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 |   def test_remove_extra | ||||||
|     @source_index.add_spec @a1 |     @source_index.add_spec @a1 | ||||||
|     @source_index.add_spec @a2 |     @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 |   end | ||||||
| 
 | 
 | ||||||
|   def test_remove_extra_no_changes |   def test_remove_extra_no_changes | ||||||
|  |  | ||||||
|  | @ -287,6 +287,7 @@ class TestGemSourceInfoCache < RubyGemTestCase | ||||||
| 
 | 
 | ||||||
|     @sic.set_cache_data @gem_repo => sice |     @sic.set_cache_data @gem_repo => sice | ||||||
|     @sic.update |     @sic.update | ||||||
|  |     @sic.instance_variable_set :@only_latest, false | ||||||
|     @sic.write_cache |     @sic.write_cache | ||||||
|     @sic.reset_cache_data |     @sic.reset_cache_data | ||||||
| 
 | 
 | ||||||
|  | @ -358,6 +359,7 @@ class TestGemSourceInfoCache < RubyGemTestCase | ||||||
|     @sic.set_cache_data({@gem_repo => @sice_new}) |     @sic.set_cache_data({@gem_repo => @sice_new}) | ||||||
|     @sic.update |     @sic.update | ||||||
|     @sic.write_cache |     @sic.write_cache | ||||||
|  |     @sic.instance_variable_set :@only_latest, false | ||||||
| 
 | 
 | ||||||
|     assert File.exist?(@sic.user_cache_file), 'user_cache_file' |     assert File.exist?(@sic.user_cache_file), 'user_cache_file' | ||||||
|     assert File.exist?(@sic.latest_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.set_cache_data({ @gem_repo => @sice }) | ||||||
|     @sic.update |     @sic.update | ||||||
|  | 
 | ||||||
|     @sic.write_cache |     @sic.write_cache | ||||||
| 
 | 
 | ||||||
|     assert File.exist?(@sic.user_cache_file), 'system_cache_file' |     assert File.exist?(@sic.user_cache_file), 'system_cache_file' | ||||||
|  | @ -390,7 +393,7 @@ class TestGemSourceInfoCache < RubyGemTestCase | ||||||
|            'latest_system_cache_file' |            'latest_system_cache_file' | ||||||
| 
 | 
 | ||||||
|     user_cache_data = read_cache(@sic.user_cache_file).to_a.sort |     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 |     user_cache_data = user_cache_data.first | ||||||
| 
 | 
 | ||||||
|     assert_equal @gem_repo, user_cache_data.first |     assert_equal @gem_repo, user_cache_data.first | ||||||
|  | @ -415,6 +418,24 @@ class TestGemSourceInfoCache < RubyGemTestCase | ||||||
|     @sic.update |     @sic.update | ||||||
|     @sic.write_cache |     @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]], |     assert_equal [[@gem_repo, @sys_sice]], | ||||||
|                  read_cache(@sic.system_cache_file).to_a.sort |                  read_cache(@sic.system_cache_file).to_a.sort | ||||||
|     assert_equal [[@gem_repo, @sice_new]], |     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
	
	 drbrain
						drbrain