diff --git a/Manifest.txt b/Manifest.txt
index 5304cd96eb12..10f60a801a10 100644
--- a/Manifest.txt
+++ b/Manifest.txt
@@ -566,7 +566,7 @@ lib/rubygems/vendor/net-http/lib/net/http/response.rb
lib/rubygems/vendor/net-http/lib/net/http/responses.rb
lib/rubygems/vendor/net-http/lib/net/http/status.rb
lib/rubygems/vendor/net-http/lib/net/https.rb
-lib/rubygems/vendor/net-protocol/LICENSE.txt
+lib/rubygems/vendor/net-protocol/COPYING
lib/rubygems/vendor/net-protocol/lib/net/protocol.rb
lib/rubygems/vendor/optparse/COPYING
lib/rubygems/vendor/optparse/lib/optionparser.rb
diff --git a/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb b/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb
index 8cb81be7301a..e8aaf70016bd 100644
--- a/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb
+++ b/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb
@@ -104,6 +104,9 @@ def initialize(options = {}, &block)
end
def with(options = {})
+ # We need to manage exception handling manually here in order
+ # to work correctly with `Gem::Timeout.timeout` and `Thread#raise`.
+ # Otherwise an interrupted Thread can leak connections.
Thread.handle_interrupt(Exception => :never) do
conn = checkout(options)
begin
diff --git a/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb b/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb
index 364662d801b4..026d2c5be27a 100644
--- a/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb
+++ b/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb
@@ -54,9 +54,12 @@ def push(obj, options = {})
# immediately returned. If no connection is available within the given
# timeout a Bundler::ConnectionPool::TimeoutError is raised.
#
- # +:timeout+ is the only checked entry in +options+ and is preferred over
- # the +timeout+ argument (which will be removed in a future release). Other
- # options may be used by subclasses that extend TimedStack.
+ # @option options [Float] :timeout (0.5) Wait this many seconds for an available entry
+ # @option options [Class] :exception (Bundler::ConnectionPool::TimeoutError) Exception class to raise
+ # if an entry was not available within the timeout period. Use `exception: false` to return nil.
+ #
+ # The +timeout+ argument will be removed in 3.0.
+ # Other options may be used by subclasses that extend TimedStack.
def pop(timeout = 0.5, options = {})
options, timeout = timeout, 0.5 if Hash === timeout
timeout = options.fetch :timeout, timeout
@@ -73,7 +76,14 @@ def pop(timeout = 0.5, options = {})
return connection if connection
to_wait = deadline - current_time
- raise Bundler::ConnectionPool::TimeoutError, "Waited #{timeout} sec, #{length}/#{@max} available" if to_wait <= 0
+ if to_wait <= 0
+ exc = options.fetch(:exception, Bundler::ConnectionPool::TimeoutError)
+ if exc
+ raise Bundler::ConnectionPool::TimeoutError, "Waited #{timeout} sec, #{length}/#{@max} available"
+ else
+ return nil
+ end
+ end
@resource.wait(@mutex, to_wait)
end
end
diff --git a/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb b/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb
index cbac68b3dc83..2e9eebdbb6d2 100644
--- a/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb
+++ b/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb
@@ -1,3 +1,3 @@
class Bundler::ConnectionPool
- VERSION = "2.5.4"
+ VERSION = "2.5.5"
end
diff --git a/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb b/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb
index e2008c4e512d..61763cc511a0 100644
--- a/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb
+++ b/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb
@@ -181,7 +181,7 @@
#
module Bundler::FileUtils
# The version number.
- VERSION = "1.8.0"
+ VERSION = "1.8.1"
def self.private_module_function(name) #:nodoc:
module_function name
@@ -279,38 +279,67 @@ def remove_trailing_slash(dir) #:nodoc:
end
private_module_function :remove_trailing_slash
+ # :markup: markdown
#
- # Creates directories at the paths in the given +list+
- # (a single path or an array of paths);
- # returns +list+ if it is an array, [list] otherwise.
+ # call-seq:
+ # Bundler::FileUtils.mkdir(*paths, mode: 0775, noop: nil, verbose: nil) -> array_of_paths or nil
#
- # Argument +list+ or its elements
- # should be {interpretable as paths}[rdoc-ref:FileUtils@Path+Arguments].
+ # Argument `paths` may be one path or an array of paths;
+ # each must be {interpretable as a path}[rdoc-ref:FileUtils@Path+Arguments].
#
- # With no keyword arguments, creates a directory at each +path+ in +list+
- # by calling: Dir.mkdir(path, mode);
- # see {Dir.mkdir}[https://docs.ruby-lang.org/en/master/Dir.html#method-c-mkdir]:
+ # By default, creates a directory entry at each of the given `paths`;
+ # each directory has permissions `0775`;
+ # returns an array of the paths:
#
- # Bundler::FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"]
- # Bundler::FileUtils.mkdir('tmp4') # => ["tmp4"]
+ # ```ruby
+ # Bundler::FileUtils.mkdir('foo') # => ["foo"]
+ # Bundler::FileUtils.mkdir(%w[bar baz]) # => ["bar", "baz"]
+ # File.stat(Dir.new('foo')).mode.to_s(8) # => "40775"
+ # File.stat(Dir.new('bar')).mode.to_s(8) # => "40775"
+ # File.stat(Dir.new('baz')).mode.to_s(8) # => "40775"
+ # Bundler::FileUtils.rmdir(%w[foo bar baz]) # => ["foo", "bar", "baz"]
+ # ```
#
- # Keyword arguments:
+ # Raises an exception if for any reason a directory cannot be created;
+ # a common reason is that the directory already exists.
#
- # - mode: mode - also calls File.chmod(mode, path);
- # see {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod].
- # - noop: true - does not create directories.
- # - verbose: true - prints an equivalent command:
+ # With keyword argument `mode` given,
+ # creates directories with the given permissions:
#
- # Bundler::FileUtils.mkdir(%w[tmp0 tmp1], verbose: true)
- # Bundler::FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
+ # ```ruby
+ # Bundler::FileUtils.mkdir('bar', mode: 0664)
+ # File.stat(Dir.new('bar')).mode.to_s(8) # => "40664"
+ # Bundler::FileUtils.rmdir('bar')
+ # ```
#
- # Output:
+ # With keyword argument `noop` given as `true`,
+ # does not create directories;
+ # returns `nil`
+ #
+ # ```ruby
+ # Bundler::FileUtils.mkdir('foo', noop: true) # => nil
+ # Dir.exist?('foo') # => false
+ # ```
+ #
+ # With keyword argument `verbose` given as `true`,
+ # prints a shell command:
#
- # mkdir tmp0 tmp1
- # mkdir -m 700 tmp2 tmp3
+ # ```ruby
+ # Bundler::FileUtils.mkdir('foo', verbose: true)
+ # Bundler::FileUtils.mkdir(%w[bar baz], mode: 0644, verbose: true)
+ # Bundler::FileUtils.mkdir(%w[bar baz], mode: 0644, verbose: true, noop: true)
+ # ```
#
- # Raises an exception if any path points to an existing
- # file or directory, or if for any reason a directory cannot be created.
+ # Output:
+ #
+ # ```text
+ # mkdir foo
+ # mkdir -m 644 bar baz
+ # mkdir -m 644 bar baz
+ # ```
+ #
+ # Note that in the last call above (containing `noop: true`)
+ # the existence of the directory is not checked.
#
# Related: Bundler::FileUtils.mkdir_p.
#
@@ -686,7 +715,7 @@ def cp_lr(src, dest, noop: nil, verbose: nil,
# Keyword arguments:
#
# - force: true - overwrites +dest+ if it exists.
- # - relative: false - create links relative to +dest+.
+ # - relative: true - create links relative to +dest+.
# - noop: true - does not create links.
# - verbose: true - prints an equivalent command:
#
@@ -754,7 +783,7 @@ def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil
n = real_ddirs.size - i
n -= 1 unless target_directory
link2 = fu_clean_components(*Array.new([n, 0].max, '..'), *real_sdirs[i..-1])
- link1 = link2 if link1.size > link2.size
+ link1 = link2 if !link2.empty? and link1.size > link2.size
end
s = File.join(link1)
fu_output_message [cmd, s, d].flatten.join(' ') if verbose
@@ -2037,10 +2066,6 @@ def fu_windows?; true end #:nodoc:
def fu_windows?; false end #:nodoc:
end
- def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
- IO.copy_stream(src, dest)
- end
-
def fu_stream_blksize(*streams) #:nodoc:
streams.each do |s|
next unless s.respond_to?(:stat)
diff --git a/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb b/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
index 93e403a5bb36..00f2bca14ad3 100644
--- a/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
+++ b/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
@@ -1,10 +1,7 @@
require_relative '../../../../../vendored_net_http'
require_relative '../../../../../vendored_uri'
-begin
- require 'cgi/escape'
-rescue LoadError
- require 'cgi/util' # for escaping
-end
+require 'cgi/escape'
+require 'cgi/util' unless defined?(CGI::EscapeExt)
require_relative '../../../../connection_pool/lib/connection_pool'
autoload :OpenSSL, 'openssl'
@@ -180,7 +177,7 @@ class Gem::Net::HTTP::Persistent
##
# The version of Gem::Net::HTTP::Persistent you are using
- VERSION = '4.0.6'
+ VERSION = '4.0.8'
##
# Error class for errors raised by Gem::Net::HTTP::Persistent. Various
@@ -475,6 +472,13 @@ def self.detect_idle_timeout uri, max = 10
attr_reader :verify_hostname
+
+ ##
+ # Sets whether to ignore end-of-file when reading a response body
+ # with Content-Length headers.
+
+ attr_accessor :ignore_eof
+
##
# Creates a new Gem::Net::HTTP::Persistent.
#
@@ -514,6 +518,7 @@ def initialize name: nil, proxy: nil, pool_size: DEFAULT_POOL_SIZE
@max_retries = 1
@socket_options = []
@ssl_generation = 0 # incremented when SSL session variables change
+ @ignore_eof = nil
@socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
Socket.const_defined? :TCP_NODELAY
@@ -642,6 +647,7 @@ def connection_for uri
reset connection
end
+ http.ignore_eof = @ignore_eof if @ignore_eof
http.keep_alive_timeout = @idle_timeout if @idle_timeout
http.max_retries = @max_retries if http.respond_to?(:max_retries=)
http.read_timeout = @read_timeout if @read_timeout
diff --git a/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb b/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb
index 04a1e754bfdd..5e45ea77d1af 100644
--- a/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb
+++ b/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb
@@ -4,7 +4,7 @@ class Gem::Net::HTTP::Persistent::Pool < Bundler::ConnectionPool # :nodoc:
attr_reader :key # :nodoc:
def initialize(options = {}, &block)
- super
+ super(**options, &block)
@available = Gem::Net::HTTP::Persistent::TimedStackMulti.new(@size, &block)
@key = "current-#{@available.object_id}"
diff --git a/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb b/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb
index 034fbe39b811..57dfefdaae50 100644
--- a/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb
+++ b/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb
@@ -1,5 +1,10 @@
class Gem::Net::HTTP::Persistent::TimedStackMulti < Bundler::ConnectionPool::TimedStack # :nodoc:
+ ##
+ # Detects if Bundler::ConnectionPool 3.0+ is being used (needed for TimedStack subclass compatibility)
+
+ CP_USES_KEYWORD_ARGS = Gem::Version.new(Bundler::ConnectionPool::VERSION) >= Gem::Version.new('3.0.0') # :nodoc:
+
##
# Returns a new hash that has arrays for keys
#
@@ -11,7 +16,11 @@ def self.hash_of_arrays # :nodoc:
end
def initialize(size = 0, &block)
- super
+ if CP_USES_KEYWORD_ARGS
+ super(size: size, &block)
+ else
+ super(size, &block)
+ end
@enqueued = 0
@ques = self.class.hash_of_arrays
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor.rb b/bundler/lib/bundler/vendor/thor/lib/thor.rb
index 945bdbd5515f..b78593a6ac3b 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor.rb
@@ -625,7 +625,7 @@ def normalize_command_name(meth) #:nodoc:
# alias name.
def find_command_possibilities(meth)
len = meth.to_s.length
- possibilities = all_commands.reject { |_k, c| c.hidden? }.merge(map).keys.select { |n| meth == n[0, len] }.sort
+ possibilities = all_commands.reject {|k, v| v.is_a?(HiddenCommand) }.merge(map).keys.select { |n| meth == n[0, len] }.sort
unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
if possibilities.include?(meth)
@@ -671,4 +671,37 @@ def help(command = nil, subcommand = false)
self.class.help(shell, subcommand)
end
end
+
+ map TREE_MAPPINGS => :tree
+
+ desc "tree", "Print a tree of all available commands"
+ def tree
+ build_command_tree(self.class, "")
+ end
+
+private
+
+ def build_command_tree(klass, indent)
+ # Print current class name if it's not the root Bundler::Thor class
+ unless klass == Bundler::Thor
+ say "#{indent}#{klass.namespace || 'default'}", :blue
+ indent = "#{indent} "
+ end
+
+ # Print all commands for this class
+ visible_commands = klass.commands.reject { |_, cmd| cmd.hidden? || cmd.name == "help" }
+ commands_count = visible_commands.count
+ visible_commands.sort.each_with_index do |(command_name, command), i|
+ description = command.description.split("\n").first || ""
+ icon = i == (commands_count - 1) ? "└─" : "├─"
+ say "#{indent}#{icon} ", nil, false
+ say command_name, :green, false
+ say " (#{description})" unless description.empty?
+ end
+
+ # Print all subcommands (from registered Bundler::Thor subclasses)
+ klass.subcommand_classes.each do |_, subclass|
+ build_command_tree(subclass, indent)
+ end
+ end
end
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb b/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
index 70526e615f18..229f294b10c1 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb
@@ -2,6 +2,38 @@
class Bundler::Thor
module Actions
+ WARNINGS = {unchanged_no_flag: "File unchanged! Either the supplied flag value not found or the content has already been inserted!"}
+
+ # Injects the given content into a file, raising an error if the contents of
+ # the file are not changed. Different from gsub_file, this method is reversible.
+ #
+ # ==== Parameters
+ # destination:: Relative path to the destination root
+ # data:: Data to add to the file. Can be given as a block.
+ # config:: give :verbose => false to not log the status and the flag
+ # for injection (:after or :before) or :force => true for
+ # insert two or more times the same content.
+ #
+ # ==== Examples
+ #
+ # insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
+ #
+ # insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
+ # gems = ask "Which gems would you like to add?"
+ # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
+ # end
+ #
+ def insert_into_file!(destination, *args, &block)
+ data = block_given? ? block : args.shift
+
+ config = args.shift || {}
+ config[:after] = /\z/ unless config.key?(:before) || config.key?(:after)
+ config = config.merge({error_on_no_change: true})
+
+ action InjectIntoFile.new(self, destination, data, config)
+ end
+ alias_method :inject_into_file!, :insert_into_file!
+
# Injects the given content into a file. Different from gsub_file, this
# method is reversible.
#
@@ -21,8 +53,6 @@ module Actions
# gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
# end
#
- WARNINGS = {unchanged_no_flag: "File unchanged! Either the supplied flag value not found or the content has already been inserted!"}
-
def insert_into_file(destination, *args, &block)
data = block_given? ? block : args.shift
@@ -47,6 +77,7 @@ def initialize(base, destination, data, config)
@replacement = data.is_a?(Proc) ? data.call : data
@flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
+ @error_on_no_change = @config.fetch(:error_on_no_change, false)
end
def invoke!
@@ -59,6 +90,8 @@ def invoke!
if exists?
if replace!(/#{flag}/, content, config[:force])
say_status(:invoke)
+ elsif @error_on_no_change
+ raise Bundler::Thor::Error, "The content of #{destination} did not change"
elsif replacement_present?
say_status(:unchanged, color: :blue)
else
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/base.rb b/bundler/lib/bundler/vendor/thor/lib/thor/base.rb
index b156899c1e0a..f378a48d589e 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor/base.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor/base.rb
@@ -13,8 +13,9 @@ class Bundler::Thor
autoload :RakeCompat, File.expand_path("rake_compat", __dir__)
autoload :Group, File.expand_path("group", __dir__)
- # Shortcuts for help.
+ # Shortcuts for help and tree commands.
HELP_MAPPINGS = %w(-h -? --help -D)
+ TREE_MAPPINGS = %w(-t --tree)
# Bundler::Thor methods that should not be overwritten by the user.
THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
index da02b9422758..fcd84f45e762 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
@@ -311,13 +311,11 @@ def file_collision_help(block_given) #:nodoc:
end
def show_diff(destination, content) #:nodoc:
- diff_cmd = ENV["THOR_DIFF"] || ENV["RAILS_DIFF"] || "diff -u"
-
require "tempfile"
Tempfile.open(File.basename(destination), File.dirname(destination), binmode: true) do |temp|
temp.write content
temp.rewind
- system %(#{diff_cmd} "#{destination}" "#{temp.path}")
+ system(*diff_tool, destination, temp.path)
end
end
@@ -369,15 +367,25 @@ def answer_match(possibilities, answer, case_insensitive)
def merge(destination, content) #:nodoc:
require "tempfile"
- Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination)) do |temp|
+ Tempfile.open([File.basename(destination), File.extname(destination)], File.dirname(destination), binmode: true) do |temp|
temp.write content
temp.rewind
- system(merge_tool, temp.path, destination)
+ system(*merge_tool, temp.path, destination)
end
end
def merge_tool #:nodoc:
- @merge_tool ||= ENV["THOR_MERGE"] || "git difftool --no-index"
+ @merge_tool ||= begin
+ require "shellwords"
+ Shellwords.split(ENV["THOR_MERGE"] || "git difftool --no-index")
+ end
+ end
+
+ def diff_tool #:nodoc:
+ @diff_cmd ||= begin
+ require "shellwords"
+ Shellwords.split(ENV["THOR_DIFF"] || ENV["RAILS_DIFF"] || "diff -u")
+ end
end
end
end
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb b/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb
index 5d708fadcad2..b09675682c87 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require_relative "basic"
class Bundler::Thor
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/version.rb b/bundler/lib/bundler/vendor/thor/lib/thor/version.rb
index 5474a2f71bad..3fe3e3ae82e1 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor/version.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor/version.rb
@@ -1,3 +1,3 @@
class Bundler::Thor
- VERSION = "1.4.0"
+ VERSION = "1.5.0"
end
diff --git a/bundler/lib/bundler/vendor/uri/lib/uri/common.rb b/bundler/lib/bundler/vendor/uri/lib/uri/common.rb
index 935392c19463..29ef7297469f 100644
--- a/bundler/lib/bundler/vendor/uri/lib/uri/common.rb
+++ b/bundler/lib/bundler/vendor/uri/lib/uri/common.rb
@@ -271,7 +271,7 @@ def self.parse(uri)
# # => #
#
def self.join(*str)
- DEFAULT_PARSER.join(*str)
+ PARSER.join(*str)
end
#
diff --git a/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb b/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb
index 30dab609035b..e8326dda4f40 100644
--- a/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb
+++ b/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb
@@ -466,7 +466,7 @@ def userinfo=(userinfo)
#
# uri = Bundler::URI.parse("http://john:S3nsit1ve@my.example.com")
# uri.user = "sam"
- # uri.to_s #=> "http://sam:V3ry_S3nsit1ve@my.example.com"
+ # uri.to_s #=> "http://sam@my.example.com"
#
def user=(user)
check_user(user)
@@ -1021,9 +1021,21 @@ def merge_path(base, rel)
# RFC2396, Section 5.2, 6), a)
base_path << '' if base_path.last == '..'
- while i = base_path.index('..')
- base_path.slice!(i - 1, 2)
+ # Remove "/.." pairs in a single left-to-right pass (O(n)).
+ # This deliberately differs from the relative-path stack handling
+ # below: a leading ".." (one with no preceding segment left to
+ # cancel) discards the whole base path, reproducing the previous
+ # index/slice! implementation exactly.
+ reduced = []
+ base_path.each do |seg|
+ if seg == '..'
+ break if reduced.empty?
+ reduced.pop
+ else
+ reduced << seg
+ end
end
+ base_path = reduced
if (first = rel_path.first) and first.empty?
base_path.clear
diff --git a/bundler/lib/bundler/vendor/uri/lib/uri/version.rb b/bundler/lib/bundler/vendor/uri/lib/uri/version.rb
index ad76308e81d1..e3ecb556085e 100644
--- a/bundler/lib/bundler/vendor/uri/lib/uri/version.rb
+++ b/bundler/lib/bundler/vendor/uri/lib/uri/version.rb
@@ -1,6 +1,6 @@
module Bundler::URI
# :stopdoc:
- VERSION = '1.1.1'.freeze
+ VERSION = '1.1.2'.freeze
VERSION_CODE = VERSION.split('.').map{|s| s.rjust(2, '0')}.join.freeze
# :startdoc:
end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http.rb b/lib/rubygems/vendor/net-http/lib/net/http.rb
index e1ccc0561004..bdc4283eb380 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http.rb
@@ -36,7 +36,7 @@ class HTTPHeaderSyntaxError < StandardError; end
# For information about \HTTP, see:
#
# - {Hypertext Transfer Protocol}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol].
- # - {Technical overview}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview].
+ # - {Technology}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technology].
#
# == About the Examples
#
@@ -71,7 +71,7 @@ class HTTPHeaderSyntaxError < StandardError; end
#
# - If performance is important, consider using sessions, which lower request overhead.
# This {session}[rdoc-ref:Gem::Net::HTTP@Sessions] has multiple requests for
- # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]
+ # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method]
# and {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
#
# Gem::Net::HTTP.start(hostname) do |http|
@@ -81,6 +81,7 @@ class HTTPHeaderSyntaxError < StandardError; end
# body = 'Some text'
# http.post(path, body) # Can also have a block.
# http.put(path, body)
+ # http.query(path, body) # Can also have a block.
# http.delete(path)
# http.options(path)
# http.trace(path)
@@ -197,7 +198,7 @@ class HTTPHeaderSyntaxError < StandardError; end
# In the block, you can use these instance methods,
# each of which that sends a single request:
#
- # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
+ # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method]:
#
# - #get, #request_get: GET.
# - #head, #request_head: HEAD.
@@ -206,6 +207,7 @@ class HTTPHeaderSyntaxError < StandardError; end
# - #options: OPTIONS.
# - #trace: TRACE.
# - #patch: PATCH.
+ # - #query, #request_query: QUERY.
#
# - {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
#
@@ -446,7 +448,7 @@ class HTTPHeaderSyntaxError < StandardError; end
# if the response has header 'Content-Range'.
#
# Otherwise decompression (or not) depends on the value of header
- # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-encoding-response-header]:
+ # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Content-Encoding_2]:
#
# - 'deflate', 'gzip', or 'x-gzip':
# decompresses the body and deletes the header.
@@ -459,7 +461,7 @@ class HTTPHeaderSyntaxError < StandardError; end
#
# First, what's elsewhere. Class Gem::Net::HTTP:
#
- # - Inherits from {class Object}[https://docs.ruby-lang.org/en/master/Object.html#class-Object-label-What-27s+Here].
+ # - Inherits from {class Object}[https://docs.ruby-lang.org/en/master/Object.html#class-object-whats-here].
#
# This is a categorized summary of methods and attributes.
#
@@ -552,6 +554,8 @@ class HTTPHeaderSyntaxError < StandardError; end
# Sends a PROPPATCH request and returns a response object.
# - {#put}[rdoc-ref:Gem::Net::HTTP#put]:
# Sends a PUT request and returns a response object.
+ # - {#query}[rdoc-ref:Gem::Net::HTTP#query]:
+ # Sends a QUERY request and returns a response object.
# - {#request}[rdoc-ref:Gem::Net::HTTP#request]:
# Sends a request and returns a response object.
# - {#request_get}[rdoc-ref:Gem::Net::HTTP#request_get]:
@@ -723,7 +727,7 @@ class HTTPHeaderSyntaxError < StandardError; end
class HTTP < Protocol
# :stopdoc:
- VERSION = "0.7.0"
+ VERSION = "0.10.0"
HTTPVersion = '1.1'
begin
require 'zlib'
@@ -1178,6 +1182,7 @@ def initialize(address, port = nil) # :nodoc:
@debug_output = options[:debug_output]
@response_body_encoding = options[:response_body_encoding]
@ignore_eof = options[:ignore_eof]
+ @tcpsocket_supports_open_timeout = nil
@proxy_from_env = false
@proxy_uri = nil
@@ -1302,7 +1307,7 @@ def response_body_encoding=(value)
# Sets whether to determine the proxy from environment variable
# 'ENV['http_proxy']';
- # see {Proxy Using ENV['http_proxy']}[rdoc-ref:Gem::Net::HTTP@Proxy+Using+-27ENV-5B-27http_proxy-27-5D-27].
+ # see {Proxy Using ENV}[rdoc-ref:Gem::Net::HTTP@Proxy+Using+ENVHTTPProxy].
attr_writer :proxy_from_env
# Sets the proxy address;
@@ -1320,6 +1325,9 @@ def response_body_encoding=(value)
# Sets the proxy password;
# see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
attr_writer :proxy_pass
+
+ # Sets whether the proxy uses SSL;
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
attr_writer :proxy_use_ssl
# Returns the IP address for the connection.
@@ -1526,7 +1534,7 @@ def use_ssl=(flag)
:verify_depth,
:verify_mode,
:verify_hostname,
- ] # :nodoc:
+ ].freeze # :nodoc:
SSL_IVNAMES = SSL_ATTRIBUTES.map { |a| "@#{a}".to_sym }.freeze # :nodoc:
@@ -1568,11 +1576,11 @@ def use_ssl=(flag)
attr_accessor :cert_store
# Sets or returns the available SSL ciphers.
- # See {OpenSSL::SSL::SSLContext#ciphers=}[OpenSSL::SSL::SSL::Context#ciphers=].
+ # See {OpenSSL::SSL::SSLContext#ciphers=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ciphers-3D].
attr_accessor :ciphers
# Sets or returns the extra X509 certificates to be added to the certificate chain.
- # See {OpenSSL::SSL::SSLContext#add_certificate}[OpenSSL::SSL::SSL::Context#add_certificate].
+ # See {OpenSSL::SSL::SSLContext#add_certificate}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-add_certificate].
attr_accessor :extra_chain_cert
# Sets or returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
@@ -1582,15 +1590,15 @@ def use_ssl=(flag)
attr_accessor :ssl_timeout
# Sets or returns the SSL version.
- # See {OpenSSL::SSL::SSLContext#ssl_version=}[OpenSSL::SSL::SSL::Context#ssl_version=].
+ # See {OpenSSL::SSL::SSLContext#ssl_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D].
attr_accessor :ssl_version
# Sets or returns the minimum SSL version.
- # See {OpenSSL::SSL::SSLContext#min_version=}[OpenSSL::SSL::SSL::Context#min_version=].
+ # See {OpenSSL::SSL::SSLContext#min_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D].
attr_accessor :min_version
# Sets or returns the maximum SSL version.
- # See {OpenSSL::SSL::SSLContext#max_version=}[OpenSSL::SSL::SSL::Context#max_version=].
+ # See {OpenSSL::SSL::SSLContext#max_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D].
attr_accessor :max_version
# Sets or returns the callback for the server certification verification.
@@ -1606,7 +1614,7 @@ def use_ssl=(flag)
# Sets or returns whether to verify that the server certificate is valid
# for the hostname.
- # See {OpenSSL::SSL::SSLContext#verify_hostname=}[OpenSSL::SSL::SSL::Context#verify_hostname=].
+ # See {OpenSSL::SSL::SSLContext#verify_hostname=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#attribute-i-verify_hostname].
attr_accessor :verify_hostname
# Returns the X509 certificate chain (an array of strings)
@@ -1654,6 +1662,21 @@ def start # :yield: http
self
end
+ # Finishes the \HTTP session:
+ #
+ # http = Gem::Net::HTTP.new(hostname)
+ # http.start
+ # http.started? # => true
+ # http.finish # => nil
+ # http.started? # => false
+ #
+ # Raises IOError if not in a session.
+ def finish
+ raise IOError, 'HTTP session not yet started' unless started?
+ do_finish
+ end
+
+ # :stopdoc:
def do_start
connect
@started = true
@@ -1676,14 +1699,15 @@ def connect
end
debug "opening connection to #{conn_addr}:#{conn_port}..."
- s = Gem::Timeout.timeout(@open_timeout, Gem::Net::OpenTimeout) {
- begin
- TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
- rescue => e
- raise e, "Failed to open TCP connection to " +
- "#{conn_addr}:#{conn_port} (#{e.message})"
+ begin
+ s = timeouted_connect(conn_addr, conn_port)
+ rescue => e
+ if (defined?(IO::TimeoutError) && e.is_a?(IO::TimeoutError)) || e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions
+ e = Gem::Net::OpenTimeout.new(e)
end
- }
+ raise e, "Failed to open TCP connection to " +
+ "#{conn_addr}:#{conn_port} (#{e.message})"
+ end
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
debug "opened"
if use_ssl?
@@ -1776,23 +1800,30 @@ def connect
end
private :connect
- def on_connect
+ tcp_socket_parameters = TCPSocket.instance_method(:initialize).parameters
+ TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT = if tcp_socket_parameters != [[:rest]]
+ tcp_socket_parameters.include?([:key, :open_timeout])
+ else
+ # Use Socket.tcp to find out since there is no parameters information for TCPSocket#initialize
+ # See discussion in https://github.com/ruby/net-http/pull/224
+ Socket.method(:tcp).parameters.include?([:key, :open_timeout])
end
- private :on_connect
+ private_constant :TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
- # Finishes the \HTTP session:
- #
- # http = Gem::Net::HTTP.new(hostname)
- # http.start
- # http.started? # => true
- # http.finish # => nil
- # http.started? # => false
- #
- # Raises IOError if not in a session.
- def finish
- raise IOError, 'HTTP session not yet started' unless started?
- do_finish
+ def timeouted_connect(conn_addr, conn_port)
+ if TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout)
+ else
+ Gem::Timeout.timeout(@open_timeout, Gem::Net::OpenTimeout) {
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
+ }
+ end
+ end
+ private :timeouted_connect
+
+ def on_connect
end
+ private :on_connect
def do_finish
@started = false
@@ -1843,6 +1874,8 @@ def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_use_ss
}
end
+ # :startdoc:
+
class << HTTP
# Returns true if self is a class which was created by HTTP::Proxy.
def proxy_class?
@@ -1937,6 +1970,7 @@ def proxy_pass
alias proxyport proxy_port #:nodoc: obsolete
private
+ # :stopdoc:
def unescape(value)
require 'cgi/escape'
@@ -1965,6 +1999,7 @@ def edit_path(path)
path
end
end
+ # :startdoc:
#
# HTTP operations
@@ -2092,6 +2127,25 @@ def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segm
send_entity(path, data, initheader, dest, Patch, &block)
end
+ # Sends a QUERY request to the server;
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
+ #
+ # The request is based on the Gem::Net::HTTP::Query object
+ # created from string +path+, string +data+, and initial headers hash +initheader+.
+ #
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
+ # http = Gem::Net::HTTP.new(hostname)
+ # http.query('/todos/1', data) # => #
+ #
+ # Related:
+ #
+ # - Gem::Net::HTTP::Query: request class for \HTTP method QUERY.
+ # - Gem::Net::HTTP.query: sends QUERY request, returns response body.
+ #
+ def query(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
+ send_entity(path, data, initheader, dest, Query, &block)
+ end
+
# Sends a PUT request to the server;
# returns an instance of a subclass of Gem::Net::HTTPResponse.
#
@@ -2326,6 +2380,36 @@ def request_put(path, data, initheader = nil, &block) #:nodoc:
request Put.new(path, initheader), data, &block
end
+ # Sends a QUERY request to the server;
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
+ #
+ # The request is based on the Gem::Net::HTTP::Query object
+ # created from string +path+, string +body+, and initial headers hash +initheader+.
+ #
+ # http = Gem::Net::HTTP.new(hostname)
+ # http.query('/todos/1', 'xyzzy')
+ # # => #
+ #
+ # With no block given, returns the response object:
+ #
+ # http = Gem::Net::HTTP.new(hostname)
+ # http.request_query('/todos') # => #
+ #
+ # With a block given, calls the block with the response object
+ # and returns the response object:
+ #
+ # http.request_query('/todos') do |res|
+ # p res
+ # end # => #
+ #
+ # Output:
+ #
+ # #
+ #
+ def request_query(path, data, initheader = nil, &block) # :yield: +response+
+ request Query.new(path, initheader), data, &block
+ end
+
alias get2 request_get #:nodoc: obsolete
alias head2 request_head #:nodoc: obsolete
alias post2 request_post #:nodoc: obsolete
@@ -2419,7 +2503,9 @@ def send_entity(path, data, initheader, dest, type, &block)
res
end
- IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE/ # :nodoc:
+ # :stopdoc:
+
+ IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE QUERY/.freeze # :nodoc:
def transport_request(req)
count = 0
@@ -2433,11 +2519,17 @@ def transport_request(req)
# still read the received response.
end
+ informational_count = 0
begin
res = HTTPResponse.read_new(@socket)
res.decode_content = req.decode_content
res.body_encoding = @response_body_encoding
res.ignore_eof = @ignore_eof
+ if res.kind_of?(HTTPInformation)
+ informational_count += 1
+ raise HTTPBadResponse, 'too many informational responses' if
+ informational_count > HTTPResponse::MAX_INFORMATIONAL_RESPONSES
+ end
end while res.kind_of?(HTTPInformation)
res.uri = req.uri
@@ -2576,7 +2668,7 @@ def debug(msg)
alias_method :D, :debug
end
- # for backward compatibility until Ruby 3.5
+ # for backward compatibility until Ruby 4.0
# https://bugs.ruby-lang.org/issues/20900
# https://github.com/bblimke/webmock/pull/1081
HTTPSession = HTTP
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb b/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb
index c629c0113b1a..218df9a8bd15 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb
@@ -3,7 +3,7 @@ module Gem::Net
# Gem::Net::HTTP exception class.
# You cannot use Gem::Net::HTTPExceptions directly; instead, you must use
# its subclasses.
- module HTTPExceptions
+ module HTTPExceptions # :nodoc:
def initialize(msg, res) #:nodoc:
super msg
@response = res
@@ -12,6 +12,7 @@ def initialize(msg, res) #:nodoc:
alias data response #:nodoc: obsolete
end
+ # :stopdoc:
class HTTPError < ProtocolError
include HTTPExceptions
end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb b/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb
index 0737b3f02afa..dd49c1521637 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb
@@ -19,16 +19,13 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc:
if Gem::URI === uri_or_path then
raise ArgumentError, "not an HTTP Gem::URI" unless Gem::URI::HTTP === uri_or_path
- hostname = uri_or_path.hostname
+ hostname = uri_or_path.host
raise ArgumentError, "no host component for Gem::URI" unless (hostname && hostname.length > 0)
@uri = uri_or_path.dup
- host = @uri.hostname.dup
- host << ":" << @uri.port.to_s if @uri.port != @uri.default_port
@path = uri_or_path.request_uri
raise ArgumentError, "no HTTP request path given" unless @path
else
@uri = nil
- host = nil
raise ArgumentError, "no HTTP request path given" unless uri_or_path
raise ArgumentError, "HTTP request path is empty" if uri_or_path.empty?
@path = uri_or_path.dup
@@ -51,7 +48,7 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc:
initialize_http_header initheader
self['Accept'] ||= '*/*'
self['User-Agent'] ||= 'Ruby'
- self['Host'] ||= host if host
+ self['Host'] ||= @uri.authority if @uri
@body = nil
@body_stream = nil
@body_data = nil
@@ -245,7 +242,7 @@ def update_uri(addr, port, ssl) # :nodoc: internal use only
end
if host = self['host']
- host.sub!(/:.*/m, '')
+ host = Gem::URI.parse("//#{host}").host # Remove a port component from the existing Host header
elsif host = @uri.host
else
host = addr
@@ -264,6 +261,8 @@ def update_uri(addr, port, ssl) # :nodoc: internal use only
private
+ # :stopdoc:
+
class Chunker #:nodoc:
def initialize(sock)
@sock = sock
@@ -337,6 +336,9 @@ def encode_multipart_form_data(out, params, opt)
boundary = opt[:boundary]
require 'securerandom' unless defined?(SecureRandom)
boundary ||= SecureRandom.urlsafe_base64(40)
+ if /[\r\n]/.match?(boundary.to_s)
+ raise ArgumentError, "multipart boundary cannot include CR/LF"
+ end
chunked_p = chunked?
buf = +''
@@ -350,7 +352,10 @@ def encode_multipart_form_data(out, params, opt)
buf << "--#{boundary}\r\n"
if filename
filename = quote_string(filename, charset)
- type = h[:content_type] || 'application/octet-stream'
+ type = (h[:content_type] || 'application/octet-stream').to_s
+ if /[\r\n]/.match?(type)
+ raise ArgumentError, "field content type cannot include CR/LF"
+ end
buf << "Content-Disposition: form-data; " \
"name=\"#{key}\"; filename=\"#{filename}\"\r\n" \
"Content-Type: #{type}\r\n\r\n"
@@ -385,6 +390,9 @@ def encode_multipart_form_data(out, params, opt)
def quote_string(str, charset)
str = str.encode(charset, fallback:->(c){'%d;'%c.encode("UTF-8").ord}) if charset
+ if /[\r\n]/.match?(str)
+ raise ArgumentError, "multipart field name or filename cannot include CR/LF"
+ end
str.gsub(/[\\"]/, '\\\\\&')
end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/header.rb b/lib/rubygems/vendor/net-http/lib/net/http/header.rb
index 5cb1da01ec07..67622f23d28b 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http/header.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http/header.rb
@@ -179,7 +179,9 @@
# - #each_value: Passes each string field value to the block.
#
module Gem::Net::HTTPHeader
+ # The maximum length of HTTP header keys.
MAX_KEY_LENGTH = 1024
+ # The maximum length of HTTP header values.
MAX_FIELD_LENGTH = 65536
def initialize_http_header(initheader) #:nodoc:
@@ -191,11 +193,9 @@ def initialize_http_header(initheader) #:nodoc:
warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE
else
value = value.strip # raise error for invalid byte sequences
- if key.to_s.bytesize > MAX_KEY_LENGTH
- raise ArgumentError, "too long (#{key.bytesize} bytes) header: #{key[0, 30].inspect}..."
- end
+ validate_field_name(key)
if value.to_s.bytesize > MAX_FIELD_LENGTH
- raise ArgumentError, "header #{key} has too long field value: #{value.bytesize}"
+ raise ArgumentError, "header #{key} has too long field value: #{value.bytesize} bytes (limit #{MAX_FIELD_LENGTH})"
end
if value.count("\r\n") > 0
raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF"
@@ -261,20 +261,34 @@ def []=(key, val)
def add_field(key, val)
stringified_downcased_key = key.downcase.to_s
if @header.key?(stringified_downcased_key)
- append_field_value(@header[stringified_downcased_key], val)
+ append_field_value(@header[stringified_downcased_key], val, key)
else
set_field(key, val)
end
end
+ # :stopdoc:
+ private def validate_field_name(key)
+ if key.to_s.bytesize > MAX_KEY_LENGTH
+ raise ArgumentError, "too long (#{key.to_s.bytesize} bytes) header: #{key.to_s[0, 30].inspect}..."
+ end
+ if /[\x00-\x1f\x7f:]/n.match?(key.to_s.b)
+ raise ArgumentError, "header field name cannot include control characters or colon: #{key.to_s[0, 30].inspect}"
+ end
+ end
+
private def set_field(key, val)
+ validate_field_name(key)
case val
when Enumerable
ary = []
- append_field_value(ary, val)
+ append_field_value(ary, val, key)
@header[key.downcase.to_s] = ary
else
val = val.to_s # for compatibility use to_s instead of to_str
+ if val.bytesize > MAX_FIELD_LENGTH
+ raise ArgumentError, "header #{key} has too long field value: #{val.bytesize} bytes (limit #{MAX_FIELD_LENGTH})"
+ end
if val.b.count("\r\n") > 0
raise ArgumentError, 'header field value cannot include CR/LF'
end
@@ -282,18 +296,22 @@ def add_field(key, val)
end
end
- private def append_field_value(ary, val)
+ private def append_field_value(ary, val, key)
case val
when Enumerable
- val.each{|x| append_field_value(ary, x)}
+ val.each{|x| append_field_value(ary, x, key)}
else
val = val.to_s
+ if val.bytesize > MAX_FIELD_LENGTH
+ raise ArgumentError, "header #{key} has too long field value: #{val.bytesize} bytes (limit #{MAX_FIELD_LENGTH})"
+ end
if /[\r\n]/n.match?(val.b)
raise ArgumentError, 'header field value cannot include CR/LF'
end
ary.push val
end
end
+ # :startdoc:
# Returns the array field value for the given +key+,
# or +nil+ if there is no such field;
@@ -490,7 +508,7 @@ def each_capitalized
alias canonical_each each_capitalized
- def capitalize(name)
+ def capitalize(name) # :nodoc:
name.to_s.split('-'.freeze).map {|s| s.capitalize }.join('-'.freeze)
end
private :capitalize
@@ -613,11 +631,35 @@ def set_range(r, e = nil)
# res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
# res.content_length # => nil
#
+ # The value must consist of digits only.
+ # Multiple 'Content-Length' values are accepted
+ # only when they are all identical;
+ # otherwise Gem::Net::HTTPHeaderSyntaxError is raised.
+ # See {RFC 9110 Section 8.6}[https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6].
def content_length
- return nil unless key?('Content-Length')
- len = self['Content-Length'].slice(/\d+/) or
- raise Gem::Net::HTTPHeaderSyntaxError, 'wrong Content-Length format'
- len.to_i
+ values = @header['content-length']
+ return nil if values.nil?
+
+ lengths = []
+ values.each do |value|
+ value = value.strip
+ if value.empty?
+ raise Gem::Net::HTTPHeaderSyntaxError,
+ "empty Content-Length value"
+ end
+ lengths.concat(value.split(/\s*,\s*/, -1))
+ end
+ if lengths.uniq.size != 1
+ raise Gem::Net::HTTPHeaderSyntaxError,
+ "Content-Length has multiple different values: " +
+ values.join(", ")
+ end
+ length = lengths.first
+ unless /\A\d+\z/.match?(length)
+ raise Gem::Net::HTTPHeaderSyntaxError,
+ "wrong Content-Length format: #{length}"
+ end
+ length.to_i
end
# Sets the value of field 'Content-Length' to the given numeric;
@@ -643,7 +685,7 @@ def content_length=(len)
end
# Returns +true+ if field 'Transfer-Encoding'
- # exists and has value 'chunked',
+ # exists and has 'chunked' as its final transfer coding,
# +false+ otherwise;
# see {Transfer-Encoding response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#transfer-encoding-response-header]:
#
@@ -651,10 +693,13 @@ def content_length=(len)
# res['Transfer-Encoding'] # => "chunked"
# res.chunked? # => true
#
+ # 'gzip, chunked' is chunked but 'chunked, gzip' is not,
+ # because only the final transfer coding frames the message.
+ # See {RFC 9112 Section 6.3}[https://www.rfc-editor.org/rfc/rfc9112.html#section-6.3].
def chunked?
return false unless @header['transfer-encoding']
field = self['Transfer-Encoding']
- (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
+ (/(?:\A|[^\-\w])chunked(?![\-\w])\s*(?:,\s*)*\z/i =~ field) ? true : false
end
# Returns a Range object representing the value of field
@@ -770,7 +815,7 @@ def type_params
#
# Gem::Net::HTTPHeader#content_type= is an alias for Gem::Net::HTTPHeader#set_content_type.
def set_content_type(type, params = {})
- @header['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')]
+ set_field('Content-Type', type + params.map{|k,v|"; #{k}=#{v}"}.join(''))
end
alias content_type= set_content_type
@@ -957,12 +1002,12 @@ def proxy_basic_auth(account, password)
@header['proxy-authorization'] = [basic_encode(account, password)]
end
- def basic_encode(account, password)
+ def basic_encode(account, password) # :nodoc:
'Basic ' + ["#{account}:#{password}"].pack('m0')
end
private :basic_encode
-# Returns whether the HTTP session is to be closed.
+ # Returns whether the HTTP session is to be closed.
def connection_close?
token = /(?:\A|,)\s*close\s*(?:\z|,)/i
@header['connection']&.grep(token) {return true}
@@ -970,7 +1015,7 @@ def connection_close?
false
end
-# Returns whether the HTTP session is to be kept alive.
+ # Returns whether the HTTP session is to be kept alive.
def connection_keep_alive?
token = /(?:\A|,)\s*keep-alive\s*(?:\z|,)/i
@header['connection']&.grep(token) {return true}
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/request.rb b/lib/rubygems/vendor/net-http/lib/net/http/request.rb
index 495ec9be5424..567786c930d9 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http/request.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http/request.rb
@@ -61,6 +61,7 @@
# - Gem::Net::HTTP::Options
# - Gem::Net::HTTP::Trace
# - Gem::Net::HTTP::Patch
+# - Gem::Net::HTTP::Query
#
# Subclasses for WebDAV requests:
#
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/requests.rb b/lib/rubygems/vendor/net-http/lib/net/http/requests.rb
index 45727e7f61fc..ca56e6449d11 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http/requests.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http/requests.rb
@@ -19,9 +19,9 @@
#
# - Request body: optional.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
#
# Related:
#
@@ -29,6 +29,7 @@
# - Gem::Net::HTTP#get: sends +GET+ request, returns response object.
#
class Gem::Net::HTTP::Get < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'GET'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -51,15 +52,16 @@ class Gem::Net::HTTP::Get < Gem::Net::HTTPRequest
#
# - Request body: optional.
# - Response body: no.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
#
# Related:
#
# - Gem::Net::HTTP#head: sends +HEAD+ request, returns response object.
#
class Gem::Net::HTTP::Head < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'HEAD'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = false
@@ -85,9 +87,9 @@ class Gem::Net::HTTP::Head < Gem::Net::HTTPRequest
#
# - Request body: yes.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: no.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: no.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
#
# Related:
#
@@ -95,6 +97,7 @@ class Gem::Net::HTTP::Head < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#post: sends +POST+ request, returns response object.
#
class Gem::Net::HTTP::Post < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'POST'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -120,9 +123,9 @@ class Gem::Net::HTTP::Post < Gem::Net::HTTPRequest
#
# - Request body: yes.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
@@ -130,6 +133,7 @@ class Gem::Net::HTTP::Post < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#put: sends +PUT+ request, returns response object.
#
class Gem::Net::HTTP::Put < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'PUT'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -153,15 +157,16 @@ class Gem::Net::HTTP::Put < Gem::Net::HTTPRequest
#
# - Request body: optional.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
# - Gem::Net::HTTP#delete: sends +DELETE+ request, returns response object.
#
class Gem::Net::HTTP::Delete < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'DELETE'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -184,15 +189,16 @@ class Gem::Net::HTTP::Delete < Gem::Net::HTTPRequest
#
# - Request body: optional.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
# - Gem::Net::HTTP#options: sends +OPTIONS+ request, returns response object.
#
class Gem::Net::HTTP::Options < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'OPTIONS'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -215,15 +221,16 @@ class Gem::Net::HTTP::Options < Gem::Net::HTTPRequest
#
# - Request body: no.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
# - Gem::Net::HTTP#trace: sends +TRACE+ request, returns response object.
#
class Gem::Net::HTTP::Trace < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'TRACE'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -249,20 +256,56 @@ class Gem::Net::HTTP::Trace < Gem::Net::HTTPRequest
#
# - Request body: yes.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: no.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: no.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
# - Gem::Net::HTTP#patch: sends +PATCH+ request, returns response object.
#
class Gem::Net::HTTP::Patch < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'PATCH'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
end
+# \Class for representing
+# {HTTP method QUERY}[https://www.rfc-editor.org/rfc/rfc10008.html]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# uri.path = '/posts'
+# req = Gem::Net::HTTP::Query.new(uri) # => #
+# req.body = '{"title": "foo","body": "bar","userId": 1}'
+# req.content_type = 'application/json'
+# res = Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end
+#
+# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
+#
+# Properties:
+#
+# - Request body: yes.
+# - Response body: yes.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
+#
+# Related:
+#
+# - Gem::Net::HTTP#query: sends +QUERY+ request, returns response object.
+#
+class Gem::Net::HTTP::Query < Gem::Net::HTTPRequest
+ # :stopdoc:
+ METHOD = 'QUERY'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
+end
+
#
# WebDAV methods --- RFC2518
#
@@ -285,6 +328,7 @@ class Gem::Net::HTTP::Patch < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#propfind: sends +PROPFIND+ request, returns response object.
#
class Gem::Net::HTTP::Propfind < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'PROPFIND'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -308,6 +352,7 @@ class Gem::Net::HTTP::Propfind < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#proppatch: sends +PROPPATCH+ request, returns response object.
#
class Gem::Net::HTTP::Proppatch < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'PROPPATCH'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -331,6 +376,7 @@ class Gem::Net::HTTP::Proppatch < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#mkcol: sends +MKCOL+ request, returns response object.
#
class Gem::Net::HTTP::Mkcol < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'MKCOL'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -354,6 +400,7 @@ class Gem::Net::HTTP::Mkcol < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#copy: sends +COPY+ request, returns response object.
#
class Gem::Net::HTTP::Copy < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'COPY'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -377,6 +424,7 @@ class Gem::Net::HTTP::Copy < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#move: sends +MOVE+ request, returns response object.
#
class Gem::Net::HTTP::Move < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'MOVE'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -400,6 +448,7 @@ class Gem::Net::HTTP::Move < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#lock: sends +LOCK+ request, returns response object.
#
class Gem::Net::HTTP::Lock < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'LOCK'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -423,8 +472,8 @@ class Gem::Net::HTTP::Lock < Gem::Net::HTTPRequest
# - Gem::Net::HTTP#unlock: sends +UNLOCK+ request, returns response object.
#
class Gem::Net::HTTP::Unlock < Gem::Net::HTTPRequest
+ # :stopdoc:
METHOD = 'UNLOCK'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
end
-
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/response.rb b/lib/rubygems/vendor/net-http/lib/net/http/response.rb
index cbbd191d879b..61d8dc557724 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http/response.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http/response.rb
@@ -133,6 +133,13 @@
# there is a protocol error.
#
class Gem::Net::HTTPResponse
+ # The maximum total size in bytes of the response header.
+ MAX_RESPONSE_HEADER_LENGTH = 1024 * 1024 # 1 MiB
+
+ # The maximum number of informational (1xx) responses accepted before the
+ # final response.
+ MAX_INFORMATIONAL_RESPONSES = 100
+
class << self
# true if the response has a body.
def body_permitted?
@@ -152,10 +159,17 @@ def read_new(sock) #:nodoc: internal use only
res
end
+ def read_line(sock, limit, ignore_eof = false) #:nodoc: internal use only
+ sock.readuntil("\n", ignore_eof, limit: limit)
+ rescue Gem::Net::ReadLimitExceeded
+ raise Gem::Net::HTTPBadResponse, 'response line too long'
+ end
+
private
+ # :stopdoc:
def read_status_line(sock)
- str = sock.readline
+ str = read_line(sock, MAX_RESPONSE_HEADER_LENGTH).chop
m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)(?:\s+(.*))?\z/in.match(str) or
raise Gem::Net::HTTPBadResponse, "wrong status line: #{str.dump}"
m.captures
@@ -169,12 +183,19 @@ def response_class(code)
def each_response_header(sock)
key = value = nil
+ remaining = MAX_RESPONSE_HEADER_LENGTH
while true
- line = sock.readuntil("\n", true).sub(/\s+\z/, '')
+ line = read_line(sock, MAX_RESPONSE_HEADER_LENGTH, true)
+ remaining -= line.bytesize
+ raise Gem::Net::HTTPBadResponse, 'response header too large' if remaining < 0
+ line = line.chomp
break if line.empty?
if line[0] == ?\s or line[0] == ?\t and value
- value << ' ' unless value.empty?
- value << line.strip
+ folded = line.strip
+ unless folded.empty?
+ value << ' ' unless value.empty?
+ value << folded
+ end
else
yield key, value if key
key, value = line.strip.split(/\s*:\s*/, 2)
@@ -259,7 +280,7 @@ def body_encoding=(value)
# header.
attr_accessor :ignore_eof
- def inspect
+ def inspect # :nodoc:
"#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
end
@@ -598,15 +619,20 @@ def read_body_0(dest)
@socket = inflate_body_io
- clen = content_length()
- if clen
- @socket.read clen, dest, @ignore_eof
- return
- end
- clen = range_length()
- if clen
- @socket.read clen, dest
- return
+ # Transfer-Encoding overrides Content-Length, so a body that is not
+ # chunk-framed runs until the server closes the connection.
+ # See RFC 9112 Section 6.3.
+ unless @header['transfer-encoding']
+ clen = content_length()
+ if clen
+ @socket.read clen, dest, @ignore_eof
+ return
+ end
+ clen = range_length()
+ if clen
+ @socket.read clen, dest
+ return
+ end
end
@socket.read_all dest
end
@@ -622,7 +648,7 @@ def read_body_0(dest)
def read_chunked(dest, chunk_data_io) # :nodoc:
total = 0
while true
- line = @socket.readline
+ line = self.class.read_line(@socket, MAX_RESPONSE_HEADER_LENGTH).chop
hexlen = line.slice(/[0-9a-fA-F]+/) or
raise Gem::Net::HTTPBadResponse, "wrong chunk size line: #{line}"
len = hexlen.hex
@@ -634,7 +660,7 @@ def read_chunked(dest, chunk_data_io) # :nodoc:
@socket.read 2 # \r\n
end
end
- until @socket.readline.empty?
+ until self.class.read_line(@socket, MAX_RESPONSE_HEADER_LENGTH).chop.empty?
# none
end
end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/responses.rb b/lib/rubygems/vendor/net-http/lib/net/http/responses.rb
index 32738adc1442..62ce1cba1b29 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http/responses.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http/responses.rb
@@ -4,7 +4,9 @@
module Gem::Net
+ # Unknown HTTP response
class HTTPUnknownResponse < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPError #
end
@@ -19,6 +21,7 @@ class HTTPUnknownResponse < HTTPResponse
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#1xx_informational_response].
#
class HTTPInformation < HTTPResponse
+ # :stopdoc:
HAS_BODY = false
EXCEPTION_TYPE = HTTPError #
end
@@ -34,6 +37,7 @@ class HTTPInformation < HTTPResponse
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_success].
#
class HTTPSuccess < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPError #
end
@@ -49,6 +53,7 @@ class HTTPSuccess < HTTPResponse
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_redirection].
#
class HTTPRedirection < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPRetriableError #
end
@@ -63,6 +68,7 @@ class HTTPRedirection < HTTPResponse
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors].
#
class HTTPClientError < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPClientException #
end
@@ -77,6 +83,7 @@ class HTTPClientError < HTTPResponse
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_server_errors].
#
class HTTPServerError < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPFatalError #
end
@@ -94,6 +101,7 @@ class HTTPServerError < HTTPResponse
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#100].
#
class HTTPContinue < HTTPInformation
+ # :stopdoc:
HAS_BODY = false
end
@@ -111,6 +119,7 @@ class HTTPContinue < HTTPInformation
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#101].
#
class HTTPSwitchProtocol < HTTPInformation
+ # :stopdoc:
HAS_BODY = false
end
@@ -127,6 +136,7 @@ class HTTPSwitchProtocol < HTTPInformation
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#102].
#
class HTTPProcessing < HTTPInformation
+ # :stopdoc:
HAS_BODY = false
end
@@ -145,6 +155,7 @@ class HTTPProcessing < HTTPInformation
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#103].
#
class HTTPEarlyHints < HTTPInformation
+ # :stopdoc:
HAS_BODY = false
end
@@ -162,6 +173,7 @@ class HTTPEarlyHints < HTTPInformation
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#200].
#
class HTTPOK < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -179,6 +191,7 @@ class HTTPOK < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#201].
#
class HTTPCreated < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -196,6 +209,7 @@ class HTTPCreated < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#202].
#
class HTTPAccepted < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -215,6 +229,7 @@ class HTTPAccepted < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#203].
#
class HTTPNonAuthoritativeInformation < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -232,6 +247,7 @@ class HTTPNonAuthoritativeInformation < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#204].
#
class HTTPNoContent < HTTPSuccess
+ # :stopdoc:
HAS_BODY = false
end
@@ -250,6 +266,7 @@ class HTTPNoContent < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#205].
#
class HTTPResetContent < HTTPSuccess
+ # :stopdoc:
HAS_BODY = false
end
@@ -268,6 +285,7 @@ class HTTPResetContent < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#206].
#
class HTTPPartialContent < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -285,6 +303,7 @@ class HTTPPartialContent < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#207].
#
class HTTPMultiStatus < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -304,6 +323,7 @@ class HTTPMultiStatus < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#208].
#
class HTTPAlreadyReported < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -321,6 +341,7 @@ class HTTPAlreadyReported < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#226].
#
class HTTPIMUsed < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -338,6 +359,7 @@ class HTTPIMUsed < HTTPSuccess
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#300].
#
class HTTPMultipleChoices < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
HTTPMultipleChoice = HTTPMultipleChoices
@@ -356,6 +378,7 @@ class HTTPMultipleChoices < HTTPRedirection
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#301].
#
class HTTPMovedPermanently < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
@@ -373,6 +396,7 @@ class HTTPMovedPermanently < HTTPRedirection
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#302].
#
class HTTPFound < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
HTTPMovedTemporarily = HTTPFound
@@ -390,6 +414,7 @@ class HTTPFound < HTTPRedirection
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#303].
#
class HTTPSeeOther < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
@@ -407,6 +432,7 @@ class HTTPSeeOther < HTTPRedirection
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#304].
#
class HTTPNotModified < HTTPRedirection
+ # :stopdoc:
HAS_BODY = false
end
@@ -423,6 +449,7 @@ class HTTPNotModified < HTTPRedirection
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#305].
#
class HTTPUseProxy < HTTPRedirection
+ # :stopdoc:
HAS_BODY = false
end
@@ -440,6 +467,7 @@ class HTTPUseProxy < HTTPRedirection
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#307].
#
class HTTPTemporaryRedirect < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
@@ -456,6 +484,7 @@ class HTTPTemporaryRedirect < HTTPRedirection
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#308].
#
class HTTPPermanentRedirect < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
@@ -472,6 +501,7 @@ class HTTPPermanentRedirect < HTTPRedirection
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#400].
#
class HTTPBadRequest < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -488,6 +518,7 @@ class HTTPBadRequest < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#401].
#
class HTTPUnauthorized < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -504,6 +535,7 @@ class HTTPUnauthorized < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#402].
#
class HTTPPaymentRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -521,6 +553,7 @@ class HTTPPaymentRequired < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#403].
#
class HTTPForbidden < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -537,6 +570,7 @@ class HTTPForbidden < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#404].
#
class HTTPNotFound < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -553,6 +587,7 @@ class HTTPNotFound < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#405].
#
class HTTPMethodNotAllowed < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -570,6 +605,7 @@ class HTTPMethodNotAllowed < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#406].
#
class HTTPNotAcceptable < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -586,6 +622,7 @@ class HTTPNotAcceptable < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#407].
#
class HTTPProxyAuthenticationRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -602,6 +639,7 @@ class HTTPProxyAuthenticationRequired < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#408].
#
class HTTPRequestTimeout < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
HTTPRequestTimeOut = HTTPRequestTimeout
@@ -619,6 +657,7 @@ class HTTPRequestTimeout < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#409].
#
class HTTPConflict < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -636,6 +675,7 @@ class HTTPConflict < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#410].
#
class HTTPGone < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -653,6 +693,7 @@ class HTTPGone < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#411].
#
class HTTPLengthRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -670,6 +711,7 @@ class HTTPLengthRequired < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#412].
#
class HTTPPreconditionFailed < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -686,6 +728,7 @@ class HTTPPreconditionFailed < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#413].
#
class HTTPPayloadTooLarge < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
HTTPRequestEntityTooLarge = HTTPPayloadTooLarge
@@ -703,6 +746,7 @@ class HTTPPayloadTooLarge < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#414].
#
class HTTPURITooLong < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
HTTPRequestURITooLong = HTTPURITooLong
@@ -721,6 +765,7 @@ class HTTPURITooLong < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#415].
#
class HTTPUnsupportedMediaType < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -737,6 +782,7 @@ class HTTPUnsupportedMediaType < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#416].
#
class HTTPRangeNotSatisfiable < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
HTTPRequestedRangeNotSatisfiable = HTTPRangeNotSatisfiable
@@ -754,6 +800,7 @@ class HTTPRangeNotSatisfiable < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#417].
#
class HTTPExpectationFailed < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -774,6 +821,7 @@ class HTTPExpectationFailed < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#421].
#
class HTTPMisdirectedRequest < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -790,6 +838,7 @@ class HTTPMisdirectedRequest < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#422].
#
class HTTPUnprocessableEntity < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -805,6 +854,7 @@ class HTTPUnprocessableEntity < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#423].
#
class HTTPLocked < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -821,6 +871,7 @@ class HTTPLocked < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#424].
#
class HTTPFailedDependency < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -840,6 +891,7 @@ class HTTPFailedDependency < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#426].
#
class HTTPUpgradeRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -856,6 +908,7 @@ class HTTPUpgradeRequired < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#428].
#
class HTTPPreconditionRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -872,6 +925,7 @@ class HTTPPreconditionRequired < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#429].
#
class HTTPTooManyRequests < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -889,6 +943,7 @@ class HTTPTooManyRequests < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#431].
#
class HTTPRequestHeaderFieldsTooLarge < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -906,6 +961,7 @@ class HTTPRequestHeaderFieldsTooLarge < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#451].
#
class HTTPUnavailableForLegalReasons < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
# 444 No Response - Nginx
@@ -926,6 +982,7 @@ class HTTPUnavailableForLegalReasons < HTTPClientError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#500].
#
class HTTPInternalServerError < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -943,6 +1000,7 @@ class HTTPInternalServerError < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#501].
#
class HTTPNotImplemented < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -960,6 +1018,7 @@ class HTTPNotImplemented < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#502].
#
class HTTPBadGateway < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -977,6 +1036,7 @@ class HTTPBadGateway < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#503].
#
class HTTPServiceUnavailable < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -994,6 +1054,7 @@ class HTTPServiceUnavailable < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#504].
#
class HTTPGatewayTimeout < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
HTTPGatewayTimeOut = HTTPGatewayTimeout
@@ -1011,6 +1072,7 @@ class HTTPGatewayTimeout < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#505].
#
class HTTPVersionNotSupported < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -1027,6 +1089,7 @@ class HTTPVersionNotSupported < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#506].
#
class HTTPVariantAlsoNegotiates < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -1043,6 +1106,7 @@ class HTTPVariantAlsoNegotiates < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#507].
#
class HTTPInsufficientStorage < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -1059,6 +1123,7 @@ class HTTPInsufficientStorage < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#508].
#
class HTTPLoopDetected < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
# 509 Bandwidth Limit Exceeded - Apache bw/limited extension
@@ -1076,6 +1141,7 @@ class HTTPLoopDetected < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#510].
#
class HTTPNotExtended < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -1092,12 +1158,14 @@ class HTTPNotExtended < HTTPServerError
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#511].
#
class HTTPNetworkAuthenticationRequired < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
end
class Gem::Net::HTTPResponse
+ # :stopdoc:
CODE_CLASS_TO_OBJ = {
'1' => Gem::Net::HTTPInformation,
'2' => Gem::Net::HTTPSuccess,
diff --git a/lib/rubygems/vendor/net-protocol/COPYING b/lib/rubygems/vendor/net-protocol/COPYING
new file mode 100644
index 000000000000..48e5a96de7c8
--- /dev/null
+++ b/lib/rubygems/vendor/net-protocol/COPYING
@@ -0,0 +1,56 @@
+Ruby is copyrighted free software by Yukihiro Matsumoto .
+You can redistribute it and/or modify it under either the terms of the
+2-clause BSDL (see the file BSDL), or the conditions below:
+
+1. You may make and give away verbatim copies of the source form of the
+ software without restriction, provided that you duplicate all of the
+ original copyright notices and associated disclaimers.
+
+2. You may modify your copy of the software in any way, provided that
+ you do at least ONE of the following:
+
+ a. place your modifications in the Public Domain or otherwise
+ make them Freely Available, such as by posting said
+ modifications to Usenet or an equivalent medium, or by allowing
+ the author to include your modifications in the software.
+
+ b. use the modified software only within your corporation or
+ organization.
+
+ c. give non-standard binaries non-standard names, with
+ instructions on where to get the original software distribution.
+
+ d. make other distribution arrangements with the author.
+
+3. You may distribute the software in object code or binary form,
+ provided that you do at least ONE of the following:
+
+ a. distribute the binaries and library files of the software,
+ together with instructions (in the manual page or equivalent)
+ on where to get the original distribution.
+
+ b. accompany the distribution with the machine-readable source of
+ the software.
+
+ c. give non-standard binaries non-standard names, with
+ instructions on where to get the original software distribution.
+
+ d. make other distribution arrangements with the author.
+
+4. You may modify and include the part of the software into any other
+ software (possibly commercial). But some files in the distribution
+ are not written by the author, so that they are not under these terms.
+
+ For the list of those files and their copying conditions, see the
+ file LEGAL.
+
+5. The scripts and library files supplied as input to or produced as
+ output from the software do not automatically fall under the
+ copyright of the software, but belong to whomever generated them,
+ and may be sold commercially, and may be aggregated with this
+ software.
+
+6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE.
diff --git a/lib/rubygems/vendor/net-protocol/LICENSE.txt b/lib/rubygems/vendor/net-protocol/LICENSE.txt
deleted file mode 100644
index a009caefea81..000000000000
--- a/lib/rubygems/vendor/net-protocol/LICENSE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
diff --git a/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb b/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb
index 53d34d8d98eb..3c803fefe5d7 100644
--- a/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb
+++ b/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb
@@ -21,12 +21,12 @@
require 'socket'
require_relative '../../../timeout/lib/timeout'
-require 'io/wait'
+require 'io/wait' if RUBY_VERSION < '3.2'
module Gem::Net # :nodoc:
class Protocol #:nodoc: internal use only
- VERSION = "0.2.2"
+ VERSION = "0.4.0"
private
def Protocol.protocol_param(name, val)
@@ -54,9 +54,20 @@ def ssl_socket_connect(s, timeout)
s.connect
end
end
+
+ tcp_socket_parameters = TCPSocket.instance_method(:initialize).parameters
+ TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT = if tcp_socket_parameters != [[:rest]]
+ tcp_socket_parameters.include?([:key, :open_timeout])
+ else
+ # Use Socket.tcp to find out since there is no parameters information for TCPSocket#initialize
+ # See discussion in https://github.com/ruby/net-http/pull/224
+ Socket.method(:tcp).parameters.include?([:key, :open_timeout])
+ end
+ private_constant :TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
end
+ # :stopdoc:
class ProtocolError < StandardError; end
class ProtoSyntaxError < ProtocolError; end
class ProtoFatalError < ProtocolError; end
@@ -66,6 +77,29 @@ class ProtoAuthError < ProtocolError; end
class ProtoCommandError < ProtocolError; end
class ProtoRetriableError < ProtocolError; end
ProtocRetryError = ProtoRetriableError
+ # :startdoc:
+
+ ##
+ # ReadLimitExceeded, a subclass of ProtocolError, is raised if the
+ # terminator is not found within the byte limit given to
+ # Gem::Net::BufferedIO#readuntil.
+ #
+ # The limit is the largest result readuntil may return, counting the
+ # terminator itself, so a limit of 4 accepts "abc\n" and rejects
+ # "abcd\n". Unlike the limit of IO#gets it never truncates a result to
+ # fit. Either the whole thing comes back or this is raised, except
+ # under ignore_eof, which still returns what was buffered when the
+ # stream ended. The count is in bytes while the IO hands back binary
+ # strings, which every real one does.
+ #
+ # It bounds one call, not a connection. The unconsumed buffer can
+ # still run one BUFSIZE past the limit, and a peer sending endless
+ # short lines is not bounded at all.
+ #
+ # Nothing is consumed when this is raised, so the usual response is to
+ # close the connection rather than read on under a wider limit.
+
+ class ReadLimitExceeded < ProtocolError; end
##
# OpenTimeout, a subclass of Gem::Timeout::Error, is raised if a connection cannot
@@ -78,6 +112,7 @@ class OpenTimeout < Gem::Timeout::Error; end
# response cannot be read within the read_timeout.
class ReadTimeout < Gem::Timeout::Error
+ # :stopdoc:
def initialize(io = nil)
@io = io
end
@@ -97,6 +132,7 @@ def message
# response cannot be written within the write_timeout. Not raised on Windows.
class WriteTimeout < Gem::Timeout::Error
+ # :stopdoc:
def initialize(io = nil)
@io = io
end
@@ -153,6 +189,7 @@ def close
public
def read(len, dest = ''.b, ignore_eof = false)
+ raise ArgumentError, "negative length #{len} given" if len < 0
LOG "reading #{len} bytes..."
read_bytes = 0
begin
@@ -191,14 +228,31 @@ def read_all(dest = ''.b)
dest
end
- def readuntil(terminator, ignore_eof = false)
+ def readuntil(terminator, ignore_eof = false, limit: nil)
+ unless limit.nil? || (Integer === limit && limit > 0)
+ # Integer === calls nothing on limit, and only an Integer is
+ # echoed back, so validation never runs the caller's code.
+ got = Integer === limit ? limit : "a non-Integer"
+ raise ArgumentError, "limit must be a positive Integer, got #{got}"
+ end
offset = @rbuf_offset
begin
until idx = @rbuf.index(terminator, offset)
- offset = @rbuf.bytesize
+ if limit && rbuf_size > limit
+ raise ReadLimitExceeded, "exceeded the #{limit} byte read limit"
+ end
+ # Rewind so a terminator split across reads is still found. The
+ # floor guards two things. String#index reads a negative offset
+ # as counting from the end, and an offset below @rbuf_offset
+ # matches inside bytes already returned.
+ offset = [@rbuf.bytesize - terminator.bytesize + 1, @rbuf_offset].max
rbuf_fill
end
- return rbuf_consume(idx + terminator.bytesize - @rbuf_offset)
+ len = idx + terminator.bytesize - @rbuf_offset
+ if limit && len > limit
+ raise ReadLimitExceeded, "exceeded the #{limit} byte read limit"
+ end
+ return rbuf_consume(len)
rescue EOFError
raise unless ignore_eof
return rbuf_consume
@@ -303,9 +357,9 @@ def writing
@debug_output << '<- ' if @debug_output
yield
@debug_output << "\n" if @debug_output
- bytes = @written_bytes
+ @written_bytes
+ ensure
@written_bytes = nil
- bytes
end
def write0(*strs)
@@ -331,6 +385,9 @@ def write0(*strs)
# next string
end
# continue looping
+ when :wait_readable
+ (io = @io.to_io).wait_readable(@write_timeout) or raise Gem::Net::WriteTimeout.new(io)
+ # continue looping
when :wait_writable
(io = @io.to_io).wait_writable(@write_timeout) or raise Gem::Net::WriteTimeout.new(io)
# continue looping
@@ -373,12 +430,15 @@ def initialize(*, **)
def each_message_chunk
LOG 'reading message...'
LOG_off()
- read_bytes = 0
- while (line = readuntil("\r\n")) != ".\r\n"
- read_bytes += line.size
- yield line.delete_prefix('.')
+ begin
+ read_bytes = 0
+ while (line = readuntil("\r\n")) != ".\r\n"
+ read_bytes += line.size
+ yield line.delete_prefix('.')
+ end
+ ensure
+ LOG_on()
end
- LOG_on()
LOG "read message (#{read_bytes} bytes)"
end
@@ -404,12 +464,15 @@ def write_message_0(src)
def write_message(src)
LOG "writing message from #{src.class}"
LOG_off()
- len = writing {
- using_each_crlf_line {
- write_message_0 src
+ begin
+ len = writing {
+ using_each_crlf_line {
+ write_message_0 src
+ }
}
- }
- LOG_on()
+ ensure
+ LOG_on()
+ end
LOG "wrote #{len} bytes"
len
end
@@ -417,16 +480,19 @@ def write_message(src)
def write_message_by_block(&block)
LOG 'writing message from block'
LOG_off()
- len = writing {
- using_each_crlf_line {
- begin
- block.call(WriteAdapter.new(self.method(:write_message_0)))
- rescue LocalJumpError
- # allow `break' from writer block
- end
+ begin
+ len = writing {
+ using_each_crlf_line {
+ begin
+ block.call(WriteAdapter.new(self.method(:write_message_0)))
+ rescue LocalJumpError
+ # allow `break' from writer block
+ end
+ }
}
- }
- LOG_on()
+ ensure
+ LOG_on()
+ end
LOG "wrote #{len} bytes"
len
end
@@ -446,6 +512,8 @@ def using_each_crlf_line
write0 "\r\n"
end
write0 ".\r\n"
+ nil
+ ensure
@wbuf = nil
end
@@ -484,6 +552,7 @@ def buffer_filling(buf, src)
# The writer adapter class
#
class WriteAdapter
+ # :stopdoc:
def initialize(writer)
@writer = writer
end
diff --git a/lib/rubygems/vendor/optparse/lib/optparse.rb b/lib/rubygems/vendor/optparse/lib/optparse.rb
index d39d9dd4e02f..66d5fe390e8f 100644
--- a/lib/rubygems/vendor/optparse/lib/optparse.rb
+++ b/lib/rubygems/vendor/optparse/lib/optparse.rb
@@ -426,8 +426,9 @@
#
class Gem::OptionParser
# The version string
- VERSION = "0.8.0"
- Version = VERSION # for compatibility
+ VERSION = "0.8.1"
+ # An alias for compatibility
+ Version = VERSION
# :stopdoc:
NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
@@ -471,7 +472,6 @@ def candidate(key, icase = false, pat = nil, &_)
Completion.candidate(key, icase, pat, &method(:each))
end
- public
def complete(key, icase = false, pat = nil)
candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size}
if candidates.size == 1
@@ -561,7 +561,7 @@ def initialize(pattern = nil, conv = nil,
# Parses +arg+ and returns rest of +arg+ and matched portion to the
# argument pattern. Yields when the pattern doesn't match substring.
#
- def parse_arg(arg) # :nodoc:
+ private def parse_arg(arg) # :nodoc:
pattern or return nil, [arg]
unless m = pattern.match(arg)
yield(InvalidArgument, arg)
@@ -579,14 +579,13 @@ def parse_arg(arg) # :nodoc:
yield(InvalidArgument, arg) # didn't match whole arg
return arg[s.length..-1], m
end
- private :parse_arg
#
# Parses argument, converts and returns +arg+, +block+ and result of
# conversion. Yields at semi-error condition instead of raising an
# exception.
#
- def conv_arg(arg, val = []) # :nodoc:
+ private def conv_arg(arg, val = []) # :nodoc:
v, = *val
if conv
val = conv.call(*val)
@@ -598,7 +597,6 @@ def conv_arg(arg, val = []) # :nodoc:
end
return arg, block, val
end
- private :conv_arg
#
# Produces the summary text. Each line of the summary is yielded to the
@@ -882,14 +880,13 @@ def reject(t)
# +lopts+:: Long style option list.
# +nlopts+:: Negated long style options list.
#
- def update(sw, sopts, lopts, nsw = nil, nlopts = nil) # :nodoc:
+ private def update(sw, sopts, lopts, nsw = nil, nlopts = nil) # :nodoc:
sopts.each {|o| @short[o] = sw} if sopts
lopts.each {|o| @long[o] = sw} if lopts
nlopts.each {|o| @long[o] = nsw} if nsw and nlopts
used = @short.invert.update(@long.invert)
@list.delete_if {|o| Switch === o and !used[o]}
end
- private :update
#
# Inserts +switch+ at the head of the list, and associates short, long
@@ -1458,14 +1455,13 @@ def to_a; summarize("#{banner}".split(/^/)) end
# +prv+:: Previously specified argument.
# +msg+:: Exception message.
#
- def notwice(obj, prv, msg) # :nodoc:
+ private def notwice(obj, prv, msg) # :nodoc:
unless !prv or prv == obj
raise(ArgumentError, "argument #{msg} given twice: #{obj}",
ParseError.filter_backtrace(caller(2)))
end
obj
end
- private :notwice
SPLAT_PROC = proc {|*a| a.length <= 1 ? a.first : a} # :nodoc:
@@ -1732,7 +1728,7 @@ def order!(argv = default_argv, into: nil, **keywords, &nonopt)
parse_in_order(argv, setter, **keywords, &nonopt)
end
- def parse_in_order(argv = default_argv, setter = nil, exact: require_exact, **, &nonopt) # :nodoc:
+ private def parse_in_order(argv = default_argv, setter = nil, exact: require_exact, **, &nonopt) # :nodoc:
opt, arg, val, rest = nil
nonopt ||= proc {|a| throw :terminate, a}
argv.unshift(arg) if arg = catch(:terminate) {
@@ -1823,10 +1819,9 @@ def parse_in_order(argv = default_argv, setter = nil, exact: require_exact, **,
argv
end
- private :parse_in_order
# Calls callback with _val_.
- def callback!(cb, max_arity, *args) # :nodoc:
+ private def callback!(cb, max_arity, *args) # :nodoc:
args.compact!
if (size = args.size) < max_arity and cb.to_proc.lambda?
@@ -1836,7 +1831,6 @@ def callback!(cb, max_arity, *args) # :nodoc:
end
cb.call(*args)
end
- private :callback!
#
# Parses command line arguments +argv+ in permutation mode and returns
@@ -1950,24 +1944,22 @@ def self.getopts(*args, symbolize_names: false)
# Traverses @stack, sending each element method +id+ with +args+ and
# +block+.
#
- def visit(id, *args, &block) # :nodoc:
+ private def visit(id, *args, &block) # :nodoc:
@stack.reverse_each do |el|
el.__send__(id, *args, &block)
end
nil
end
- private :visit
#
# Searches +key+ in @stack for +id+ hash and returns or yields the result.
#
- def search(id, key) # :nodoc:
+ private def search(id, key) # :nodoc:
block_given = block_given?
visit(:search, id, key) do |k|
return block_given ? yield(k) : k
end
end
- private :search
#
# Completes shortened long style option switch and returns pair of
@@ -1978,7 +1970,7 @@ def search(id, key) # :nodoc:
# +icase+:: Search case insensitive if true.
# +pat+:: Optional pattern for completion.
#
- def complete(typ, opt, icase = false, *pat) # :nodoc:
+ private def complete(typ, opt, icase = false, *pat) # :nodoc:
if pat.empty?
search(typ, opt) {|sw| return [sw, opt]} # exact match or...
end
@@ -1988,7 +1980,6 @@ def complete(typ, opt, icase = false, *pat) # :nodoc:
exc = ambiguous ? AmbiguousOption : InvalidOption
raise exc.new(opt, additional: proc {|o| additional_message(typ, o)})
end
- private :complete
#
# Returns additional info.
@@ -2323,42 +2314,42 @@ def message
# Raises when ambiguously completable string is encountered.
#
class AmbiguousOption < ParseError
- const_set(:Reason, 'ambiguous option')
+ Reason = 'ambiguous option' # :nodoc:
end
#
# Raises when there is an argument for a switch which takes no argument.
#
class NeedlessArgument < ParseError
- const_set(:Reason, 'needless argument')
+ Reason = 'needless argument' # :nodoc:
end
#
# Raises when a switch with mandatory argument has no argument.
#
class MissingArgument < ParseError
- const_set(:Reason, 'missing argument')
+ Reason = 'missing argument' # :nodoc:
end
#
# Raises when switch is undefined.
#
class InvalidOption < ParseError
- const_set(:Reason, 'invalid option')
+ Reason = 'invalid option' # :nodoc:
end
#
# Raises when the given argument does not match required format.
#
class InvalidArgument < ParseError
- const_set(:Reason, 'invalid argument')
+ Reason = 'invalid argument' # :nodoc:
end
#
# Raises when the given argument word can't be completed uniquely.
#
class AmbiguousArgument < InvalidArgument
- const_set(:Reason, 'ambiguous argument')
+ Reason = 'ambiguous argument' # :nodoc:
end
#
@@ -2457,9 +2448,11 @@ def initialize(*args) # :nodoc:
# and DecimalNumeric. See Acceptable argument classes (in source code).
#
module Acceptables
- const_set(:DecimalInteger, Gem::OptionParser::DecimalInteger)
- const_set(:OctalInteger, Gem::OptionParser::OctalInteger)
- const_set(:DecimalNumeric, Gem::OptionParser::DecimalNumeric)
+ # :stopdoc:
+ DecimalInteger = Gem::OptionParser::DecimalInteger
+ OctalInteger = Gem::OptionParser::OctalInteger
+ DecimalNumeric = Gem::OptionParser::DecimalNumeric
+ # :startdoc:
end
end
diff --git a/lib/rubygems/vendor/timeout/lib/timeout.rb b/lib/rubygems/vendor/timeout/lib/timeout.rb
index 376b8c0e2b9e..5235bc98460b 100644
--- a/lib/rubygems/vendor/timeout/lib/timeout.rb
+++ b/lib/rubygems/vendor/timeout/lib/timeout.rb
@@ -20,9 +20,9 @@
module Gem::Timeout
# The version
- VERSION = "0.4.4"
+ VERSION = "0.6.1"
- # Internal error raised to when a timeout is triggered.
+ # Internal exception raised to when a timeout is triggered.
class ExitException < Exception
def exception(*) # :nodoc:
self
@@ -44,12 +44,101 @@ def self.handle_timeout(message) # :nodoc:
end
# :stopdoc:
- CONDVAR = ConditionVariable.new
- QUEUE = Queue.new
- QUEUE_MUTEX = Mutex.new
- TIMEOUT_THREAD_MUTEX = Mutex.new
- @timeout_thread = nil
- private_constant :CONDVAR, :QUEUE, :QUEUE_MUTEX, :TIMEOUT_THREAD_MUTEX
+
+ # We keep a private reference so that time mocking libraries won't break Gem::Timeout.
+ GET_TIME = Process.method(:clock_gettime)
+ if defined?(Ractor.make_shareable)
+ # Ractor.make_shareable(Method) only works on Ruby 4+
+ Ractor.make_shareable(GET_TIME) rescue nil
+ end
+ private_constant :GET_TIME
+
+ class State
+ def initialize
+ @condvar = ConditionVariable.new
+ @queue = Queue.new
+ @queue_mutex = Mutex.new
+
+ @timeout_thread = nil
+ @timeout_thread_mutex = Mutex.new
+ end
+
+ if defined?(Ractor.store_if_absent) && defined?(Ractor.shareable?) && Ractor.shareable?(GET_TIME)
+ # Ractor support if
+ # 1. Ractor.store_if_absent is available
+ # 2. Method object can be shareable (4.0~)
+ def self.instance
+ Ractor.store_if_absent :timeout_gem_state do
+ State.new
+ end
+ end
+ else
+ GLOBAL_STATE = State.new
+
+ def self.instance
+ GLOBAL_STATE
+ end
+ end
+
+ def create_timeout_thread
+ # Threads unexpectedly inherit the interrupt mask: https://github.com/ruby/timeout/issues/41
+ # So reset the interrupt mask to the default one for the timeout thread
+ Thread.handle_interrupt(Object => :immediate) do
+ watcher = Thread.new do
+ requests = []
+ while true
+ until @queue.empty? and !requests.empty? # wait to have at least one request
+ req = @queue.pop
+ requests << req unless req.done?
+ end
+ closest_deadline = requests.min_by(&:deadline).deadline
+
+ now = 0.0
+ @queue_mutex.synchronize do
+ while (now = GET_TIME.call(Process::CLOCK_MONOTONIC)) < closest_deadline and @queue.empty?
+ @condvar.wait(@queue_mutex, closest_deadline - now)
+ end
+ end
+
+ requests.each do |req|
+ req.interrupt if req.expired?(now)
+ end
+ requests.reject!(&:done?)
+ end
+ end
+
+ if !watcher.group.enclosed? && (!defined?(Ractor.main?) || Ractor.main?)
+ ThreadGroup::Default.add(watcher)
+ end
+
+ watcher.name = "Gem::Timeout stdlib thread"
+ watcher.thread_variable_set(:"\0__detached_thread__", true)
+ watcher
+ end
+ end
+
+ def ensure_timeout_thread_created
+ unless @timeout_thread&.alive?
+ # If the Mutex is already owned we are in a signal handler.
+ # In that case, just return and let the main thread create the Gem::Timeout thread.
+ return if @timeout_thread_mutex.owned?
+
+ Sync.synchronize @timeout_thread_mutex do
+ unless @timeout_thread&.alive?
+ @timeout_thread = create_timeout_thread
+ end
+ end
+ end
+ end
+
+ def add_request(request)
+ Sync.synchronize @queue_mutex do
+ @queue << request
+ @condvar.signal
+ end
+ end
+ end
+ private_constant :State
class Request
attr_reader :deadline
@@ -64,6 +153,7 @@ def initialize(thread, timeout, exception_class, message)
@done = false # protected by @mutex
end
+ # Only called by the timeout thread, so does not need Sync.synchronize
def done?
@mutex.synchronize do
@done
@@ -74,6 +164,7 @@ def expired?(now)
now >= @deadline
end
+ # Only called by the timeout thread, so does not need Sync.synchronize
def interrupt
@mutex.synchronize do
unless @done
@@ -84,64 +175,36 @@ def interrupt
end
def finished
- @mutex.synchronize do
+ Sync.synchronize @mutex do
@done = true
end
end
end
private_constant :Request
- def self.create_timeout_thread
- watcher = Thread.new do
- requests = []
- while true
- until QUEUE.empty? and !requests.empty? # wait to have at least one request
- req = QUEUE.pop
- requests << req unless req.done?
- end
- closest_deadline = requests.min_by(&:deadline).deadline
-
- now = 0.0
- QUEUE_MUTEX.synchronize do
- while (now = GET_TIME.call(Process::CLOCK_MONOTONIC)) < closest_deadline and QUEUE.empty?
- CONDVAR.wait(QUEUE_MUTEX, closest_deadline - now)
- end
- end
-
- requests.each do |req|
- req.interrupt if req.expired?(now)
- end
- requests.reject!(&:done?)
- end
- end
- ThreadGroup::Default.add(watcher) unless watcher.group.enclosed?
- watcher.name = "Gem::Timeout stdlib thread"
- watcher.thread_variable_set(:"\0__detached_thread__", true)
- watcher
- end
- private_class_method :create_timeout_thread
-
- def self.ensure_timeout_thread_created
- unless @timeout_thread and @timeout_thread.alive?
- # If the Mutex is already owned we are in a signal handler.
- # In that case, just return and let the main thread create the @timeout_thread.
- return if TIMEOUT_THREAD_MUTEX.owned?
- TIMEOUT_THREAD_MUTEX.synchronize do
- unless @timeout_thread and @timeout_thread.alive?
- @timeout_thread = create_timeout_thread
- end
+ module Sync
+ # Calls mutex.synchronize(&block) but if that fails on CRuby due to being in a trap handler,
+ # run mutex.synchronize(&block) in a separate Thread instead.
+ def self.synchronize(mutex, &block)
+ begin
+ mutex.synchronize(&block)
+ rescue ThreadError => e
+ raise e unless e.message == "can't be called from trap context"
+ # Workaround CRuby issue https://bugs.ruby-lang.org/issues/19473
+ # which raises on Mutex#synchronize in trap handler.
+ # It's expensive to create a Thread just for this,
+ # but better than failing.
+ Thread.new {
+ mutex.synchronize(&block)
+ }.join
end
end
end
-
- # We keep a private reference so that time mocking libraries won't break
- # Gem::Timeout.
- GET_TIME = Process.method(:clock_gettime)
- private_constant :GET_TIME
+ private_constant :Sync
# :startdoc:
- # Perform an operation in a block, raising an error if it takes longer than
+ # Perform an operation in a block, raising an exception if it takes longer than
# +sec+ seconds to complete.
#
# +sec+:: Number of seconds to wait for the block to terminate. Any non-negative number
@@ -149,45 +212,91 @@ def self.ensure_timeout_thread_created
# value of 0 or +nil+ will execute the block without any timeout.
# Any negative number will raise an ArgumentError.
# +klass+:: Exception Class to raise if the block fails to terminate
- # in +sec+ seconds. Omitting will use the default, Gem::Timeout::Error
+ # in +sec+ seconds. Omitting will use the default, Gem::Timeout::Error.
# +message+:: Error message to raise with Exception Class.
- # Omitting will use the default, "execution expired"
+ # Omitting will use the default, "execution expired".
#
# Returns the result of the block *if* the block completed before
- # +sec+ seconds, otherwise throws an exception, based on the value of +klass+.
+ # +sec+ seconds, otherwise raises an exception, based on the value of +klass+.
+ #
+ # The exception raised to terminate the given block is the given +klass+, or
+ # Gem::Timeout::ExitException if +klass+ is not given. The reason for that behavior
+ # is that Gem::Timeout::Error inherits from RuntimeError and might be caught unexpectedly by +rescue+.
+ # Gem::Timeout::ExitException inherits from Exception so it will only be rescued by rescue Exception.
+ # Note that the Gem::Timeout::ExitException is translated to a Gem::Timeout::Error once it reaches the Gem::Timeout.timeout call,
+ # so outside that call it will be a Gem::Timeout::Error.
#
- # The exception thrown to terminate the given block cannot be rescued inside
- # the block unless +klass+ is given explicitly. However, the block can use
- # ensure to prevent the handling of the exception. For that reason, this
- # method cannot be relied on to enforce timeouts for untrusted blocks.
+ # In general, be aware that the code block may rescue the exception, and in such a case not respect the timeout.
+ # Also, the block can use +ensure+ to prevent the handling of the exception.
+ # For those reasons, this method cannot be relied on to enforce timeouts for untrusted blocks.
#
# If a scheduler is defined, it will be used to handle the timeout by invoking
- # Scheduler#timeout_after.
+ # Fiber::Scheduler#timeout_after.
#
# Note that this is both a method of module Gem::Timeout, so you can include
# Gem::Timeout into your classes so they have a #timeout method, as well as
# a module method, so you can call it directly as Gem::Timeout.timeout().
- def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
+ #
+ # ==== Ensuring the exception does not fire inside ensure blocks
+ #
+ # When using Gem::Timeout.timeout, it can be desirable to ensure the timeout exception does not fire inside an +ensure+ block.
+ # The simplest and best way to do so is to put the Gem::Timeout.timeout call inside the body of the +begin+/+ensure+/+end+:
+ #
+ # begin
+ # Gem::Timeout.timeout(sec) { some_long_operation }
+ # ensure
+ # cleanup # safe, cannot be interrupted by timeout
+ # end
+ #
+ # If that is not feasible, e.g. if there are +ensure+ blocks inside +some_long_operation+,
+ # they need to not be interrupted by timeout, and it's not possible to move these ensure blocks outside,
+ # one can use Thread.handle_interrupt to delay the timeout exception like so:
+ #
+ # Thread.handle_interrupt(Gem::Timeout::Error => :never) {
+ # Gem::Timeout.timeout(sec, Gem::Timeout::Error) do
+ # setup # timeout cannot happen here, no matter how long it takes
+ # Thread.handle_interrupt(Gem::Timeout::Error => :immediate) {
+ # some_long_operation # timeout can happen here
+ # }
+ # ensure
+ # cleanup # timeout cannot happen here, no matter how long it takes
+ # end
+ # }
+ #
+ # An important thing to note is the need to pass an exception +klass+ to Gem::Timeout.timeout,
+ # otherwise it does not work. Specifically, using Thread.handle_interrupt(Gem::Timeout::ExitException => ...)
+ # is unsupported and causes subtle errors like raising the wrong exception outside the block, do not use that.
+ #
+ # Note that Thread.handle_interrupt is somewhat dangerous because if setup or cleanup hangs
+ # then the current thread will hang too and the timeout will never fire.
+ # Also note the block might run for longer than +sec+ seconds:
+ # e.g. +some_long_operation+ executes for +sec+ seconds + whatever time cleanup takes.
+ #
+ # If you want the timeout to only happen on blocking operations, one can use +:on_blocking+
+ # instead of +:immediate+. However, that means if the block uses no blocking operations after +sec+ seconds,
+ # the block will not be interrupted.
+ def self.timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
return yield(sec) if sec == nil or sec.zero?
raise ArgumentError, "Timeout sec must be a non-negative number" if 0 > sec
message ||= "execution expired"
if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after)
- return scheduler.timeout_after(sec, klass || Error, message, &block)
- end
-
- Gem::Timeout.ensure_timeout_thread_created
- perform = Proc.new do |exc|
- request = Request.new(Thread.current, sec, exc, message)
- QUEUE_MUTEX.synchronize do
- QUEUE << request
- CONDVAR.signal
+ perform = Proc.new do |exc|
+ scheduler.timeout_after(sec, exc, message, &block)
end
- begin
- return yield(sec)
- ensure
- request.finished
+ else
+ state = State.instance
+ state.ensure_timeout_thread_created
+
+ perform = Proc.new do |exc|
+ request = Request.new(Thread.current, sec, exc, message)
+ state.add_request(request)
+ begin
+ return yield(sec)
+ ensure
+ request.finished
+ end
end
end
@@ -197,5 +306,9 @@ def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
Error.handle_timeout(message, &perform)
end
end
- module_function :timeout
+
+ # See Gem::Timeout.timeout
+ private def timeout(*args, &block)
+ Gem::Timeout.timeout(*args, &block)
+ end
end
diff --git a/lib/rubygems/vendor/uri/lib/uri/common.rb b/lib/rubygems/vendor/uri/lib/uri/common.rb
index f6c7b1bd0469..b648d9b8ca6f 100644
--- a/lib/rubygems/vendor/uri/lib/uri/common.rb
+++ b/lib/rubygems/vendor/uri/lib/uri/common.rb
@@ -271,7 +271,7 @@ def self.parse(uri)
# # => #
#
def self.join(*str)
- DEFAULT_PARSER.join(*str)
+ PARSER.join(*str)
end
#
diff --git a/lib/rubygems/vendor/uri/lib/uri/generic.rb b/lib/rubygems/vendor/uri/lib/uri/generic.rb
index d0bc77dfda28..e1b14f43fdbb 100644
--- a/lib/rubygems/vendor/uri/lib/uri/generic.rb
+++ b/lib/rubygems/vendor/uri/lib/uri/generic.rb
@@ -466,7 +466,7 @@ def userinfo=(userinfo)
#
# uri = Gem::URI.parse("http://john:S3nsit1ve@my.example.com")
# uri.user = "sam"
- # uri.to_s #=> "http://sam:V3ry_S3nsit1ve@my.example.com"
+ # uri.to_s #=> "http://sam@my.example.com"
#
def user=(user)
check_user(user)
@@ -1021,9 +1021,21 @@ def merge_path(base, rel)
# RFC2396, Section 5.2, 6), a)
base_path << '' if base_path.last == '..'
- while i = base_path.index('..')
- base_path.slice!(i - 1, 2)
+ # Remove "/.." pairs in a single left-to-right pass (O(n)).
+ # This deliberately differs from the relative-path stack handling
+ # below: a leading ".." (one with no preceding segment left to
+ # cancel) discards the whole base path, reproducing the previous
+ # index/slice! implementation exactly.
+ reduced = []
+ base_path.each do |seg|
+ if seg == '..'
+ break if reduced.empty?
+ reduced.pop
+ else
+ reduced << seg
+ end
end
+ base_path = reduced
if (first = rel_path.first) and first.empty?
base_path.clear
diff --git a/lib/rubygems/vendor/uri/lib/uri/version.rb b/lib/rubygems/vendor/uri/lib/uri/version.rb
index 7ee577887b37..56c7229bd672 100644
--- a/lib/rubygems/vendor/uri/lib/uri/version.rb
+++ b/lib/rubygems/vendor/uri/lib/uri/version.rb
@@ -1,6 +1,6 @@
module Gem::URI
# :stopdoc:
- VERSION = '1.1.1'.freeze
+ VERSION = '1.1.2'.freeze
VERSION_CODE = VERSION.split('.').map{|s| s.rjust(2, '0')}.join.freeze
# :startdoc:
end
diff --git a/tool/automatiek/net-http-persistent-v4.0.6.patch b/tool/automatiek/net-http-persistent-v4.0.8.patch
similarity index 60%
rename from tool/automatiek/net-http-persistent-v4.0.6.patch
rename to tool/automatiek/net-http-persistent-v4.0.8.patch
index 65867aefdc8b..c9740ed36fc2 100644
--- a/tool/automatiek/net-http-persistent-v4.0.6.patch
+++ b/tool/automatiek/net-http-persistent-v4.0.8.patch
@@ -1,29 +1,29 @@
diff --git b/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb a/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
-index f57e64df9c..52a8051183 100644
--- b/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
+++ a/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb
-@@ -1,12 +1,11 @@
+@@ -1,14 +1,9 @@
-require_relative '../../../../../../../../lib/rubygems/vendor/net-http/lib/net/http'
-require_relative '../../../../../../../../lib/rubygems/vendor/uri/lib/uri'
--require 'cgi' # for escaping
--require_relative '../../../../connection_pool/lib/connection_pool'
--
+require_relative '../../../../../vendored_net_http'
+require_relative '../../../../../vendored_uri'
- begin
-- require_relative '../../../../../../../../lib/rubygems/vendor/net-http/lib/net/http/pipeline'
-+ require 'cgi/escape'
- rescue LoadError
-+ require 'cgi/util' # for escaping
- end
-+require_relative '../../../../connection_pool/lib/connection_pool'
+ require 'cgi/escape'
+ require 'cgi/util' unless defined?(CGI::EscapeExt)
+ require_relative '../../../../connection_pool/lib/connection_pool'
+-begin
+- require_relative '../../../../../../../../lib/rubygems/vendor/net-http/lib/net/http/pipeline'
+-rescue LoadError
+-end
+-
autoload :OpenSSL, 'openssl'
-@@ -762,23 +761,6 @@ def max_retries= retries
- reconnect
- end
+ ##
+@@ -770,23 +765,6 @@
+ @max_retries = retries
+ reconnect
+- end
+-
- ##
- # Pipelines +requests+ to the HTTP server at +uri+ yielding responses if a
- # block is given. Returns all responses received.
@@ -39,17 +39,6 @@ index f57e64df9c..52a8051183 100644
- connection_for uri do |connection|
- connection.http.pipeline requests, &block
- end
-- end
--
- ##
- # Sets this client's SSL private key
-
-@@ -826,7 +808,7 @@ def proxy= proxy
- @proxy_connection_id = [nil, *@proxy_args].join ':'
-
- if @proxy_uri.query then
-- @no_proxy = CGI.parse(@proxy_uri.query)['no_proxy'].join(',').downcase.split(',').map { |x| x.strip }.reject { |x| x.empty? }
-+ @no_proxy = Gem::URI.decode_www_form(@proxy_uri.query).filter_map { |k, v| v if k == 'no_proxy' }.join(',').downcase.split(',').map { |x| x.strip }.reject { |x| x.empty? }
- end
- end
+ end
+ ##
diff --git a/tool/automatiek/net-http-v0.7.0.patch b/tool/automatiek/net-http-v0.10.0.patch
similarity index 91%
rename from tool/automatiek/net-http-v0.7.0.patch
rename to tool/automatiek/net-http-v0.10.0.patch
index 7ef5cb203897..0c66888b2e38 100644
--- a/tool/automatiek/net-http-v0.7.0.patch
+++ b/tool/automatiek/net-http-v0.10.0.patch
@@ -1,5 +1,5 @@
-diff --git b/lib/rubygems/vendor/net-http/lib/net/http/status.rb a/lib/rubygems/vendor/net-http/lib/net/http/status.rb
-index cd5177fcbc..9110b108b8 100644
+diff --git a/lib/rubygems/vendor/net-http/lib/net/http/status.rb b/lib/rubygems/vendor/net-http/lib/net/http/status.rb
+index cd5177f..9110b10 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http/status.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http/status.rb
@@ -50,13 +50,13 @@
@@ -28,7 +28,7 @@ index cd5177fcbc..9110b108b8 100644
506 => 'Variant Also Negotiates',
507 => 'Insufficient Storage',
diff --git a/lib/rubygems/vendor/net-http/lib/net/http.rb b/lib/rubygems/vendor/net-http/lib/net/http.rb
-index e5258175add..e1ccc056100 100644
+index 7a480fc..bdc4283 100644
--- a/lib/rubygems/vendor/net-http/lib/net/http.rb
+++ b/lib/rubygems/vendor/net-http/lib/net/http.rb
@@ -22,7 +22,6 @@
@@ -39,7 +39,7 @@ index e5258175add..e1ccc056100 100644
autoload :OpenSSL, 'openssl'
module Gem::Net #:nodoc:
-@@ -1531,6 +1530,29 @@ def use_ssl=(flag)
+@@ -1539,6 +1538,29 @@ def use_ssl=(flag)
SSL_IVNAMES = SSL_ATTRIBUTES.map { |a| "@#{a}".to_sym }.freeze # :nodoc:
@@ -69,7 +69,7 @@ index e5258175add..e1ccc056100 100644
# Sets or returns the path to a CA certification file in PEM format.
attr_accessor :ca_file
-@@ -1714,7 +1736,7 @@ def connect
+@@ -1738,7 +1760,7 @@ def connect
# Server Name Indication (SNI) RFC 3546/6066
case @address
diff --git a/tool/automatiek/thor-v1.4.0.patch b/tool/automatiek/thor-v1.5.0.patch
similarity index 77%
rename from tool/automatiek/thor-v1.4.0.patch
rename to tool/automatiek/thor-v1.5.0.patch
index 216e3eb41c9e..ece40ec57aba 100644
--- a/tool/automatiek/thor-v1.4.0.patch
+++ b/tool/automatiek/thor-v1.5.0.patch
@@ -1,41 +1,27 @@
-diff --git a/bundler/lib/bundler/vendor/thor/lib/thor.rb b/bundler/lib/bundler/vendor/thor/lib/thor.rb
-index bfd9f5c914..945bdbd551 100644
---- a/bundler/lib/bundler/vendor/thor/lib/thor.rb
-+++ b/bundler/lib/bundler/vendor/thor/lib/thor.rb
-@@ -625,7 +625,7 @@ def normalize_command_name(meth) #:nodoc:
- # alias name.
- def find_command_possibilities(meth)
- len = meth.to_s.length
-- possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort
-+ possibilities = all_commands.reject { |_k, c| c.hidden? }.merge(map).keys.select { |n| meth == n[0, len] }.sort
- unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
-
- if possibilities.include?(meth)
-
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb b/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb
-index 95f8b16e31..f0ce6df96c 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb
@@ -2,7 +2,7 @@
require_relative "group"
-
+
require "digest/sha2"
-require "pathname"
+require "pathname" unless defined?(Pathname)
-
+
class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb b/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb
-index 6a9176331..5d708fadc 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb
-@@ -1,5 +1,4 @@
+@@ -1,7 +1,6 @@
+ # frozen_string_literal: true
+
require_relative "basic"
-require_relative "lcs_diff"
class Bundler::Thor
module Shell
-@@ -7,8 +6,6 @@ module Shell
+@@ -9,8 +8,6 @@
# Bundler::Thor::Shell::Basic to see all available methods.
#
class Color < Basic
@@ -45,7 +31,6 @@ index 6a9176331..5d708fadc 100644
CLEAR = "\e[0m"
# The start of an ANSI bold sequence.
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb b/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb
-index 6091485ac..0277b882b 100644
--- a/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb
+++ b/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb
@@ -1,5 +1,4 @@
@@ -54,7 +39,7 @@ index 6091485ac..0277b882b 100644
class Bundler::Thor
module Shell
-@@ -7,8 +6,6 @@ module Shell
+@@ -7,8 +6,6 @@
# Bundler::Thor::Shell::Basic to see all available methods.
#
class HTML < Basic
@@ -65,7 +50,6 @@ index 6091485ac..0277b882b 100644
diff --git a/bundler/lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb b/bundler/lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb
deleted file mode 100644
-index 81268a9f0..000000000
--- a/bundler/lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb
+++ /dev/null
@@ -1,49 +0,0 @@
diff --git a/tool/automatiek/timeout-v0.4.3.patch b/tool/automatiek/timeout-v0.6.1.patch
similarity index 70%
rename from tool/automatiek/timeout-v0.4.3.patch
rename to tool/automatiek/timeout-v0.6.1.patch
index 91cca25244b9..a283d854eefa 100644
--- a/tool/automatiek/timeout-v0.4.3.patch
+++ b/tool/automatiek/timeout-v0.6.1.patch
@@ -1,5 +1,4 @@
diff --git a/lib/rubygems/vendor/timeout/lib/timeout.rb b/lib/rubygems/vendor/timeout/lib/timeout.rb
-index cc5d05ce670..455c504f470 100644
--- a/lib/rubygems/vendor/timeout/lib/timeout.rb
+++ b/lib/rubygems/vendor/timeout/lib/timeout.rb
@@ -1,5 +1,5 @@
@@ -9,9 +8,9 @@ index cc5d05ce670..455c504f470 100644
#
# == Synopsis
#
-@@ -166,7 +166,7 @@ def self.ensure_timeout_thread_created
- # a module method, so you can call it directly as Gem::Timeout.timeout().
- def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
+@@ -277,7 +277,7 @@
+ # the block will not be interrupted.
+ def self.timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
return yield(sec) if sec == nil or sec.zero?
- raise ArgumentError, "Gem::Timeout sec must be a non-negative number" if 0 > sec
+ raise ArgumentError, "Timeout sec must be a non-negative number" if 0 > sec
diff --git a/tool/automatiek/vendor.rb b/tool/automatiek/vendor.rb
index 444695b731ad..2713bb6aadec 100755
--- a/tool/automatiek/vendor.rb
+++ b/tool/automatiek/vendor.rb
@@ -81,19 +81,19 @@ def require_target
vendored_gems = [
# RubyGems
VendoredGem.new(name: "molinillo", namespace: "Molinillo", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/molinillo", license_path: "LICENSE", extra_dependencies: %w[tsort/lib/rubygems/vendor/tsort], patch_name: "molinillo-master.patch"),
- VendoredGem.new(name: "net-http", namespace: "Net", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/net-http", license_path: "COPYING", extra_dependencies: %w[net-protocol timeout uri/lib/rubygems/vendor/uri], skip_dependencies: %w[uri], patch_name: "net-http-v0.7.0.patch"),
- VendoredGem.new(name: "net-http-persistent", namespace: "Net::HTTP::Persistent", prefix: "Gem", vendor_lib: "bundler/lib/bundler/vendor/net-http-persistent", license_path: "README.rdoc", extra_dependencies: %w[net-http uri/lib/rubygems/vendor/uri], patch_name: "net-http-persistent-v4.0.6.patch"),
- VendoredGem.new(name: "net-protocol", namespace: "Net", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/net-protocol", license_path: "LICENSE.txt"),
+ VendoredGem.new(name: "net-http", namespace: "Net", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/net-http", license_path: "COPYING", extra_dependencies: %w[timeout uri/lib/rubygems/vendor/uri], skip_dependencies: %w[uri], patch_name: "net-http-v0.10.0.patch"),
+ VendoredGem.new(name: "net-http-persistent", namespace: "Net::HTTP::Persistent", prefix: "Gem", vendor_lib: "bundler/lib/bundler/vendor/net-http-persistent", license_path: "README.rdoc", extra_dependencies: %w[net-http uri/lib/rubygems/vendor/uri], patch_name: "net-http-persistent-v4.0.8.patch"),
+ VendoredGem.new(name: "net-protocol", namespace: "Net", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/net-protocol", license_path: "COPYING"),
VendoredGem.new(name: "optparse", namespace: "OptionParser", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/optparse", license_path: "COPYING", extra_dependencies: %w[uri/lib/rubygems/vendor/uri], patch_name: "optparse-v0.8.0.patch"),
VendoredGem.new(name: "securerandom", namespace: "SecureRandom", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/securerandom", license_path: "COPYING"),
- VendoredGem.new(name: "timeout", namespace: "Timeout", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/timeout", license_path: "COPYING", patch_name: "timeout-v0.4.3.patch"),
+ VendoredGem.new(name: "timeout", namespace: "Timeout", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/timeout", license_path: "COPYING", patch_name: "timeout-v0.6.1.patch"),
VendoredGem.new(name: "tsort", namespace: "TSort", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/tsort", license_path: "LICENSE.txt"),
VendoredGem.new(name: "uri", namespace: "URI", prefix: "Gem", vendor_lib: "lib/rubygems/vendor/uri", license_path: "COPYING"),
# Bundler
VendoredGem.new(name: "connection_pool", namespace: "ConnectionPool", prefix: "Bundler", vendor_lib: "bundler/lib/bundler/vendor/connection_pool", license_path: "LICENSE", patch_name: "connection_pool-v2.4.1.patch", extra_dependencies: %w[timeout]),
VendoredGem.new(name: "fileutils", namespace: "FileUtils", prefix: "Bundler", vendor_lib: "bundler/lib/bundler/vendor/fileutils", license_path: "COPYING"),
VendoredGem.new(name: "pub_grub", namespace: "PubGrub", prefix: "Bundler", vendor_lib: "bundler/lib/bundler/vendor/pub_grub", license_path: "LICENSE.txt"),
- VendoredGem.new(name: "thor", namespace: "Thor", prefix: "Bundler", vendor_lib: "bundler/lib/bundler/vendor/thor", license_path: "LICENSE.md", patch_name: "thor-v1.4.0.patch"),
+ VendoredGem.new(name: "thor", namespace: "Thor", prefix: "Bundler", vendor_lib: "bundler/lib/bundler/vendor/thor", license_path: "LICENSE.md", patch_name: "thor-v1.5.0.patch"),
VendoredGem.new(name: "uri", namespace: "URI", prefix: "Bundler", vendor_lib: "bundler/lib/bundler/vendor/uri", license_path: "COPYING"),
VendoredGem.new(name: "securerandom", namespace: "SecureRandom", prefix: "Bundler", vendor_lib: "bundler/lib/bundler/vendor/securerandom", license_path: "COPYING"),
].group_by(&:name)
diff --git a/tool/bundler/vendor_gems.rb b/tool/bundler/vendor_gems.rb
index ebffc281f50b..398799a33d03 100644
--- a/tool/bundler/vendor_gems.rb
+++ b/tool/bundler/vendor_gems.rb
@@ -2,15 +2,16 @@
source "https://rubygems.org"
-gem "fileutils", "1.8.0"
+gem "connection_pool", "2.5.5" # connection_pool 3.x does not parse on Ruby 3.3.0
+gem "fileutils", "1.8.1"
gem "molinillo", github: "cocoapods/molinillo", ref: "1d62d7d5f448e79418716dc779a4909509ccda2a"
-gem "net-http", "0.7.0" # net-http-0.8.0 is broken with JRuby
-gem "net-http-persistent", "4.0.6"
-gem "net-protocol", "0.2.2"
-gem "optparse", "0.8.0"
+gem "net-http", "0.10.0"
+gem "net-http-persistent", "4.0.8"
+gem "net-protocol", "0.4.0"
+gem "optparse", "0.8.1"
gem "pub_grub", github: "jhawthorn/pub_grub", ref: "df6add45d1b4d122daff2f959c9bd1ca93d14261"
gem "securerandom", "0.4.1"
-gem "timeout", "0.4.4"
-gem "thor", "1.4.0"
+gem "timeout", "0.6.1"
+gem "thor", "1.5.0"
gem "tsort", "0.2.0"
-gem "uri", "1.1.1"
+gem "uri", "1.1.2"
diff --git a/tool/bundler/vendor_gems.rb.lock b/tool/bundler/vendor_gems.rb.lock
index c6f63b246cf7..879d45439482 100644
--- a/tool/bundler/vendor_gems.rb.lock
+++ b/tool/bundler/vendor_gems.rb.lock
@@ -15,20 +15,21 @@ GIT
GEM
remote: https://rubygems.org/
specs:
- connection_pool (2.5.4)
- fileutils (1.8.0)
- net-http (0.7.0)
- uri
- net-http-persistent (4.0.6)
- connection_pool (~> 2.2, >= 2.2.4)
- net-protocol (0.2.2)
+ connection_pool (2.5.5)
+ fileutils (1.8.1)
+ net-http (0.10.0)
+ net-protocol (>= 0.3.0)
+ uri (>= 0.11.1)
+ net-http-persistent (4.0.8)
+ connection_pool (>= 2.2.4, < 4)
+ net-protocol (0.4.0)
timeout
- optparse (0.8.0)
+ optparse (0.8.1)
securerandom (0.4.1)
- thor (1.4.0)
- timeout (0.4.4)
+ thor (1.5.0)
+ timeout (0.6.1)
tsort (0.2.0)
- uri (1.1.1)
+ uri (1.1.2)
PLATFORMS
java
@@ -40,33 +41,34 @@ PLATFORMS
x86_64-linux
DEPENDENCIES
- fileutils (= 1.8.0)
+ connection_pool (= 2.5.5)
+ fileutils (= 1.8.1)
molinillo!
- net-http (= 0.7.0)
- net-http-persistent (= 4.0.6)
- net-protocol (= 0.2.2)
- optparse (= 0.8.0)
+ net-http (= 0.10.0)
+ net-http-persistent (= 4.0.8)
+ net-protocol (= 0.4.0)
+ optparse (= 0.8.1)
pub_grub!
securerandom (= 0.4.1)
- thor (= 1.4.0)
- timeout (= 0.4.4)
+ thor (= 1.5.0)
+ timeout (= 0.6.1)
tsort (= 0.2.0)
- uri (= 1.1.1)
+ uri (= 1.1.2)
CHECKSUMS
- connection_pool (2.5.4) sha256=e9e1922327416091f3f6542f5f4446c2a20745276b9aa796dd0bb2fd0ea1e70a
- fileutils (1.8.0) sha256=8c6b1df54e2540bdb2f39258f08af78853aa70bad52b4d394bbc6424593c6e02
+ connection_pool (2.5.5) sha256=e54ff92855753df1fd7c59fa04a398833355f27dd14c074f8c83a05f72a716ad
+ fileutils (1.8.1) sha256=2d541a1ee34a9ed5c4f054be8fb819a26b5d654488a31dc8806917cf448b9cc3
molinillo (0.8.0)
- net-http (0.7.0) sha256=4db7d9f558f8ffd4dcf832d0aefd02320c569c7d4f857def49e585069673a425
- net-http-persistent (4.0.6) sha256=2abb3a04438edf6cb9e0e7e505969605f709eda3e3c5211beadd621a2c84dd5d
- net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8
- optparse (0.8.0) sha256=ef6b7fbaf7ec331474f325bc08dd5622e6e1e651007a5341330ee4b08ce734f0
+ net-http (0.10.0) sha256=1a2ff6e37a05724973c43f2bf7bf105f59c36a4cd0a7e9b1c021a0a566987c27
+ net-http-persistent (4.0.8) sha256=ef3de8319d691537b329053fae3a33195f8b070bbbfae8bf1a58c796081960e6
+ net-protocol (0.4.0) sha256=f9f90c8c6f64794a45160bf422177a336db12809de3beeeaa26b88fcd2e8c853
+ optparse (0.8.1) sha256=42bea10d53907ccff4f080a69991441d611fbf8733b60ed1ce9ee365ce03bd1a
pub_grub (0.5.0)
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
- thor (1.4.0) sha256=8763e822ccb0f1d7bee88cde131b19a65606657b847cc7b7b4b82e772bcd8a3d
- timeout (0.4.4) sha256=f0f6f970104b82427cd990680f539b6bbb8b1e55efa913a55c6492935e4e0edb
+ thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
+ timeout (0.6.1) sha256=78f57368a7e7bbadec56971f78a3f5ecbcfb59b7fcbb0a3ed6ddc08a5094accb
tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
- uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
+ uri (1.1.2) sha256=89292e98eabbef6248b0a0ed5e7e398e152f83f17560023a6d94a7f492b169fb
BUNDLED WITH
4.0.22