summaryrefslogtreecommitdiff
path: root/lib/rubygems/vendor/net-http/lib/net/http
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rubygems/vendor/net-http/lib/net/http')
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/backward.rb40
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb34
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb414
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/header.rb981
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb17
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/request.rb88
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/requests.rb425
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/response.rb738
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/responses.rb1174
-rw-r--r--lib/rubygems/vendor/net-http/lib/net/http/status.rb84
10 files changed, 3995 insertions, 0 deletions
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/backward.rb b/lib/rubygems/vendor/net-http/lib/net/http/backward.rb
new file mode 100644
index 0000000000..10dbc16224
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/backward.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+# for backward compatibility
+
+# :enddoc:
+
+class Gem::Net::HTTP
+ ProxyMod = ProxyDelta
+ deprecate_constant :ProxyMod
+end
+
+module Gem::Net::NetPrivate
+ HTTPRequest = ::Gem::Net::HTTPRequest
+ deprecate_constant :HTTPRequest
+end
+
+module Gem::Net
+ HTTPSession = HTTP
+
+ HTTPInformationCode = HTTPInformation
+ HTTPSuccessCode = HTTPSuccess
+ HTTPRedirectionCode = HTTPRedirection
+ HTTPRetriableCode = HTTPRedirection
+ HTTPClientErrorCode = HTTPClientError
+ HTTPFatalErrorCode = HTTPClientError
+ HTTPServerErrorCode = HTTPServerError
+ HTTPResponseReceiver = HTTPResponse
+
+ HTTPResponceReceiver = HTTPResponse # Typo since 2001
+
+ deprecate_constant :HTTPSession,
+ :HTTPInformationCode,
+ :HTTPSuccessCode,
+ :HTTPRedirectionCode,
+ :HTTPRetriableCode,
+ :HTTPClientErrorCode,
+ :HTTPFatalErrorCode,
+ :HTTPServerErrorCode,
+ :HTTPResponseReceiver,
+ :HTTPResponceReceiver
+end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb b/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb
new file mode 100644
index 0000000000..c629c0113b
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+module Gem::Net
+ # Gem::Net::HTTP exception class.
+ # You cannot use Gem::Net::HTTPExceptions directly; instead, you must use
+ # its subclasses.
+ module HTTPExceptions
+ def initialize(msg, res) #:nodoc:
+ super msg
+ @response = res
+ end
+ attr_reader :response
+ alias data response #:nodoc: obsolete
+ end
+
+ class HTTPError < ProtocolError
+ include HTTPExceptions
+ end
+
+ class HTTPRetriableError < ProtoRetriableError
+ include HTTPExceptions
+ end
+
+ class HTTPClientException < ProtoServerError
+ include HTTPExceptions
+ end
+
+ class HTTPFatalError < ProtoFatalError
+ include HTTPExceptions
+ end
+
+ # We cannot use the name "HTTPServerError", it is the name of the response.
+ HTTPServerException = HTTPClientException # :nodoc:
+ deprecate_constant(:HTTPServerException)
+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
new file mode 100644
index 0000000000..5cfe75a7cd
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb
@@ -0,0 +1,414 @@
+# frozen_string_literal: true
+#
+# \HTTPGenericRequest is the parent of the Gem::Net::HTTPRequest class.
+#
+# Do not use this directly; instead, use a subclass of Gem::Net::HTTPRequest.
+#
+# == About the Examples
+#
+# :include: doc/net-http/examples.rdoc
+#
+class Gem::Net::HTTPGenericRequest
+
+ include Gem::Net::HTTPHeader
+
+ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc:
+ @method = m
+ @request_has_body = reqbody
+ @response_has_body = resbody
+
+ 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
+ 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
+ end
+
+ @decode_content = false
+
+ if Gem::Net::HTTP::HAVE_ZLIB then
+ if !initheader ||
+ !initheader.keys.any? { |k|
+ %w[accept-encoding range].include? k.downcase
+ } then
+ @decode_content = true if @response_has_body
+ initheader = initheader ? initheader.dup : {}
+ initheader["accept-encoding"] =
+ "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
+ end
+ end
+
+ initialize_http_header initheader
+ self['Accept'] ||= '*/*'
+ self['User-Agent'] ||= 'Ruby'
+ self['Host'] ||= host if host
+ @body = nil
+ @body_stream = nil
+ @body_data = nil
+ end
+
+ # Returns the string method name for the request:
+ #
+ # Gem::Net::HTTP::Get.new(uri).method # => "GET"
+ # Gem::Net::HTTP::Post.new(uri).method # => "POST"
+ #
+ attr_reader :method
+
+ # Returns the string path for the request:
+ #
+ # Gem::Net::HTTP::Get.new(uri).path # => "/"
+ # Gem::Net::HTTP::Post.new('example.com').path # => "example.com"
+ #
+ attr_reader :path
+
+ # Returns the Gem::URI object for the request, or +nil+ if none:
+ #
+ # Gem::Net::HTTP::Get.new(uri).uri
+ # # => #<Gem::URI::HTTPS https://jsonplaceholder.typicode.com/>
+ # Gem::Net::HTTP::Get.new('example.com').uri # => nil
+ #
+ attr_reader :uri
+
+ # Returns +false+ if the request's header <tt>'Accept-Encoding'</tt>
+ # has been set manually or deleted
+ # (indicating that the user intends to handle encoding in the response),
+ # +true+ otherwise:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri) # => #<Gem::Net::HTTP::Get GET>
+ # req['Accept-Encoding'] # => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
+ # req.decode_content # => true
+ # req['Accept-Encoding'] = 'foo'
+ # req.decode_content # => false
+ # req.delete('Accept-Encoding')
+ # req.decode_content # => false
+ #
+ attr_reader :decode_content
+
+ # Returns a string representation of the request:
+ #
+ # Gem::Net::HTTP::Post.new(uri).inspect # => "#<Gem::Net::HTTP::Post POST>"
+ #
+ def inspect
+ "\#<#{self.class} #{@method}>"
+ end
+
+ ##
+ # Don't automatically decode response content-encoding if the user indicates
+ # they want to handle it.
+
+ def []=(key, val) # :nodoc:
+ @decode_content = false if key.downcase == 'accept-encoding'
+
+ super key, val
+ end
+
+ # Returns whether the request may have a body:
+ #
+ # Gem::Net::HTTP::Post.new(uri).request_body_permitted? # => true
+ # Gem::Net::HTTP::Get.new(uri).request_body_permitted? # => false
+ #
+ def request_body_permitted?
+ @request_has_body
+ end
+
+ # Returns whether the response may have a body:
+ #
+ # Gem::Net::HTTP::Post.new(uri).response_body_permitted? # => true
+ # Gem::Net::HTTP::Head.new(uri).response_body_permitted? # => false
+ #
+ def response_body_permitted?
+ @response_has_body
+ end
+
+ def body_exist? # :nodoc:
+ warn "Gem::Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?", uplevel: 1 if $VERBOSE
+ response_body_permitted?
+ end
+
+ # Returns the string body for the request, or +nil+ if there is none:
+ #
+ # req = Gem::Net::HTTP::Post.new(uri)
+ # req.body # => nil
+ # req.body = '{"title": "foo","body": "bar","userId": 1}'
+ # req.body # => "{\"title\": \"foo\",\"body\": \"bar\",\"userId\": 1}"
+ #
+ attr_reader :body
+
+ # Sets the body for the request:
+ #
+ # req = Gem::Net::HTTP::Post.new(uri)
+ # req.body # => nil
+ # req.body = '{"title": "foo","body": "bar","userId": 1}'
+ # req.body # => "{\"title\": \"foo\",\"body\": \"bar\",\"userId\": 1}"
+ #
+ def body=(str)
+ @body = str
+ @body_stream = nil
+ @body_data = nil
+ str
+ end
+
+ # Returns the body stream object for the request, or +nil+ if there is none:
+ #
+ # req = Gem::Net::HTTP::Post.new(uri) # => #<Gem::Net::HTTP::Post POST>
+ # req.body_stream # => nil
+ # require 'stringio'
+ # req.body_stream = StringIO.new('xyzzy') # => #<StringIO:0x0000027d1e5affa8>
+ # req.body_stream # => #<StringIO:0x0000027d1e5affa8>
+ #
+ attr_reader :body_stream
+
+ # Sets the body stream for the request:
+ #
+ # req = Gem::Net::HTTP::Post.new(uri) # => #<Gem::Net::HTTP::Post POST>
+ # req.body_stream # => nil
+ # require 'stringio'
+ # req.body_stream = StringIO.new('xyzzy') # => #<StringIO:0x0000027d1e5affa8>
+ # req.body_stream # => #<StringIO:0x0000027d1e5affa8>
+ #
+ def body_stream=(input)
+ @body = nil
+ @body_stream = input
+ @body_data = nil
+ input
+ end
+
+ def set_body_internal(str) #:nodoc: internal use only
+ raise ArgumentError, "both of body argument and HTTPRequest#body set" if str and (@body or @body_stream)
+ self.body = str if str
+ if @body.nil? && @body_stream.nil? && @body_data.nil? && request_body_permitted?
+ self.body = ''
+ end
+ end
+
+ #
+ # write
+ #
+
+ def exec(sock, ver, path) #:nodoc: internal use only
+ if @body
+ send_request_with_body sock, ver, path, @body
+ elsif @body_stream
+ send_request_with_body_stream sock, ver, path, @body_stream
+ elsif @body_data
+ send_request_with_body_data sock, ver, path, @body_data
+ else
+ write_header sock, ver, path
+ end
+ end
+
+ def update_uri(addr, port, ssl) # :nodoc: internal use only
+ # reflect the connection and @path to @uri
+ return unless @uri
+
+ if ssl
+ scheme = 'https'
+ klass = Gem::URI::HTTPS
+ else
+ scheme = 'http'
+ klass = Gem::URI::HTTP
+ end
+
+ if host = self['host']
+ host.sub!(/:.*/m, '')
+ elsif host = @uri.host
+ else
+ host = addr
+ end
+ # convert the class of the Gem::URI
+ if @uri.is_a?(klass)
+ @uri.host = host
+ @uri.port = port
+ else
+ @uri = klass.new(
+ scheme, @uri.userinfo,
+ host, port, nil,
+ @uri.path, nil, @uri.query, nil)
+ end
+ end
+
+ private
+
+ class Chunker #:nodoc:
+ def initialize(sock)
+ @sock = sock
+ @prev = nil
+ end
+
+ def write(buf)
+ # avoid memcpy() of buf, buf can huge and eat memory bandwidth
+ rv = buf.bytesize
+ @sock.write("#{rv.to_s(16)}\r\n", buf, "\r\n")
+ rv
+ end
+
+ def finish
+ @sock.write("0\r\n\r\n")
+ end
+ end
+
+ def send_request_with_body(sock, ver, path, body)
+ self.content_length = body.bytesize
+ delete 'Transfer-Encoding'
+ supply_default_content_type
+ write_header sock, ver, path
+ wait_for_continue sock, ver if sock.continue_timeout
+ sock.write body
+ end
+
+ def send_request_with_body_stream(sock, ver, path, f)
+ unless content_length() or chunked?
+ raise ArgumentError,
+ "Content-Length not given and Transfer-Encoding is not `chunked'"
+ end
+ supply_default_content_type
+ write_header sock, ver, path
+ wait_for_continue sock, ver if sock.continue_timeout
+ if chunked?
+ chunker = Chunker.new(sock)
+ IO.copy_stream(f, chunker)
+ chunker.finish
+ else
+ IO.copy_stream(f, sock)
+ end
+ end
+
+ def send_request_with_body_data(sock, ver, path, params)
+ if /\Amultipart\/form-data\z/i !~ self.content_type
+ self.content_type = 'application/x-www-form-urlencoded'
+ return send_request_with_body(sock, ver, path, Gem::URI.encode_www_form(params))
+ end
+
+ opt = @form_option.dup
+ require 'securerandom' unless defined?(SecureRandom)
+ opt[:boundary] ||= SecureRandom.urlsafe_base64(40)
+ self.set_content_type(self.content_type, boundary: opt[:boundary])
+ if chunked?
+ write_header sock, ver, path
+ encode_multipart_form_data(sock, params, opt)
+ else
+ require 'tempfile'
+ file = Tempfile.new('multipart')
+ file.binmode
+ encode_multipart_form_data(file, params, opt)
+ file.rewind
+ self.content_length = file.size
+ write_header sock, ver, path
+ IO.copy_stream(file, sock)
+ file.close(true)
+ end
+ end
+
+ def encode_multipart_form_data(out, params, opt)
+ charset = opt[:charset]
+ boundary = opt[:boundary]
+ require 'securerandom' unless defined?(SecureRandom)
+ boundary ||= SecureRandom.urlsafe_base64(40)
+ chunked_p = chunked?
+
+ buf = +''
+ params.each do |key, value, h={}|
+ key = quote_string(key, charset)
+ filename =
+ h.key?(:filename) ? h[:filename] :
+ value.respond_to?(:to_path) ? File.basename(value.to_path) :
+ nil
+
+ buf << "--#{boundary}\r\n"
+ if filename
+ filename = quote_string(filename, charset)
+ type = h[:content_type] || 'application/octet-stream'
+ buf << "Content-Disposition: form-data; " \
+ "name=\"#{key}\"; filename=\"#{filename}\"\r\n" \
+ "Content-Type: #{type}\r\n\r\n"
+ if !out.respond_to?(:write) || !value.respond_to?(:read)
+ # if +out+ is not an IO or +value+ is not an IO
+ buf << (value.respond_to?(:read) ? value.read : value)
+ elsif value.respond_to?(:size) && chunked_p
+ # if +out+ is an IO and +value+ is a File, use IO.copy_stream
+ flush_buffer(out, buf, chunked_p)
+ out << "%x\r\n" % value.size if chunked_p
+ IO.copy_stream(value, out)
+ out << "\r\n" if chunked_p
+ else
+ # +out+ is an IO, and +value+ is not a File but an IO
+ flush_buffer(out, buf, chunked_p)
+ 1 while flush_buffer(out, value.read(4096), chunked_p)
+ end
+ else
+ # non-file field:
+ # HTML5 says, "The parts of the generated multipart/form-data
+ # resource that correspond to non-file fields must not have a
+ # Content-Type header specified."
+ buf << "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n"
+ buf << (value.respond_to?(:read) ? value.read : value)
+ end
+ buf << "\r\n"
+ end
+ buf << "--#{boundary}--\r\n"
+ flush_buffer(out, buf, chunked_p)
+ out << "0\r\n\r\n" if chunked_p
+ end
+
+ def quote_string(str, charset)
+ str = str.encode(charset, fallback:->(c){'&#%d;'%c.encode("UTF-8").ord}) if charset
+ str.gsub(/[\\"]/, '\\\\\&')
+ end
+
+ def flush_buffer(out, buf, chunked_p)
+ return unless buf
+ out << "%x\r\n"%buf.bytesize if chunked_p
+ out << buf
+ out << "\r\n" if chunked_p
+ buf.clear
+ end
+
+ def supply_default_content_type
+ return if content_type()
+ warn 'net/http: Content-Type did not set; using application/x-www-form-urlencoded', uplevel: 1 if $VERBOSE
+ set_content_type 'application/x-www-form-urlencoded'
+ end
+
+ ##
+ # Waits up to the continue timeout for a response from the server provided
+ # we're speaking HTTP 1.1 and are expecting a 100-continue response.
+
+ def wait_for_continue(sock, ver)
+ if ver >= '1.1' and @header['expect'] and
+ @header['expect'].include?('100-continue')
+ if sock.io.to_io.wait_readable(sock.continue_timeout)
+ res = Gem::Net::HTTPResponse.read_new(sock)
+ unless res.kind_of?(Gem::Net::HTTPContinue)
+ res.decode_content = @decode_content
+ throw :response, res
+ end
+ end
+ end
+ end
+
+ def write_header(sock, ver, path)
+ reqline = "#{@method} #{path} HTTP/#{ver}"
+ if /[\r\n]/ =~ reqline
+ raise ArgumentError, "A Request-Line must not contain CR or LF"
+ end
+ buf = +''
+ buf << reqline << "\r\n"
+ each_capitalized do |k,v|
+ buf << "#{k}: #{v}\r\n"
+ end
+ buf << "\r\n"
+ sock.write buf
+ end
+
+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
new file mode 100644
index 0000000000..1488e60068
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/header.rb
@@ -0,0 +1,981 @@
+# frozen_string_literal: true
+#
+# The \HTTPHeader module provides access to \HTTP headers.
+#
+# The module is included in:
+#
+# - Gem::Net::HTTPGenericRequest (and therefore Gem::Net::HTTPRequest).
+# - Gem::Net::HTTPResponse.
+#
+# The headers are a hash-like collection of key/value pairs called _fields_.
+#
+# == Request and Response Fields
+#
+# Headers may be included in:
+#
+# - A Gem::Net::HTTPRequest object:
+# the object's headers will be sent with the request.
+# Any fields may be defined in the request;
+# see {Setters}[rdoc-ref:Gem::Net::HTTPHeader@Setters].
+# - A Gem::Net::HTTPResponse object:
+# the objects headers are usually those returned from the host.
+# Fields may be retrieved from the object;
+# see {Getters}[rdoc-ref:Gem::Net::HTTPHeader@Getters]
+# and {Iterators}[rdoc-ref:Gem::Net::HTTPHeader@Iterators].
+#
+# Exactly which fields should be sent or expected depends on the host;
+# see:
+#
+# - {Request fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields].
+# - {Response fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields].
+#
+# == About the Examples
+#
+# :include: doc/net-http/examples.rdoc
+#
+# == Fields
+#
+# A header field is a key/value pair.
+#
+# === Field Keys
+#
+# A field key may be:
+#
+# - A string: Key <tt>'Accept'</tt> is treated as if it were
+# <tt>'Accept'.downcase</tt>; i.e., <tt>'accept'</tt>.
+# - A symbol: Key <tt>:Accept</tt> is treated as if it were
+# <tt>:Accept.to_s.downcase</tt>; i.e., <tt>'accept'</tt>.
+#
+# Examples:
+#
+# req = Gem::Net::HTTP::Get.new(uri)
+# req[:accept] # => "*/*"
+# req['Accept'] # => "*/*"
+# req['ACCEPT'] # => "*/*"
+#
+# req['accept'] = 'text/html'
+# req[:accept] = 'text/html'
+# req['ACCEPT'] = 'text/html'
+#
+# === Field Values
+#
+# A field value may be returned as an array of strings or as a string:
+#
+# - These methods return field values as arrays:
+#
+# - #get_fields: Returns the array value for the given key,
+# or +nil+ if it does not exist.
+# - #to_hash: Returns a hash of all header fields:
+# each key is a field name; its value is the array value for the field.
+#
+# - These methods return field values as string;
+# the string value for a field is equivalent to
+# <tt>self[key.downcase.to_s].join(', '))</tt>:
+#
+# - #[]: Returns the string value for the given key,
+# or +nil+ if it does not exist.
+# - #fetch: Like #[], but accepts a default value
+# to be returned if the key does not exist.
+#
+# The field value may be set:
+#
+# - #[]=: Sets the value for the given key;
+# the given value may be a string, a symbol, an array, or a hash.
+# - #add_field: Adds a given value to a value for the given key
+# (not overwriting the existing value).
+# - #delete: Deletes the field for the given key.
+#
+# Example field values:
+#
+# - \String:
+#
+# req['Accept'] = 'text/html' # => "text/html"
+# req['Accept'] # => "text/html"
+# req.get_fields('Accept') # => ["text/html"]
+#
+# - \Symbol:
+#
+# req['Accept'] = :text # => :text
+# req['Accept'] # => "text"
+# req.get_fields('Accept') # => ["text"]
+#
+# - Simple array:
+#
+# req[:foo] = %w[bar baz bat]
+# req[:foo] # => "bar, baz, bat"
+# req.get_fields(:foo) # => ["bar", "baz", "bat"]
+#
+# - Simple hash:
+#
+# req[:foo] = {bar: 0, baz: 1, bat: 2}
+# req[:foo] # => "bar, 0, baz, 1, bat, 2"
+# req.get_fields(:foo) # => ["bar", "0", "baz", "1", "bat", "2"]
+#
+# - Nested:
+#
+# req[:foo] = [%w[bar baz], {bat: 0, bam: 1}]
+# req[:foo] # => "bar, baz, bat, 0, bam, 1"
+# req.get_fields(:foo) # => ["bar", "baz", "bat", "0", "bam", "1"]
+#
+# req[:foo] = {bar: %w[baz bat], bam: {bah: 0, bad: 1}}
+# req[:foo] # => "bar, baz, bat, bam, bah, 0, bad, 1"
+# req.get_fields(:foo) # => ["bar", "baz", "bat", "bam", "bah", "0", "bad", "1"]
+#
+# == Convenience Methods
+#
+# Various convenience methods retrieve values, set values, query values,
+# set form values, or iterate over fields.
+#
+# === Setters
+#
+# \Method #[]= can set any field, but does little to validate the new value;
+# some of the other setter methods provide some validation:
+#
+# - #[]=: Sets the string or array value for the given key.
+# - #add_field: Creates or adds to the array value for the given key.
+# - #basic_auth: Sets the string authorization header for <tt>'Authorization'</tt>.
+# - #content_length=: Sets the integer length for field <tt>'Content-Length</tt>.
+# - #content_type=: Sets the string value for field <tt>'Content-Type'</tt>.
+# - #proxy_basic_auth: Sets the string authorization header for <tt>'Proxy-Authorization'</tt>.
+# - #set_range: Sets the value for field <tt>'Range'</tt>.
+#
+# === Form Setters
+#
+# - #set_form: Sets an HTML form data set.
+# - #set_form_data: Sets header fields and a body from HTML form data.
+#
+# === Getters
+#
+# \Method #[] can retrieve the value of any field that exists,
+# but always as a string;
+# some of the other getter methods return something different
+# from the simple string value:
+#
+# - #[]: Returns the string field value for the given key.
+# - #content_length: Returns the integer value of field <tt>'Content-Length'</tt>.
+# - #content_range: Returns the Range value of field <tt>'Content-Range'</tt>.
+# - #content_type: Returns the string value of field <tt>'Content-Type'</tt>.
+# - #fetch: Returns the string field value for the given key.
+# - #get_fields: Returns the array field value for the given +key+.
+# - #main_type: Returns first part of the string value of field <tt>'Content-Type'</tt>.
+# - #sub_type: Returns second part of the string value of field <tt>'Content-Type'</tt>.
+# - #range: Returns an array of Range objects of field <tt>'Range'</tt>, or +nil+.
+# - #range_length: Returns the integer length of the range given in field <tt>'Content-Range'</tt>.
+# - #type_params: Returns the string parameters for <tt>'Content-Type'</tt>.
+#
+# === Queries
+#
+# - #chunked?: Returns whether field <tt>'Transfer-Encoding'</tt> is set to <tt>'chunked'</tt>.
+# - #connection_close?: Returns whether field <tt>'Connection'</tt> is set to <tt>'close'</tt>.
+# - #connection_keep_alive?: Returns whether field <tt>'Connection'</tt> is set to <tt>'keep-alive'</tt>.
+# - #key?: Returns whether a given key exists.
+#
+# === Iterators
+#
+# - #each_capitalized: Passes each field capitalized-name/value pair to the block.
+# - #each_capitalized_name: Passes each capitalized field name to the block.
+# - #each_header: Passes each field name/value pair to the block.
+# - #each_name: Passes each field name to the block.
+# - #each_value: Passes each string field value to the block.
+#
+module Gem::Net::HTTPHeader
+ MAX_KEY_LENGTH = 1024
+ MAX_FIELD_LENGTH = 65536
+
+ def initialize_http_header(initheader) #:nodoc:
+ @header = {}
+ return unless initheader
+ initheader.each do |key, value|
+ warn "net/http: duplicated HTTP header: #{key}", uplevel: 3 if key?(key) and $VERBOSE
+ if value.nil?
+ 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
+ if value.to_s.bytesize > MAX_FIELD_LENGTH
+ raise ArgumentError, "header #{key} has too long field value: #{value.bytesize}"
+ end
+ if value.count("\r\n") > 0
+ raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF"
+ end
+ @header[key.downcase.to_s] = [value]
+ end
+ end
+ end
+
+ def size #:nodoc: obsolete
+ @header.size
+ end
+
+ alias length size #:nodoc: obsolete
+
+ # Returns the string field value for the case-insensitive field +key+,
+ # or +nil+ if there is no such key;
+ # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res['Connection'] # => "keep-alive"
+ # res['Nosuch'] # => nil
+ #
+ # Note that some field values may be retrieved via convenience methods;
+ # see {Getters}[rdoc-ref:Gem::Net::HTTPHeader@Getters].
+ def [](key)
+ a = @header[key.downcase.to_s] or return nil
+ a.join(', ')
+ end
+
+ # Sets the value for the case-insensitive +key+ to +val+,
+ # overwriting the previous value if the field exists;
+ # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri)
+ # req['Accept'] # => "*/*"
+ # req['Accept'] = 'text/html'
+ # req['Accept'] # => "text/html"
+ #
+ # Note that some field values may be set via convenience methods;
+ # see {Setters}[rdoc-ref:Gem::Net::HTTPHeader@Setters].
+ def []=(key, val)
+ unless val
+ @header.delete key.downcase.to_s
+ return val
+ end
+ set_field(key, val)
+ end
+
+ # Adds value +val+ to the value array for field +key+ if the field exists;
+ # creates the field with the given +key+ and +val+ if it does not exist.
+ # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri)
+ # req.add_field('Foo', 'bar')
+ # req['Foo'] # => "bar"
+ # req.add_field('Foo', 'baz')
+ # req['Foo'] # => "bar, baz"
+ # req.add_field('Foo', %w[baz bam])
+ # req['Foo'] # => "bar, baz, baz, bam"
+ # req.get_fields('Foo') # => ["bar", "baz", "baz", "bam"]
+ #
+ 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)
+ else
+ set_field(key, val)
+ end
+ end
+
+ private def set_field(key, val)
+ case val
+ when Enumerable
+ ary = []
+ append_field_value(ary, val)
+ @header[key.downcase.to_s] = ary
+ else
+ val = val.to_s # for compatibility use to_s instead of to_str
+ if val.b.count("\r\n") > 0
+ raise ArgumentError, 'header field value cannot include CR/LF'
+ end
+ @header[key.downcase.to_s] = [val]
+ end
+ end
+
+ private def append_field_value(ary, val)
+ case val
+ when Enumerable
+ val.each{|x| append_field_value(ary, x)}
+ else
+ val = val.to_s
+ if /[\r\n]/n.match?(val.b)
+ raise ArgumentError, 'header field value cannot include CR/LF'
+ end
+ ary.push val
+ end
+ end
+
+ # Returns the array field value for the given +key+,
+ # or +nil+ if there is no such field;
+ # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res.get_fields('Connection') # => ["keep-alive"]
+ # res.get_fields('Nosuch') # => nil
+ #
+ def get_fields(key)
+ stringified_downcased_key = key.downcase.to_s
+ return nil unless @header[stringified_downcased_key]
+ @header[stringified_downcased_key].dup
+ end
+
+ # call-seq:
+ # fetch(key, default_val = nil) {|key| ... } -> object
+ # fetch(key, default_val = nil) -> value or default_val
+ #
+ # With a block, returns the string value for +key+ if it exists;
+ # otherwise returns the value of the block;
+ # ignores the +default_val+;
+ # see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ #
+ # # Field exists; block not called.
+ # res.fetch('Connection') do |value|
+ # fail 'Cannot happen'
+ # end # => "keep-alive"
+ #
+ # # Field does not exist; block called.
+ # res.fetch('Nosuch') do |value|
+ # value.downcase
+ # end # => "nosuch"
+ #
+ # With no block, returns the string value for +key+ if it exists;
+ # otherwise, returns +default_val+ if it was given;
+ # otherwise raises an exception:
+ #
+ # res.fetch('Connection', 'Foo') # => "keep-alive"
+ # res.fetch('Nosuch', 'Foo') # => "Foo"
+ # res.fetch('Nosuch') # Raises KeyError.
+ #
+ def fetch(key, *args, &block) #:yield: +key+
+ a = @header.fetch(key.downcase.to_s, *args, &block)
+ a.kind_of?(Array) ? a.join(', ') : a
+ end
+
+ # Calls the block with each key/value pair:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res.each_header do |key, value|
+ # p [key, value] if key.start_with?('c')
+ # end
+ #
+ # Output:
+ #
+ # ["content-type", "application/json; charset=utf-8"]
+ # ["connection", "keep-alive"]
+ # ["cache-control", "max-age=43200"]
+ # ["cf-cache-status", "HIT"]
+ # ["cf-ray", "771d17e9bc542cf5-ORD"]
+ #
+ # Returns an enumerator if no block is given.
+ #
+ # Gem::Net::HTTPHeader#each is an alias for Gem::Net::HTTPHeader#each_header.
+ def each_header #:yield: +key+, +value+
+ block_given? or return enum_for(__method__) { @header.size }
+ @header.each do |k,va|
+ yield k, va.join(', ')
+ end
+ end
+
+ alias each each_header
+
+ # Calls the block with each field key:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res.each_key do |key|
+ # p key if key.start_with?('c')
+ # end
+ #
+ # Output:
+ #
+ # "content-type"
+ # "connection"
+ # "cache-control"
+ # "cf-cache-status"
+ # "cf-ray"
+ #
+ # Returns an enumerator if no block is given.
+ #
+ # Gem::Net::HTTPHeader#each_name is an alias for Gem::Net::HTTPHeader#each_key.
+ def each_name(&block) #:yield: +key+
+ block_given? or return enum_for(__method__) { @header.size }
+ @header.each_key(&block)
+ end
+
+ alias each_key each_name
+
+ # Calls the block with each capitalized field name:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res.each_capitalized_name do |key|
+ # p key if key.start_with?('C')
+ # end
+ #
+ # Output:
+ #
+ # "Content-Type"
+ # "Connection"
+ # "Cache-Control"
+ # "Cf-Cache-Status"
+ # "Cf-Ray"
+ #
+ # The capitalization is system-dependent;
+ # see {Case Mapping}[https://docs.ruby-lang.org/en/master/case_mapping_rdoc.html].
+ #
+ # Returns an enumerator if no block is given.
+ def each_capitalized_name #:yield: +key+
+ block_given? or return enum_for(__method__) { @header.size }
+ @header.each_key do |k|
+ yield capitalize(k)
+ end
+ end
+
+ # Calls the block with each string field value:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res.each_value do |value|
+ # p value if value.start_with?('c')
+ # end
+ #
+ # Output:
+ #
+ # "chunked"
+ # "cf-q-config;dur=6.0000002122251e-06"
+ # "cloudflare"
+ #
+ # Returns an enumerator if no block is given.
+ def each_value #:yield: +value+
+ block_given? or return enum_for(__method__) { @header.size }
+ @header.each_value do |va|
+ yield va.join(', ')
+ end
+ end
+
+ # Removes the header for the given case-insensitive +key+
+ # (see {Fields}[rdoc-ref:Gem::Net::HTTPHeader@Fields]);
+ # returns the deleted value, or +nil+ if no such field exists:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri)
+ # req.delete('Accept') # => ["*/*"]
+ # req.delete('Nosuch') # => nil
+ #
+ def delete(key)
+ @header.delete(key.downcase.to_s)
+ end
+
+ # Returns +true+ if the field for the case-insensitive +key+ exists, +false+ otherwise:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri)
+ # req.key?('Accept') # => true
+ # req.key?('Nosuch') # => false
+ #
+ def key?(key)
+ @header.key?(key.downcase.to_s)
+ end
+
+ # Returns a hash of the key/value pairs:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri)
+ # req.to_hash
+ # # =>
+ # {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"],
+ # "accept"=>["*/*"],
+ # "user-agent"=>["Ruby"],
+ # "host"=>["jsonplaceholder.typicode.com"]}
+ #
+ def to_hash
+ @header.dup
+ end
+
+ # Like #each_header, but the keys are returned in capitalized form.
+ #
+ # Gem::Net::HTTPHeader#canonical_each is an alias for Gem::Net::HTTPHeader#each_capitalized.
+ def each_capitalized
+ block_given? or return enum_for(__method__) { @header.size }
+ @header.each do |k,v|
+ yield capitalize(k), v.join(', ')
+ end
+ end
+
+ alias canonical_each each_capitalized
+
+ def capitalize(name)
+ name.to_s.split(/-/).map {|s| s.capitalize }.join('-')
+ end
+ private :capitalize
+
+ # Returns an array of Range objects that represent
+ # the value of field <tt>'Range'</tt>,
+ # or +nil+ if there is no such field;
+ # see {Range request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#range-request-header]:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri)
+ # req['Range'] = 'bytes=0-99,200-299,400-499'
+ # req.range # => [0..99, 200..299, 400..499]
+ # req.delete('Range')
+ # req.range # # => nil
+ #
+ def range
+ return nil unless @header['range']
+
+ value = self['Range']
+ # byte-range-set = *( "," OWS ) ( byte-range-spec / suffix-byte-range-spec )
+ # *( OWS "," [ OWS ( byte-range-spec / suffix-byte-range-spec ) ] )
+ # corrected collected ABNF
+ # http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#section-5.4.1
+ # http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#appendix-C
+ # http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-19#section-3.2.5
+ unless /\Abytes=((?:,[ \t]*)*(?:\d+-\d*|-\d+)(?:[ \t]*,(?:[ \t]*\d+-\d*|-\d+)?)*)\z/ =~ value
+ raise Gem::Net::HTTPHeaderSyntaxError, "invalid syntax for byte-ranges-specifier: '#{value}'"
+ end
+
+ byte_range_set = $1
+ result = byte_range_set.split(/,/).map {|spec|
+ m = /(\d+)?\s*-\s*(\d+)?/i.match(spec) or
+ raise Gem::Net::HTTPHeaderSyntaxError, "invalid byte-range-spec: '#{spec}'"
+ d1 = m[1].to_i
+ d2 = m[2].to_i
+ if m[1] and m[2]
+ if d1 > d2
+ raise Gem::Net::HTTPHeaderSyntaxError, "last-byte-pos MUST greater than or equal to first-byte-pos but '#{spec}'"
+ end
+ d1..d2
+ elsif m[1]
+ d1..-1
+ elsif m[2]
+ -d2..-1
+ else
+ raise Gem::Net::HTTPHeaderSyntaxError, 'range is not specified'
+ end
+ }
+ # if result.empty?
+ # byte-range-set must include at least one byte-range-spec or suffix-byte-range-spec
+ # but above regexp already denies it.
+ if result.size == 1 && result[0].begin == 0 && result[0].end == -1
+ raise Gem::Net::HTTPHeaderSyntaxError, 'only one suffix-byte-range-spec with zero suffix-length'
+ end
+ result
+ end
+
+ # call-seq:
+ # set_range(length) -> length
+ # set_range(offset, length) -> range
+ # set_range(begin..length) -> range
+ #
+ # Sets the value for field <tt>'Range'</tt>;
+ # see {Range request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#range-request-header]:
+ #
+ # With argument +length+:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri)
+ # req.set_range(100) # => 100
+ # req['Range'] # => "bytes=0-99"
+ #
+ # With arguments +offset+ and +length+:
+ #
+ # req.set_range(100, 100) # => 100...200
+ # req['Range'] # => "bytes=100-199"
+ #
+ # With argument +range+:
+ #
+ # req.set_range(100..199) # => 100..199
+ # req['Range'] # => "bytes=100-199"
+ #
+ # Gem::Net::HTTPHeader#range= is an alias for Gem::Net::HTTPHeader#set_range.
+ def set_range(r, e = nil)
+ unless r
+ @header.delete 'range'
+ return r
+ end
+ r = (r...r+e) if e
+ case r
+ when Numeric
+ n = r.to_i
+ rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}")
+ when Range
+ first = r.first
+ last = r.end
+ last -= 1 if r.exclude_end?
+ if last == -1
+ rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
+ else
+ raise Gem::Net::HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
+ raise Gem::Net::HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
+ raise Gem::Net::HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
+ rangestr = "#{first}-#{last}"
+ end
+ else
+ raise TypeError, 'Range/Integer is required'
+ end
+ @header['range'] = ["bytes=#{rangestr}"]
+ r
+ end
+
+ alias range= set_range
+
+ # Returns the value of field <tt>'Content-Length'</tt> as an integer,
+ # or +nil+ if there is no such field;
+ # see {Content-Length request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-length-request-header]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/nosuch/1')
+ # res.content_length # => 2
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res.content_length # => nil
+ #
+ 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
+ end
+
+ # Sets the value of field <tt>'Content-Length'</tt> to the given numeric;
+ # see {Content-Length response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-length-response-header]:
+ #
+ # _uri = uri.dup
+ # hostname = _uri.hostname # => "jsonplaceholder.typicode.com"
+ # _uri.path = '/posts' # => "/posts"
+ # req = Gem::Net::HTTP::Post.new(_uri) # => #<Gem::Net::HTTP::Post POST>
+ # req.body = '{"title": "foo","body": "bar","userId": 1}'
+ # req.content_length = req.body.size # => 42
+ # req.content_type = 'application/json'
+ # res = Gem::Net::HTTP.start(hostname) do |http|
+ # http.request(req)
+ # end # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
+ #
+ def content_length=(len)
+ unless len
+ @header.delete 'content-length'
+ return nil
+ end
+ @header['content-length'] = [len.to_i.to_s]
+ end
+
+ # Returns +true+ if field <tt>'Transfer-Encoding'</tt>
+ # exists and has value <tt>'chunked'</tt>,
+ # +false+ otherwise;
+ # see {Transfer-Encoding response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#transfer-encoding-response-header]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res['Transfer-Encoding'] # => "chunked"
+ # res.chunked? # => true
+ #
+ def chunked?
+ return false unless @header['transfer-encoding']
+ field = self['Transfer-Encoding']
+ (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
+ end
+
+ # Returns a Range object representing the value of field
+ # <tt>'Content-Range'</tt>, or +nil+ if no such field exists;
+ # see {Content-Range response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-range-response-header]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res['Content-Range'] # => nil
+ # res['Content-Range'] = 'bytes 0-499/1000'
+ # res['Content-Range'] # => "bytes 0-499/1000"
+ # res.content_range # => 0..499
+ #
+ def content_range
+ return nil unless @header['content-range']
+ m = %r<\A\s*(\w+)\s+(\d+)-(\d+)/(\d+|\*)>.match(self['Content-Range']) or
+ raise Gem::Net::HTTPHeaderSyntaxError, 'wrong Content-Range format'
+ return unless m[1] == 'bytes'
+ m[2].to_i .. m[3].to_i
+ end
+
+ # Returns the integer representing length of the value of field
+ # <tt>'Content-Range'</tt>, or +nil+ if no such field exists;
+ # see {Content-Range response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-range-response-header]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res['Content-Range'] # => nil
+ # res['Content-Range'] = 'bytes 0-499/1000'
+ # res.range_length # => 500
+ #
+ def range_length
+ r = content_range() or return nil
+ r.end - r.begin + 1
+ end
+
+ # Returns the {media type}[https://en.wikipedia.org/wiki/Media_type]
+ # from the value of field <tt>'Content-Type'</tt>,
+ # or +nil+ if no such field exists;
+ # see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res['content-type'] # => "application/json; charset=utf-8"
+ # res.content_type # => "application/json"
+ #
+ def content_type
+ main = main_type()
+ return nil unless main
+
+ sub = sub_type()
+ if sub
+ "#{main}/#{sub}"
+ else
+ main
+ end
+ end
+
+ # Returns the leading ('type') part of the
+ # {media type}[https://en.wikipedia.org/wiki/Media_type]
+ # from the value of field <tt>'Content-Type'</tt>,
+ # or +nil+ if no such field exists;
+ # see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res['content-type'] # => "application/json; charset=utf-8"
+ # res.main_type # => "application"
+ #
+ def main_type
+ return nil unless @header['content-type']
+ self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
+ end
+
+ # Returns the trailing ('subtype') part of the
+ # {media type}[https://en.wikipedia.org/wiki/Media_type]
+ # from the value of field <tt>'Content-Type'</tt>,
+ # or +nil+ if no such field exists;
+ # see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res['content-type'] # => "application/json; charset=utf-8"
+ # res.sub_type # => "json"
+ #
+ def sub_type
+ return nil unless @header['content-type']
+ _, sub = *self['Content-Type'].split(';').first.to_s.split('/')
+ return nil unless sub
+ sub.strip
+ end
+
+ # Returns the trailing ('parameters') part of the value of field <tt>'Content-Type'</tt>,
+ # or +nil+ if no such field exists;
+ # see {Content-Type response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-response-header]:
+ #
+ # res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
+ # res['content-type'] # => "application/json; charset=utf-8"
+ # res.type_params # => {"charset"=>"utf-8"}
+ #
+ def type_params
+ result = {}
+ list = self['Content-Type'].to_s.split(';')
+ list.shift
+ list.each do |param|
+ k, v = *param.split('=', 2)
+ result[k.strip] = v.strip
+ end
+ result
+ end
+
+ # Sets the value of field <tt>'Content-Type'</tt>;
+ # returns the new value;
+ # see {Content-Type request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-type-request-header]:
+ #
+ # req = Gem::Net::HTTP::Get.new(uri)
+ # req.set_content_type('application/json') # => ["application/json"]
+ #
+ # 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('')]
+ end
+
+ alias content_type= set_content_type
+
+ # Sets the request body to a URL-encoded string derived from argument +params+,
+ # and sets request header field <tt>'Content-Type'</tt>
+ # to <tt>'application/x-www-form-urlencoded'</tt>.
+ #
+ # The resulting request is suitable for HTTP request +POST+ or +PUT+.
+ #
+ # Argument +params+ must be suitable for use as argument +enum+ to
+ # {Gem::URI.encode_www_form}[https://docs.ruby-lang.org/en/master/Gem::URI.html#method-c-encode_www_form].
+ #
+ # With only argument +params+ given,
+ # sets the body to a URL-encoded string with the default separator <tt>'&'</tt>:
+ #
+ # req = Gem::Net::HTTP::Post.new('example.com')
+ #
+ # req.set_form_data(q: 'ruby', lang: 'en')
+ # req.body # => "q=ruby&lang=en"
+ # req['Content-Type'] # => "application/x-www-form-urlencoded"
+ #
+ # req.set_form_data([['q', 'ruby'], ['lang', 'en']])
+ # req.body # => "q=ruby&lang=en"
+ #
+ # req.set_form_data(q: ['ruby', 'perl'], lang: 'en')
+ # req.body # => "q=ruby&q=perl&lang=en"
+ #
+ # req.set_form_data([['q', 'ruby'], ['q', 'perl'], ['lang', 'en']])
+ # req.body # => "q=ruby&q=perl&lang=en"
+ #
+ # With string argument +sep+ also given,
+ # uses that string as the separator:
+ #
+ # req.set_form_data({q: 'ruby', lang: 'en'}, '|')
+ # req.body # => "q=ruby|lang=en"
+ #
+ # Gem::Net::HTTPHeader#form_data= is an alias for Gem::Net::HTTPHeader#set_form_data.
+ def set_form_data(params, sep = '&')
+ query = Gem::URI.encode_www_form(params)
+ query.gsub!(/&/, sep) if sep != '&'
+ self.body = query
+ self.content_type = 'application/x-www-form-urlencoded'
+ end
+
+ alias form_data= set_form_data
+
+ # Stores form data to be used in a +POST+ or +PUT+ request.
+ #
+ # The form data given in +params+ consists of zero or more fields;
+ # each field is:
+ #
+ # - A scalar value.
+ # - A name/value pair.
+ # - An IO stream opened for reading.
+ #
+ # Argument +params+ should be an
+ # {Enumerable}[https://docs.ruby-lang.org/en/master/Enumerable.html#module-Enumerable-label-Enumerable+in+Ruby+Classes]
+ # (method <tt>params.map</tt> will be called),
+ # and is often an array or hash.
+ #
+ # First, we set up a request:
+ #
+ # _uri = uri.dup
+ # _uri.path ='/posts'
+ # req = Gem::Net::HTTP::Post.new(_uri)
+ #
+ # <b>Argument +params+ As an Array</b>
+ #
+ # When +params+ is an array,
+ # each of its elements is a subarray that defines a field;
+ # the subarray may contain:
+ #
+ # - One string:
+ #
+ # req.set_form([['foo'], ['bar'], ['baz']])
+ #
+ # - Two strings:
+ #
+ # req.set_form([%w[foo 0], %w[bar 1], %w[baz 2]])
+ #
+ # - When argument +enctype+ (see below) is given as
+ # <tt>'multipart/form-data'</tt>:
+ #
+ # - A string name and an IO stream opened for reading:
+ #
+ # require 'stringio'
+ # req.set_form([['file', StringIO.new('Ruby is cool.')]])
+ #
+ # - A string name, an IO stream opened for reading,
+ # and an options hash, which may contain these entries:
+ #
+ # - +:filename+: The name of the file to use.
+ # - +:content_type+: The content type of the uploaded file.
+ #
+ # Example:
+ #
+ # req.set_form([['file', file, {filename: "other-filename.foo"}]]
+ #
+ # The various forms may be mixed:
+ #
+ # req.set_form(['foo', %w[bar 1], ['file', file]])
+ #
+ # <b>Argument +params+ As a Hash</b>
+ #
+ # When +params+ is a hash,
+ # each of its entries is a name/value pair that defines a field:
+ #
+ # - The name is a string.
+ # - The value may be:
+ #
+ # - +nil+.
+ # - Another string.
+ # - An IO stream opened for reading
+ # (only when argument +enctype+ -- see below -- is given as
+ # <tt>'multipart/form-data'</tt>).
+ #
+ # Examples:
+ #
+ # # Nil-valued fields.
+ # req.set_form({'foo' => nil, 'bar' => nil, 'baz' => nil})
+ #
+ # # String-valued fields.
+ # req.set_form({'foo' => 0, 'bar' => 1, 'baz' => 2})
+ #
+ # # IO-valued field.
+ # require 'stringio'
+ # req.set_form({'file' => StringIO.new('Ruby is cool.')})
+ #
+ # # Mixture of fields.
+ # req.set_form({'foo' => nil, 'bar' => 1, 'file' => file})
+ #
+ # Optional argument +enctype+ specifies the value to be given
+ # to field <tt>'Content-Type'</tt>, and must be one of:
+ #
+ # - <tt>'application/x-www-form-urlencoded'</tt> (the default).
+ # - <tt>'multipart/form-data'</tt>;
+ # see {RFC 7578}[https://www.rfc-editor.org/rfc/rfc7578].
+ #
+ # Optional argument +formopt+ is a hash of options
+ # (applicable only when argument +enctype+
+ # is <tt>'multipart/form-data'</tt>)
+ # that may include the following entries:
+ #
+ # - +:boundary+: The value is the boundary string for the multipart message.
+ # If not given, the boundary is a random string.
+ # See {Boundary}[https://www.rfc-editor.org/rfc/rfc7578#section-4.1].
+ # - +:charset+: Value is the character set for the form submission.
+ # Field names and values of non-file fields should be encoded with this charset.
+ #
+ def set_form(params, enctype='application/x-www-form-urlencoded', formopt={})
+ @body_data = params
+ @body = nil
+ @body_stream = nil
+ @form_option = formopt
+ case enctype
+ when /\Aapplication\/x-www-form-urlencoded\z/i,
+ /\Amultipart\/form-data\z/i
+ self.content_type = enctype
+ else
+ raise ArgumentError, "invalid enctype: #{enctype}"
+ end
+ end
+
+ # Sets header <tt>'Authorization'</tt> using the given
+ # +account+ and +password+ strings:
+ #
+ # req.basic_auth('my_account', 'my_password')
+ # req['Authorization']
+ # # => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
+ #
+ def basic_auth(account, password)
+ @header['authorization'] = [basic_encode(account, password)]
+ end
+
+ # Sets header <tt>'Proxy-Authorization'</tt> using the given
+ # +account+ and +password+ strings:
+ #
+ # req.proxy_basic_auth('my_account', 'my_password')
+ # req['Proxy-Authorization']
+ # # => "Basic bXlfYWNjb3VudDpteV9wYXNzd29yZA=="
+ #
+ def proxy_basic_auth(account, password)
+ @header['proxy-authorization'] = [basic_encode(account, password)]
+ end
+
+ def basic_encode(account, password)
+ 'Basic ' + ["#{account}:#{password}"].pack('m0')
+ end
+ private :basic_encode
+
+# 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}
+ @header['proxy-connection']&.grep(token) {return true}
+ false
+ end
+
+# 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}
+ @header['proxy-connection']&.grep(token) {return true}
+ false
+ end
+
+end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb b/lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb
new file mode 100644
index 0000000000..137295a883
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/proxy_delta.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+module Gem::Net::HTTP::ProxyDelta #:nodoc: internal use only
+ private
+
+ def conn_address
+ proxy_address()
+ end
+
+ def conn_port
+ proxy_port()
+ end
+
+ def edit_path(path)
+ use_ssl? ? path : "http://#{addr_port()}#{path}"
+ end
+end
+
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/request.rb b/lib/rubygems/vendor/net-http/lib/net/http/request.rb
new file mode 100644
index 0000000000..495ec9be54
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/request.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+# This class is the base class for \Gem::Net::HTTP request classes.
+# The class should not be used directly;
+# instead you should use its subclasses, listed below.
+#
+# == Creating a Request
+#
+# An request object may be created with either a Gem::URI or a string hostname:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('https://jsonplaceholder.typicode.com/')
+# req = Gem::Net::HTTP::Get.new(uri) # => #<Gem::Net::HTTP::Get GET>
+# req = Gem::Net::HTTP::Get.new(uri.hostname) # => #<Gem::Net::HTTP::Get GET>
+#
+# And with any of the subclasses:
+#
+# req = Gem::Net::HTTP::Head.new(uri) # => #<Gem::Net::HTTP::Head HEAD>
+# req = Gem::Net::HTTP::Post.new(uri) # => #<Gem::Net::HTTP::Post POST>
+# req = Gem::Net::HTTP::Put.new(uri) # => #<Gem::Net::HTTP::Put PUT>
+# # ...
+#
+# The new instance is suitable for use as the argument to Gem::Net::HTTP#request.
+#
+# == Request Headers
+#
+# A new request object has these header fields by default:
+#
+# req.to_hash
+# # =>
+# {"accept-encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"],
+# "accept"=>["*/*"],
+# "user-agent"=>["Ruby"],
+# "host"=>["jsonplaceholder.typicode.com"]}
+#
+# See:
+#
+# - {Request header Accept-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Accept-Encoding]
+# and {Compression and Decompression}[rdoc-ref:Gem::Net::HTTP@Compression+and+Decompression].
+# - {Request header Accept}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#accept-request-header].
+# - {Request header User-Agent}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#user-agent-request-header].
+# - {Request header Host}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#host-request-header].
+#
+# You can add headers or override default headers:
+#
+# # res = Gem::Net::HTTP::Get.new(uri, {'foo' => '0', 'bar' => '1'})
+#
+# This class (and therefore its subclasses) also includes (indirectly)
+# module Gem::Net::HTTPHeader, which gives access to its
+# {methods for setting headers}[rdoc-ref:Gem::Net::HTTPHeader@Setters].
+#
+# == Request Subclasses
+#
+# Subclasses for HTTP requests:
+#
+# - Gem::Net::HTTP::Get
+# - Gem::Net::HTTP::Head
+# - Gem::Net::HTTP::Post
+# - Gem::Net::HTTP::Put
+# - Gem::Net::HTTP::Delete
+# - Gem::Net::HTTP::Options
+# - Gem::Net::HTTP::Trace
+# - Gem::Net::HTTP::Patch
+#
+# Subclasses for WebDAV requests:
+#
+# - Gem::Net::HTTP::Propfind
+# - Gem::Net::HTTP::Proppatch
+# - Gem::Net::HTTP::Mkcol
+# - Gem::Net::HTTP::Copy
+# - Gem::Net::HTTP::Move
+# - Gem::Net::HTTP::Lock
+# - Gem::Net::HTTP::Unlock
+#
+class Gem::Net::HTTPRequest < Gem::Net::HTTPGenericRequest
+ # Creates an HTTP request object for +path+.
+ #
+ # +initheader+ are the default headers to use. Gem::Net::HTTP adds
+ # Accept-Encoding to enable compression of the response body unless
+ # Accept-Encoding or Range are supplied in +initheader+.
+
+ def initialize(path, initheader = nil)
+ super self.class::METHOD,
+ self.class::REQUEST_HAS_BODY,
+ self.class::RESPONSE_HAS_BODY,
+ path, initheader
+ end
+end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/requests.rb b/lib/rubygems/vendor/net-http/lib/net/http/requests.rb
new file mode 100644
index 0000000000..1a57ddc7c2
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/requests.rb
@@ -0,0 +1,425 @@
+# frozen_string_literal: true
+
+# HTTP/1.1 methods --- RFC2616
+
+# \Class for representing
+# {HTTP method GET}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#GET_method]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Get.new(uri) # => #<Gem::Net::HTTP::Get GET>
+# 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: 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.
+#
+# Related:
+#
+# - Gem::Net::HTTP.get: sends +GET+ request, returns response body.
+# - Gem::Net::HTTP#get: sends +GET+ request, returns response object.
+#
+class Gem::Net::HTTP::Get < Gem::Net::HTTPRequest
+ METHOD = 'GET'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {HTTP method HEAD}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#HEAD_method]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Head.new(uri) # => #<Gem::Net::HTTP::Head HEAD>
+# 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: 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.
+#
+# Related:
+#
+# - Gem::Net::HTTP#head: sends +HEAD+ request, returns response object.
+#
+class Gem::Net::HTTP::Head < Gem::Net::HTTPRequest
+ METHOD = 'HEAD'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = false
+end
+
+# \Class for representing
+# {HTTP method POST}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#POST_method]:
+#
+# 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::Post.new(uri) # => #<Gem::Net::HTTP::Post POST>
+# 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/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.
+#
+# Related:
+#
+# - Gem::Net::HTTP.post: sends +POST+ request, returns response object.
+# - Gem::Net::HTTP#post: sends +POST+ request, returns response object.
+#
+class Gem::Net::HTTP::Post < Gem::Net::HTTPRequest
+ METHOD = 'POST'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {HTTP method PUT}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#PUT_method]:
+#
+# 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::Put.new(uri) # => #<Gem::Net::HTTP::Put PUT>
+# 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/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.
+#
+class Gem::Net::HTTP::Put < Gem::Net::HTTPRequest
+ METHOD = 'PUT'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {HTTP method DELETE}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#DELETE_method]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# uri.path = '/posts/1'
+# req = Gem::Net::HTTP::Delete.new(uri) # => #<Gem::Net::HTTP::Delete DELETE>
+# 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: 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.
+#
+# Related:
+#
+# - Gem::Net::HTTP#delete: sends +DELETE+ request, returns response object.
+#
+class Gem::Net::HTTP::Delete < Gem::Net::HTTPRequest
+ METHOD = 'DELETE'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {HTTP method OPTIONS}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#OPTIONS_method]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Options.new(uri) # => #<Gem::Net::HTTP::Options OPTIONS>
+# 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: 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.
+#
+# Related:
+#
+# - Gem::Net::HTTP#options: sends +OPTIONS+ request, returns response object.
+#
+class Gem::Net::HTTP::Options < Gem::Net::HTTPRequest
+ METHOD = 'OPTIONS'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {HTTP method TRACE}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#TRACE_method]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Trace.new(uri) # => #<Gem::Net::HTTP::Trace TRACE>
+# 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: 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.
+#
+# Related:
+#
+# - Gem::Net::HTTP#trace: sends +TRACE+ request, returns response object.
+#
+class Gem::Net::HTTP::Trace < Gem::Net::HTTPRequest
+ METHOD = 'TRACE'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {HTTP method PATCH}[https://en.wikipedia.org/w/index.php?title=Hypertext_Transfer_Protocol#PATCH_method]:
+#
+# 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::Patch.new(uri) # => #<Gem::Net::HTTP::Patch PATCH>
+# 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/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.
+#
+# Related:
+#
+# - Gem::Net::HTTP#patch: sends +PATCH+ request, returns response object.
+#
+class Gem::Net::HTTP::Patch < Gem::Net::HTTPRequest
+ METHOD = 'PATCH'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
+end
+
+#
+# WebDAV methods --- RFC2518
+#
+
+# \Class for representing
+# {WebDAV method PROPFIND}[http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Propfind.new(uri) # => #<Gem::Net::HTTP::Propfind PROPFIND>
+# res = Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end
+#
+# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
+#
+# Related:
+#
+# - Gem::Net::HTTP#propfind: sends +PROPFIND+ request, returns response object.
+#
+class Gem::Net::HTTP::Propfind < Gem::Net::HTTPRequest
+ METHOD = 'PROPFIND'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {WebDAV method PROPPATCH}[http://www.webdav.org/specs/rfc4918.html#METHOD_PROPPATCH]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Proppatch.new(uri) # => #<Gem::Net::HTTP::Proppatch PROPPATCH>
+# res = Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end
+#
+# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
+#
+# Related:
+#
+# - Gem::Net::HTTP#proppatch: sends +PROPPATCH+ request, returns response object.
+#
+class Gem::Net::HTTP::Proppatch < Gem::Net::HTTPRequest
+ METHOD = 'PROPPATCH'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {WebDAV method MKCOL}[http://www.webdav.org/specs/rfc4918.html#METHOD_MKCOL]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Mkcol.new(uri) # => #<Gem::Net::HTTP::Mkcol MKCOL>
+# res = Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end
+#
+# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
+#
+# Related:
+#
+# - Gem::Net::HTTP#mkcol: sends +MKCOL+ request, returns response object.
+#
+class Gem::Net::HTTP::Mkcol < Gem::Net::HTTPRequest
+ METHOD = 'MKCOL'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {WebDAV method COPY}[http://www.webdav.org/specs/rfc4918.html#METHOD_COPY]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Copy.new(uri) # => #<Gem::Net::HTTP::Copy COPY>
+# res = Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end
+#
+# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
+#
+# Related:
+#
+# - Gem::Net::HTTP#copy: sends +COPY+ request, returns response object.
+#
+class Gem::Net::HTTP::Copy < Gem::Net::HTTPRequest
+ METHOD = 'COPY'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {WebDAV method MOVE}[http://www.webdav.org/specs/rfc4918.html#METHOD_MOVE]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Move.new(uri) # => #<Gem::Net::HTTP::Move MOVE>
+# res = Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end
+#
+# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
+#
+# Related:
+#
+# - Gem::Net::HTTP#move: sends +MOVE+ request, returns response object.
+#
+class Gem::Net::HTTP::Move < Gem::Net::HTTPRequest
+ METHOD = 'MOVE'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {WebDAV method LOCK}[http://www.webdav.org/specs/rfc4918.html#METHOD_LOCK]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Lock.new(uri) # => #<Gem::Net::HTTP::Lock LOCK>
+# res = Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end
+#
+# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
+#
+# Related:
+#
+# - Gem::Net::HTTP#lock: sends +LOCK+ request, returns response object.
+#
+class Gem::Net::HTTP::Lock < Gem::Net::HTTPRequest
+ METHOD = 'LOCK'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
+end
+
+# \Class for representing
+# {WebDAV method UNLOCK}[http://www.webdav.org/specs/rfc4918.html#METHOD_UNLOCK]:
+#
+# require 'rubygems/vendor/net-http/lib/net/http'
+# uri = Gem::URI('http://example.com')
+# hostname = uri.hostname # => "example.com"
+# req = Gem::Net::HTTP::Unlock.new(uri) # => #<Gem::Net::HTTP::Unlock UNLOCK>
+# res = Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end
+#
+# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
+#
+# Related:
+#
+# - Gem::Net::HTTP#unlock: sends +UNLOCK+ request, returns response object.
+#
+class Gem::Net::HTTP::Unlock < Gem::Net::HTTPRequest
+ 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
new file mode 100644
index 0000000000..cbbd191d87
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/response.rb
@@ -0,0 +1,738 @@
+# frozen_string_literal: true
+
+# This class is the base class for \Gem::Net::HTTP response classes.
+#
+# == About the Examples
+#
+# :include: doc/net-http/examples.rdoc
+#
+# == Returned Responses
+#
+# \Method Gem::Net::HTTP.get_response returns
+# an instance of one of the subclasses of \Gem::Net::HTTPResponse:
+#
+# Gem::Net::HTTP.get_response(uri)
+# # => #<Gem::Net::HTTPOK 200 OK readbody=true>
+# Gem::Net::HTTP.get_response(hostname, '/nosuch')
+# # => #<Gem::Net::HTTPNotFound 404 Not Found readbody=true>
+#
+# As does method Gem::Net::HTTP#request:
+#
+# req = Gem::Net::HTTP::Get.new(uri)
+# Gem::Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
+#
+# \Class \Gem::Net::HTTPResponse includes module Gem::Net::HTTPHeader,
+# which provides access to response header values via (among others):
+#
+# - \Hash-like method <tt>[]</tt>.
+# - Specific reader methods, such as +content_type+.
+#
+# Examples:
+#
+# res = Gem::Net::HTTP.get_response(uri) # => #<Gem::Net::HTTPOK 200 OK readbody=true>
+# res['Content-Type'] # => "text/html; charset=UTF-8"
+# res.content_type # => "text/html"
+#
+# == Response Subclasses
+#
+# \Class \Gem::Net::HTTPResponse has a subclass for each
+# {HTTP status code}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes].
+# You can look up the response class for a given code:
+#
+# Gem::Net::HTTPResponse::CODE_TO_OBJ['200'] # => Gem::Net::HTTPOK
+# Gem::Net::HTTPResponse::CODE_TO_OBJ['400'] # => Gem::Net::HTTPBadRequest
+# Gem::Net::HTTPResponse::CODE_TO_OBJ['404'] # => Gem::Net::HTTPNotFound
+#
+# And you can retrieve the status code for a response object:
+#
+# Gem::Net::HTTP.get_response(uri).code # => "200"
+# Gem::Net::HTTP.get_response(hostname, '/nosuch').code # => "404"
+#
+# The response subclasses (indentation shows class hierarchy):
+#
+# - Gem::Net::HTTPUnknownResponse (for unhandled \HTTP extensions).
+#
+# - Gem::Net::HTTPInformation:
+#
+# - Gem::Net::HTTPContinue (100)
+# - Gem::Net::HTTPSwitchProtocol (101)
+# - Gem::Net::HTTPProcessing (102)
+# - Gem::Net::HTTPEarlyHints (103)
+#
+# - Gem::Net::HTTPSuccess:
+#
+# - Gem::Net::HTTPOK (200)
+# - Gem::Net::HTTPCreated (201)
+# - Gem::Net::HTTPAccepted (202)
+# - Gem::Net::HTTPNonAuthoritativeInformation (203)
+# - Gem::Net::HTTPNoContent (204)
+# - Gem::Net::HTTPResetContent (205)
+# - Gem::Net::HTTPPartialContent (206)
+# - Gem::Net::HTTPMultiStatus (207)
+# - Gem::Net::HTTPAlreadyReported (208)
+# - Gem::Net::HTTPIMUsed (226)
+#
+# - Gem::Net::HTTPRedirection:
+#
+# - Gem::Net::HTTPMultipleChoices (300)
+# - Gem::Net::HTTPMovedPermanently (301)
+# - Gem::Net::HTTPFound (302)
+# - Gem::Net::HTTPSeeOther (303)
+# - Gem::Net::HTTPNotModified (304)
+# - Gem::Net::HTTPUseProxy (305)
+# - Gem::Net::HTTPTemporaryRedirect (307)
+# - Gem::Net::HTTPPermanentRedirect (308)
+#
+# - Gem::Net::HTTPClientError:
+#
+# - Gem::Net::HTTPBadRequest (400)
+# - Gem::Net::HTTPUnauthorized (401)
+# - Gem::Net::HTTPPaymentRequired (402)
+# - Gem::Net::HTTPForbidden (403)
+# - Gem::Net::HTTPNotFound (404)
+# - Gem::Net::HTTPMethodNotAllowed (405)
+# - Gem::Net::HTTPNotAcceptable (406)
+# - Gem::Net::HTTPProxyAuthenticationRequired (407)
+# - Gem::Net::HTTPRequestTimeOut (408)
+# - Gem::Net::HTTPConflict (409)
+# - Gem::Net::HTTPGone (410)
+# - Gem::Net::HTTPLengthRequired (411)
+# - Gem::Net::HTTPPreconditionFailed (412)
+# - Gem::Net::HTTPRequestEntityTooLarge (413)
+# - Gem::Net::HTTPRequestURITooLong (414)
+# - Gem::Net::HTTPUnsupportedMediaType (415)
+# - Gem::Net::HTTPRequestedRangeNotSatisfiable (416)
+# - Gem::Net::HTTPExpectationFailed (417)
+# - Gem::Net::HTTPMisdirectedRequest (421)
+# - Gem::Net::HTTPUnprocessableEntity (422)
+# - Gem::Net::HTTPLocked (423)
+# - Gem::Net::HTTPFailedDependency (424)
+# - Gem::Net::HTTPUpgradeRequired (426)
+# - Gem::Net::HTTPPreconditionRequired (428)
+# - Gem::Net::HTTPTooManyRequests (429)
+# - Gem::Net::HTTPRequestHeaderFieldsTooLarge (431)
+# - Gem::Net::HTTPUnavailableForLegalReasons (451)
+#
+# - Gem::Net::HTTPServerError:
+#
+# - Gem::Net::HTTPInternalServerError (500)
+# - Gem::Net::HTTPNotImplemented (501)
+# - Gem::Net::HTTPBadGateway (502)
+# - Gem::Net::HTTPServiceUnavailable (503)
+# - Gem::Net::HTTPGatewayTimeOut (504)
+# - Gem::Net::HTTPVersionNotSupported (505)
+# - Gem::Net::HTTPVariantAlsoNegotiates (506)
+# - Gem::Net::HTTPInsufficientStorage (507)
+# - Gem::Net::HTTPLoopDetected (508)
+# - Gem::Net::HTTPNotExtended (510)
+# - Gem::Net::HTTPNetworkAuthenticationRequired (511)
+#
+# There is also the Gem::Net::HTTPBadResponse exception which is raised when
+# there is a protocol error.
+#
+class Gem::Net::HTTPResponse
+ class << self
+ # true if the response has a body.
+ def body_permitted?
+ self::HAS_BODY
+ end
+
+ def exception_type # :nodoc: internal use only
+ self::EXCEPTION_TYPE
+ end
+
+ def read_new(sock) #:nodoc: internal use only
+ httpv, code, msg = read_status_line(sock)
+ res = response_class(code).new(httpv, code, msg)
+ each_response_header(sock) do |k,v|
+ res.add_field k, v
+ end
+ res
+ end
+
+ private
+
+ def read_status_line(sock)
+ str = sock.readline
+ 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
+ end
+
+ def response_class(code)
+ CODE_TO_OBJ[code] or
+ CODE_CLASS_TO_OBJ[code[0,1]] or
+ Gem::Net::HTTPUnknownResponse
+ end
+
+ def each_response_header(sock)
+ key = value = nil
+ while true
+ line = sock.readuntil("\n", true).sub(/\s+\z/, '')
+ break if line.empty?
+ if line[0] == ?\s or line[0] == ?\t and value
+ value << ' ' unless value.empty?
+ value << line.strip
+ else
+ yield key, value if key
+ key, value = line.strip.split(/\s*:\s*/, 2)
+ raise Gem::Net::HTTPBadResponse, 'wrong header line format' if value.nil?
+ end
+ end
+ yield key, value if key
+ end
+ end
+
+ # next is to fix bug in RDoc, where the private inside class << self
+ # spills out.
+ public
+
+ include Gem::Net::HTTPHeader
+
+ def initialize(httpv, code, msg) #:nodoc: internal use only
+ @http_version = httpv
+ @code = code
+ @message = msg
+ initialize_http_header nil
+ @body = nil
+ @read = false
+ @uri = nil
+ @decode_content = false
+ @body_encoding = false
+ @ignore_eof = true
+ end
+
+ # The HTTP version supported by the server.
+ attr_reader :http_version
+
+ # The HTTP result code string. For example, '302'. You can also
+ # determine the response type by examining which response subclass
+ # the response object is an instance of.
+ attr_reader :code
+
+ # The HTTP result message sent by the server. For example, 'Not Found'.
+ attr_reader :message
+ alias msg message # :nodoc: obsolete
+
+ # The Gem::URI used to fetch this response. The response Gem::URI is only available
+ # if a Gem::URI was used to create the request.
+ attr_reader :uri
+
+ # Set to true automatically when the request did not contain an
+ # Accept-Encoding header from the user.
+ attr_accessor :decode_content
+
+ # Returns the value set by body_encoding=, or +false+ if none;
+ # see #body_encoding=.
+ attr_reader :body_encoding
+
+ # Sets the encoding that should be used when reading the body:
+ #
+ # - If the given value is an Encoding object, that encoding will be used.
+ # - Otherwise if the value is a string, the value of
+ # {Encoding#find(value)}[https://docs.ruby-lang.org/en/master/Encoding.html#method-c-find]
+ # will be used.
+ # - Otherwise an encoding will be deduced from the body itself.
+ #
+ # Examples:
+ #
+ # http = Gem::Net::HTTP.new(hostname)
+ # req = Gem::Net::HTTP::Get.new('/')
+ #
+ # http.request(req) do |res|
+ # p res.body.encoding # => #<Encoding:ASCII-8BIT>
+ # end
+ #
+ # http.request(req) do |res|
+ # res.body_encoding = "UTF-8"
+ # p res.body.encoding # => #<Encoding:UTF-8>
+ # end
+ #
+ def body_encoding=(value)
+ value = Encoding.find(value) if value.is_a?(String)
+ @body_encoding = value
+ end
+
+ # Whether to ignore EOF when reading bodies with a specified Content-Length
+ # header.
+ attr_accessor :ignore_eof
+
+ def inspect
+ "#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
+ end
+
+ #
+ # response <-> exception relationship
+ #
+
+ def code_type #:nodoc:
+ self.class
+ end
+
+ def error! #:nodoc:
+ message = @code
+ message = "#{message} #{@message.dump}" if @message
+ raise error_type().new(message, self)
+ end
+
+ def error_type #:nodoc:
+ self.class::EXCEPTION_TYPE
+ end
+
+ # Raises an HTTP error if the response is not 2xx (success).
+ def value
+ error! unless self.kind_of?(Gem::Net::HTTPSuccess)
+ end
+
+ def uri= uri # :nodoc:
+ @uri = uri.dup if uri
+ end
+
+ #
+ # header (for backward compatibility only; DO NOT USE)
+ #
+
+ def response #:nodoc:
+ warn "Gem::Net::HTTPResponse#response is obsolete", uplevel: 1 if $VERBOSE
+ self
+ end
+
+ def header #:nodoc:
+ warn "Gem::Net::HTTPResponse#header is obsolete", uplevel: 1 if $VERBOSE
+ self
+ end
+
+ def read_header #:nodoc:
+ warn "Gem::Net::HTTPResponse#read_header is obsolete", uplevel: 1 if $VERBOSE
+ self
+ end
+
+ #
+ # body
+ #
+
+ def reading_body(sock, reqmethodallowbody) #:nodoc: internal use only
+ @socket = sock
+ @body_exist = reqmethodallowbody && self.class.body_permitted?
+ begin
+ yield
+ self.body # ensure to read body
+ ensure
+ @socket = nil
+ end
+ end
+
+ # Gets the entity body returned by the remote HTTP server.
+ #
+ # If a block is given, the body is passed to the block, and
+ # the body is provided in fragments, as it is read in from the socket.
+ #
+ # If +dest+ argument is given, response is read into that variable,
+ # with <code>dest#<<</code> method (it could be String or IO, or any
+ # other object responding to <code><<</code>).
+ #
+ # Calling this method a second or subsequent time for the same
+ # HTTPResponse object will return the value already read.
+ #
+ # http.request_get('/index.html') {|res|
+ # puts res.read_body
+ # }
+ #
+ # http.request_get('/index.html') {|res|
+ # p res.read_body.object_id # 538149362
+ # p res.read_body.object_id # 538149362
+ # }
+ #
+ # # using iterator
+ # http.request_get('/index.html') {|res|
+ # res.read_body do |segment|
+ # print segment
+ # end
+ # }
+ #
+ def read_body(dest = nil, &block)
+ if @read
+ raise IOError, "#{self.class}\#read_body called twice" if dest or block
+ return @body
+ end
+ to = procdest(dest, block)
+ stream_check
+ if @body_exist
+ read_body_0 to
+ @body = to
+ else
+ @body = nil
+ end
+ @read = true
+ return if @body.nil?
+
+ case enc = @body_encoding
+ when Encoding, false, nil
+ # Encoding: force given encoding
+ # false/nil: do not force encoding
+ else
+ # other value: detect encoding from body
+ enc = detect_encoding(@body)
+ end
+
+ @body.force_encoding(enc) if enc
+
+ @body
+ end
+
+ # Returns the string response body;
+ # note that repeated calls for the unmodified body return a cached string:
+ #
+ # path = '/todos/1'
+ # Gem::Net::HTTP.start(hostname) do |http|
+ # res = http.get(path)
+ # p res.body
+ # p http.head(path).body # No body.
+ # end
+ #
+ # Output:
+ #
+ # "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n}"
+ # nil
+ #
+ def body
+ read_body()
+ end
+
+ # Sets the body of the response to the given value.
+ def body=(value)
+ @body = value
+ end
+
+ alias entity body #:nodoc: obsolete
+
+ private
+
+ # :nodoc:
+ def detect_encoding(str, encoding=nil)
+ if encoding
+ elsif encoding = type_params['charset']
+ elsif encoding = check_bom(str)
+ else
+ encoding = case content_type&.downcase
+ when %r{text/x(?:ht)?ml|application/(?:[^+]+\+)?xml}
+ /\A<xml[ \t\r\n]+
+ version[ \t\r\n]*=[ \t\r\n]*(?:"[0-9.]+"|'[0-9.]*')[ \t\r\n]+
+ encoding[ \t\r\n]*=[ \t\r\n]*
+ (?:"([A-Za-z][\-A-Za-z0-9._]*)"|'([A-Za-z][\-A-Za-z0-9._]*)')/x =~ str
+ encoding = $1 || $2 || Encoding::UTF_8
+ when %r{text/html.*}
+ sniff_encoding(str)
+ end
+ end
+ return encoding
+ end
+
+ # :nodoc:
+ def sniff_encoding(str, encoding=nil)
+ # the encoding sniffing algorithm
+ # http://www.w3.org/TR/html5/parsing.html#determining-the-character-encoding
+ if enc = scanning_meta(str)
+ enc
+ # 6. last visited page or something
+ # 7. frequency
+ elsif str.ascii_only?
+ Encoding::US_ASCII
+ elsif str.dup.force_encoding(Encoding::UTF_8).valid_encoding?
+ Encoding::UTF_8
+ end
+ # 8. implementation-defined or user-specified
+ end
+
+ # :nodoc:
+ def check_bom(str)
+ case str.byteslice(0, 2)
+ when "\xFE\xFF"
+ return Encoding::UTF_16BE
+ when "\xFF\xFE"
+ return Encoding::UTF_16LE
+ end
+ if "\xEF\xBB\xBF" == str.byteslice(0, 3)
+ return Encoding::UTF_8
+ end
+ nil
+ end
+
+ # :nodoc:
+ def scanning_meta(str)
+ require 'strscan'
+ ss = StringScanner.new(str)
+ if ss.scan_until(/<meta[\t\n\f\r ]*/)
+ attrs = {} # attribute_list
+ got_pragma = false
+ need_pragma = nil
+ charset = nil
+
+ # step: Attributes
+ while attr = get_attribute(ss)
+ name, value = *attr
+ next if attrs[name]
+ attrs[name] = true
+ case name
+ when 'http-equiv'
+ got_pragma = true if value == 'content-type'
+ when 'content'
+ encoding = extracting_encodings_from_meta_elements(value)
+ unless charset
+ charset = encoding
+ end
+ need_pragma = true
+ when 'charset'
+ need_pragma = false
+ charset = value
+ end
+ end
+
+ # step: Processing
+ return if need_pragma.nil?
+ return if need_pragma && !got_pragma
+
+ charset = Encoding.find(charset) rescue nil
+ return unless charset
+ charset = Encoding::UTF_8 if charset == Encoding::UTF_16
+ return charset # tentative
+ end
+ nil
+ end
+
+ def get_attribute(ss)
+ ss.scan(/[\t\n\f\r \/]*/)
+ if ss.peek(1) == '>'
+ ss.getch
+ return nil
+ end
+ name = ss.scan(/[^=\t\n\f\r \/>]*/)
+ name.downcase!
+ raise if name.empty?
+ ss.skip(/[\t\n\f\r ]*/)
+ if ss.getch != '='
+ value = ''
+ return [name, value]
+ end
+ ss.skip(/[\t\n\f\r ]*/)
+ case ss.peek(1)
+ when '"'
+ ss.getch
+ value = ss.scan(/[^"]+/)
+ value.downcase!
+ ss.getch
+ when "'"
+ ss.getch
+ value = ss.scan(/[^']+/)
+ value.downcase!
+ ss.getch
+ when '>'
+ value = ''
+ else
+ value = ss.scan(/[^\t\n\f\r >]+/)
+ value.downcase!
+ end
+ [name, value]
+ end
+
+ def extracting_encodings_from_meta_elements(value)
+ # http://dev.w3.org/html5/spec/fetching-resources.html#algorithm-for-extracting-an-encoding-from-a-meta-element
+ if /charset[\t\n\f\r ]*=(?:"([^"]*)"|'([^']*)'|["']|\z|([^\t\n\f\r ;]+))/i =~ value
+ return $1 || $2 || $3
+ end
+ return nil
+ end
+
+ ##
+ # Checks for a supported Content-Encoding header and yields an Inflate
+ # wrapper for this response's socket when zlib is present. If the
+ # Content-Encoding is not supported or zlib is missing, the plain socket is
+ # yielded.
+ #
+ # If a Content-Range header is present, a plain socket is yielded as the
+ # bytes in the range may not be a complete deflate block.
+
+ def inflater # :nodoc:
+ return yield @socket unless Gem::Net::HTTP::HAVE_ZLIB
+ return yield @socket unless @decode_content
+ return yield @socket if self['content-range']
+
+ v = self['content-encoding']
+ case v&.downcase
+ when 'deflate', 'gzip', 'x-gzip' then
+ self.delete 'content-encoding'
+
+ inflate_body_io = Inflater.new(@socket)
+
+ begin
+ yield inflate_body_io
+ success = true
+ ensure
+ begin
+ inflate_body_io.finish
+ if self['content-length']
+ self['content-length'] = inflate_body_io.bytes_inflated.to_s
+ end
+ rescue => err
+ # Ignore #finish's error if there is an exception from yield
+ raise err if success
+ end
+ end
+ when 'none', 'identity' then
+ self.delete 'content-encoding'
+
+ yield @socket
+ else
+ yield @socket
+ end
+ end
+
+ def read_body_0(dest)
+ inflater do |inflate_body_io|
+ if chunked?
+ read_chunked dest, inflate_body_io
+ return
+ end
+
+ @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
+ end
+ @socket.read_all dest
+ end
+ end
+
+ ##
+ # read_chunked reads from +@socket+ for chunk-size, chunk-extension, CRLF,
+ # etc. and +chunk_data_io+ for chunk-data which may be deflate or gzip
+ # encoded.
+ #
+ # See RFC 2616 section 3.6.1 for definitions
+
+ def read_chunked(dest, chunk_data_io) # :nodoc:
+ total = 0
+ while true
+ line = @socket.readline
+ hexlen = line.slice(/[0-9a-fA-F]+/) or
+ raise Gem::Net::HTTPBadResponse, "wrong chunk size line: #{line}"
+ len = hexlen.hex
+ break if len == 0
+ begin
+ chunk_data_io.read len, dest
+ ensure
+ total += len
+ @socket.read 2 # \r\n
+ end
+ end
+ until @socket.readline.empty?
+ # none
+ end
+ end
+
+ def stream_check
+ raise IOError, 'attempt to read body out of block' if @socket.nil? || @socket.closed?
+ end
+
+ def procdest(dest, block)
+ raise ArgumentError, 'both arg and block given for HTTP method' if
+ dest and block
+ if block
+ Gem::Net::ReadAdapter.new(block)
+ else
+ dest || +''
+ end
+ end
+
+ ##
+ # Inflater is a wrapper around Gem::Net::BufferedIO that transparently inflates
+ # zlib and gzip streams.
+
+ class Inflater # :nodoc:
+
+ ##
+ # Creates a new Inflater wrapping +socket+
+
+ def initialize socket
+ @socket = socket
+ # zlib with automatic gzip detection
+ @inflate = Zlib::Inflate.new(32 + Zlib::MAX_WBITS)
+ end
+
+ ##
+ # Finishes the inflate stream.
+
+ def finish
+ return if @inflate.total_in == 0
+ @inflate.finish
+ end
+
+ ##
+ # The number of bytes inflated, used to update the Content-Length of
+ # the response.
+
+ def bytes_inflated
+ @inflate.total_out
+ end
+
+ ##
+ # Returns a Gem::Net::ReadAdapter that inflates each read chunk into +dest+.
+ #
+ # This allows a large response body to be inflated without storing the
+ # entire body in memory.
+
+ def inflate_adapter(dest)
+ if dest.respond_to?(:set_encoding)
+ dest.set_encoding(Encoding::ASCII_8BIT)
+ elsif dest.respond_to?(:force_encoding)
+ dest.force_encoding(Encoding::ASCII_8BIT)
+ end
+ block = proc do |compressed_chunk|
+ @inflate.inflate(compressed_chunk) do |chunk|
+ compressed_chunk.clear
+ dest << chunk
+ end
+ end
+
+ Gem::Net::ReadAdapter.new(block)
+ end
+
+ ##
+ # Reads +clen+ bytes from the socket, inflates them, then writes them to
+ # +dest+. +ignore_eof+ is passed down to Gem::Net::BufferedIO#read
+ #
+ # Unlike Gem::Net::BufferedIO#read, this method returns more than +clen+ bytes.
+ # At this time there is no way for a user of Gem::Net::HTTPResponse to read a
+ # specific number of bytes from the HTTP response body, so this internal
+ # API does not return the same number of bytes as were requested.
+ #
+ # See https://bugs.ruby-lang.org/issues/6492 for further discussion.
+
+ def read clen, dest, ignore_eof = false
+ temp_dest = inflate_adapter(dest)
+
+ @socket.read clen, temp_dest, ignore_eof
+ end
+
+ ##
+ # Reads the rest of the socket, inflates it, then writes it to +dest+.
+
+ def read_all dest
+ temp_dest = inflate_adapter(dest)
+
+ @socket.read_all temp_dest
+ end
+
+ 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
new file mode 100644
index 0000000000..0f26ae6c26
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/responses.rb
@@ -0,0 +1,1174 @@
+# frozen_string_literal: true
+#--
+# https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+
+module Gem::Net
+
+ class HTTPUnknownResponse < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = HTTPError #
+ end
+
+ # Parent class for informational (1xx) HTTP response classes.
+ #
+ # An informational response indicates that the request was received and understood.
+ #
+ # References:
+ #
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.1xx].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#1xx_informational_response].
+ #
+ class HTTPInformation < HTTPResponse
+ HAS_BODY = false
+ EXCEPTION_TYPE = HTTPError #
+ end
+
+ # Parent class for success (2xx) HTTP response classes.
+ #
+ # A success response indicates the action requested by the client
+ # was received, understood, and accepted.
+ #
+ # References:
+ #
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.2xx].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_success].
+ #
+ class HTTPSuccess < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = HTTPError #
+ end
+
+ # Parent class for redirection (3xx) HTTP response classes.
+ #
+ # A redirection response indicates the client must take additional action
+ # to complete the request.
+ #
+ # References:
+ #
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.3xx].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_redirection].
+ #
+ class HTTPRedirection < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = HTTPRetriableError #
+ end
+
+ # Parent class for client error (4xx) HTTP response classes.
+ #
+ # A client error response indicates that the client may have caused an error.
+ #
+ # References:
+ #
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.4xx].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors].
+ #
+ class HTTPClientError < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = HTTPClientException #
+ end
+
+ # Parent class for server error (5xx) HTTP response classes.
+ #
+ # A server error response indicates that the server failed to fulfill a request.
+ #
+ # References:
+ #
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#status.5xx].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_server_errors].
+ #
+ class HTTPServerError < HTTPResponse
+ HAS_BODY = true
+ EXCEPTION_TYPE = HTTPFatalError #
+ end
+
+ # Response class for +Continue+ responses (status code 100).
+ #
+ # A +Continue+ response indicates that the server has received the request headers.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-100-continue].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#100].
+ #
+ class HTTPContinue < HTTPInformation
+ HAS_BODY = false
+ end
+
+ # Response class for <tt>Switching Protocol</tt> responses (status code 101).
+ #
+ # The <tt>Switching Protocol<tt> response indicates that the server has received
+ # a request to switch protocols, and has agreed to do so.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-101-switching-protocols].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#101].
+ #
+ class HTTPSwitchProtocol < HTTPInformation
+ HAS_BODY = false
+ end
+
+ # Response class for +Processing+ responses (status code 102).
+ #
+ # The +Processing+ response indicates that the server has received
+ # and is processing the request, but no response is available yet.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {RFC 2518}[https://www.rfc-editor.org/rfc/rfc2518#section-10.1].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#102].
+ #
+ class HTTPProcessing < HTTPInformation
+ HAS_BODY = false
+ end
+
+ # Response class for <tt>Early Hints</tt> responses (status code 103).
+ #
+ # The <tt>Early Hints</tt> indicates that the server has received
+ # and is processing the request, and contains certain headers;
+ # the final response is not available yet.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103].
+ # - {RFC 8297}[https://www.rfc-editor.org/rfc/rfc8297.html#section-2].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#103].
+ #
+ class HTTPEarlyHints < HTTPInformation
+ HAS_BODY = false
+ end
+
+ # Response class for +OK+ responses (status code 200).
+ #
+ # The +OK+ response indicates that the server has received
+ # a request and has responded successfully.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-200-ok].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#200].
+ #
+ class HTTPOK < HTTPSuccess
+ HAS_BODY = true
+ end
+
+ # Response class for +Created+ responses (status code 201).
+ #
+ # The +Created+ response indicates that the server has received
+ # and has fulfilled a request to create a new resource.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-201-created].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#201].
+ #
+ class HTTPCreated < HTTPSuccess
+ HAS_BODY = true
+ end
+
+ # Response class for +Accepted+ responses (status code 202).
+ #
+ # The +Accepted+ response indicates that the server has received
+ # and is processing a request, but the processing has not yet been completed.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-202-accepted].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#202].
+ #
+ class HTTPAccepted < HTTPSuccess
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Non-Authoritative Information</tt> responses (status code 203).
+ #
+ # The <tt>Non-Authoritative Information</tt> response indicates that the server
+ # is a transforming proxy (such as a Web accelerator)
+ # that received a 200 OK response from its origin,
+ # and is returning a modified version of the origin's response.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/203].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-203-non-authoritative-infor].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#203].
+ #
+ class HTTPNonAuthoritativeInformation < HTTPSuccess
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>No Content</tt> responses (status code 204).
+ #
+ # The <tt>No Content</tt> response indicates that the server
+ # successfully processed the request, and is not returning any content.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-204-no-content].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#204].
+ #
+ class HTTPNoContent < HTTPSuccess
+ HAS_BODY = false
+ end
+
+ # Response class for <tt>Reset Content</tt> responses (status code 205).
+ #
+ # The <tt>Reset Content</tt> response indicates that the server
+ # successfully processed the request,
+ # asks that the client reset its document view, and is not returning any content.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/205].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-205-reset-content].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#205].
+ #
+ class HTTPResetContent < HTTPSuccess
+ HAS_BODY = false
+ end
+
+ # Response class for <tt>Partial Content</tt> responses (status code 206).
+ #
+ # The <tt>Partial Content</tt> response indicates that the server is delivering
+ # only part of the resource (byte serving)
+ # due to a Range header in the request.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-206-partial-content].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#206].
+ #
+ class HTTPPartialContent < HTTPSuccess
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Multi-Status (WebDAV)</tt> responses (status code 207).
+ #
+ # The <tt>Multi-Status (WebDAV)</tt> response indicates that the server
+ # has received the request,
+ # and that the message body can contain a number of separate response codes.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {RFC 4818}[https://www.rfc-editor.org/rfc/rfc4918#section-11.1].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#207].
+ #
+ class HTTPMultiStatus < HTTPSuccess
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Already Reported (WebDAV)</tt> responses (status code 208).
+ #
+ # The <tt>Already Reported (WebDAV)</tt> response indicates that the server
+ # has received the request,
+ # and that the members of a DAV binding have already been enumerated
+ # in a preceding part of the (multi-status) response,
+ # and are not being included again.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {RFC 5842}[https://www.rfc-editor.org/rfc/rfc5842.html#section-7.1].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#208].
+ #
+ class HTTPAlreadyReported < HTTPSuccess
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>IM Used</tt> responses (status code 226).
+ #
+ # The <tt>IM Used</tt> response indicates that the server has fulfilled a request
+ # for the resource, and the response is a representation of the result
+ # of one or more instance-manipulations applied to the current instance.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {RFC 3229}[https://www.rfc-editor.org/rfc/rfc3229.html#section-10.4.1].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#226].
+ #
+ class HTTPIMUsed < HTTPSuccess
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Multiple Choices</tt> responses (status code 300).
+ #
+ # The <tt>Multiple Choices</tt> response indicates that the server
+ # offers multiple options for the resource from which the client may choose.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/300].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-300-multiple-choices].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#300].
+ #
+ class HTTPMultipleChoices < HTTPRedirection
+ HAS_BODY = true
+ end
+ HTTPMultipleChoice = HTTPMultipleChoices
+
+ # Response class for <tt>Moved Permanently</tt> responses (status code 301).
+ #
+ # The <tt>Moved Permanently</tt> response indicates that links or records
+ # returning this response should be updated to use the given URL.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-301-moved-permanently].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#301].
+ #
+ class HTTPMovedPermanently < HTTPRedirection
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Found</tt> responses (status code 302).
+ #
+ # The <tt>Found</tt> response indicates that the client
+ # should look at (browse to) another URL.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-302-found].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#302].
+ #
+ class HTTPFound < HTTPRedirection
+ HAS_BODY = true
+ end
+ HTTPMovedTemporarily = HTTPFound
+
+ # Response class for <tt>See Other</tt> responses (status code 303).
+ #
+ # The response to the request can be found under another Gem::URI using the GET method.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-303-see-other].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#303].
+ #
+ class HTTPSeeOther < HTTPRedirection
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Not Modified</tt> responses (status code 304).
+ #
+ # Indicates that the resource has not been modified since the version
+ # specified by the request headers.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-304-not-modified].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#304].
+ #
+ class HTTPNotModified < HTTPRedirection
+ HAS_BODY = false
+ end
+
+ # Response class for <tt>Use Proxy</tt> responses (status code 305).
+ #
+ # The requested resource is available only through a proxy,
+ # whose address is provided in the response.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-305-use-proxy].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#305].
+ #
+ class HTTPUseProxy < HTTPRedirection
+ HAS_BODY = false
+ end
+
+ # Response class for <tt>Temporary Redirect</tt> responses (status code 307).
+ #
+ # The request should be repeated with another Gem::URI;
+ # however, future requests should still use the original Gem::URI.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-307-temporary-redirect].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#307].
+ #
+ class HTTPTemporaryRedirect < HTTPRedirection
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Permanent Redirect</tt> responses (status code 308).
+ #
+ # This and all future requests should be directed to the given Gem::URI.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-308-permanent-redirect].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#308].
+ #
+ class HTTPPermanentRedirect < HTTPRedirection
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Bad Request</tt> responses (status code 400).
+ #
+ # The server cannot or will not process the request due to an apparent client error.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-400-bad-request].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#400].
+ #
+ class HTTPBadRequest < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Unauthorized</tt> responses (status code 401).
+ #
+ # Authentication is required, but either was not provided or failed.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-401-unauthorized].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#401].
+ #
+ class HTTPUnauthorized < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Payment Required</tt> responses (status code 402).
+ #
+ # Reserved for future use.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/402].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-402-payment-required].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#402].
+ #
+ class HTTPPaymentRequired < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Forbidden</tt> responses (status code 403).
+ #
+ # The request contained valid data and was understood by the server,
+ # but the server is refusing action.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-403-forbidden].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#403].
+ #
+ class HTTPForbidden < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Not Found</tt> responses (status code 404).
+ #
+ # The requested resource could not be found but may be available in the future.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-404-not-found].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#404].
+ #
+ class HTTPNotFound < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Method Not Allowed</tt> responses (status code 405).
+ #
+ # The request method is not supported for the requested resource.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-405-method-not-allowed].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#405].
+ #
+ class HTTPMethodNotAllowed < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Not Acceptable</tt> responses (status code 406).
+ #
+ # The requested resource is capable of generating only content
+ # that not acceptable according to the Accept headers sent in the request.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-406-not-acceptable].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#406].
+ #
+ class HTTPNotAcceptable < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Proxy Authentication Required</tt> responses (status code 407).
+ #
+ # The client must first authenticate itself with the proxy.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-407-proxy-authentication-re].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#407].
+ #
+ class HTTPProxyAuthenticationRequired < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Request Gem::Timeout</tt> responses (status code 408).
+ #
+ # The server timed out waiting for the request.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-408-request-timeout].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#408].
+ #
+ class HTTPRequestTimeout < HTTPClientError
+ HAS_BODY = true
+ end
+ HTTPRequestTimeOut = HTTPRequestTimeout
+
+ # Response class for <tt>Conflict</tt> responses (status code 409).
+ #
+ # The request could not be processed because of conflict in the current state of the resource.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-409-conflict].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#409].
+ #
+ class HTTPConflict < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Gone</tt> responses (status code 410).
+ #
+ # The resource requested was previously in use but is no longer available
+ # and will not be available again.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/410].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-410-gone].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#410].
+ #
+ class HTTPGone < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Length Required</tt> responses (status code 411).
+ #
+ # The request did not specify the length of its content,
+ # which is required by the requested resource.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/411].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-411-length-required].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#411].
+ #
+ class HTTPLengthRequired < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Precondition Failed</tt> responses (status code 412).
+ #
+ # The server does not meet one of the preconditions
+ # specified in the request headers.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-412-precondition-failed].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#412].
+ #
+ class HTTPPreconditionFailed < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Payload Too Large</tt> responses (status code 413).
+ #
+ # The request is larger than the server is willing or able to process.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-413-content-too-large].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#413].
+ #
+ class HTTPPayloadTooLarge < HTTPClientError
+ HAS_BODY = true
+ end
+ HTTPRequestEntityTooLarge = HTTPPayloadTooLarge
+
+ # Response class for <tt>Gem::URI Too Long</tt> responses (status code 414).
+ #
+ # The Gem::URI provided was too long for the server to process.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-414-uri-too-long].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#414].
+ #
+ class HTTPURITooLong < HTTPClientError
+ HAS_BODY = true
+ end
+ HTTPRequestURITooLong = HTTPURITooLong
+ HTTPRequestURITooLarge = HTTPRequestURITooLong
+
+ # Response class for <tt>Unsupported Media Type</tt> responses (status code 415).
+ #
+ # The request entity has a media type which the server or resource does not support.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#415].
+ #
+ class HTTPUnsupportedMediaType < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Range Not Satisfiable</tt> responses (status code 416).
+ #
+ # The request entity has a media type which the server or resource does not support.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-416-range-not-satisfiable].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#416].
+ #
+ class HTTPRangeNotSatisfiable < HTTPClientError
+ HAS_BODY = true
+ end
+ HTTPRequestedRangeNotSatisfiable = HTTPRangeNotSatisfiable
+
+ # Response class for <tt>Expectation Failed</tt> responses (status code 417).
+ #
+ # The server cannot meet the requirements of the Expect request-header field.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/417].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-417-expectation-failed].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#417].
+ #
+ class HTTPExpectationFailed < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # 418 I'm a teapot - RFC 2324; a joke RFC
+ # See https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#418.
+
+ # 420 Enhance Your Calm - Twitter
+
+ # Response class for <tt>Misdirected Request</tt> responses (status code 421).
+ #
+ # The request was directed at a server that is not able to produce a response.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-421-misdirected-request].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#421].
+ #
+ class HTTPMisdirectedRequest < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Unprocessable Entity</tt> responses (status code 422).
+ #
+ # The request was well-formed but had semantic errors.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-422-unprocessable-content].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#422].
+ #
+ class HTTPUnprocessableEntity < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Locked (WebDAV)</tt> responses (status code 423).
+ #
+ # The requested resource is locked.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {RFC 4918}[https://www.rfc-editor.org/rfc/rfc4918#section-11.3].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#423].
+ #
+ class HTTPLocked < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Failed Dependency (WebDAV)</tt> responses (status code 424).
+ #
+ # The request failed because it depended on another request and that request failed.
+ # See {424 Failed Dependency (WebDAV)}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#424].
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {RFC 4918}[https://www.rfc-editor.org/rfc/rfc4918#section-11.4].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#424].
+ #
+ class HTTPFailedDependency < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # 425 Too Early
+ # https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#425.
+
+ # Response class for <tt>Upgrade Required</tt> responses (status code 426).
+ #
+ # The client should switch to the protocol given in the Upgrade header field.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/426].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-426-upgrade-required].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#426].
+ #
+ class HTTPUpgradeRequired < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Precondition Required</tt> responses (status code 428).
+ #
+ # The origin server requires the request to be conditional.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/428].
+ # - {RFC 6585}[https://www.rfc-editor.org/rfc/rfc6585#section-3].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#428].
+ #
+ class HTTPPreconditionRequired < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Too Many Requests</tt> responses (status code 429).
+ #
+ # The user has sent too many requests in a given amount of time.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429].
+ # - {RFC 6585}[https://www.rfc-editor.org/rfc/rfc6585#section-4].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#429].
+ #
+ class HTTPTooManyRequests < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Request Header Fields Too Large</tt> responses (status code 431).
+ #
+ # An individual header field is too large,
+ # or all the header fields collectively, are too large.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431].
+ # - {RFC 6585}[https://www.rfc-editor.org/rfc/rfc6585#section-5].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#431].
+ #
+ class HTTPRequestHeaderFieldsTooLarge < HTTPClientError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Unavailable For Legal Reasons</tt> responses (status code 451).
+ #
+ # A server operator has received a legal demand to deny access to a resource or to a set of resources
+ # that includes the requested resource.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/451].
+ # - {RFC 7725}[https://www.rfc-editor.org/rfc/rfc7725.html#section-3].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#451].
+ #
+ class HTTPUnavailableForLegalReasons < HTTPClientError
+ HAS_BODY = true
+ end
+ # 444 No Response - Nginx
+ # 449 Retry With - Microsoft
+ # 450 Blocked by Windows Parental Controls - Microsoft
+ # 499 Client Closed Request - Nginx
+
+ # Response class for <tt>Internal Server Error</tt> responses (status code 500).
+ #
+ # An unexpected condition was encountered and no more specific message is suitable.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-500-internal-server-error].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#500].
+ #
+ class HTTPInternalServerError < HTTPServerError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Not Implemented</tt> responses (status code 501).
+ #
+ # The server either does not recognize the request method,
+ # or it lacks the ability to fulfil the request.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-501-not-implemented].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#501].
+ #
+ class HTTPNotImplemented < HTTPServerError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Bad Gateway</tt> responses (status code 502).
+ #
+ # The server was acting as a gateway or proxy
+ # and received an invalid response from the upstream server.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-502-bad-gateway].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#502].
+ #
+ class HTTPBadGateway < HTTPServerError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Service Unavailable</tt> responses (status code 503).
+ #
+ # The server cannot handle the request
+ # (because it is overloaded or down for maintenance).
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-503-service-unavailable].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#503].
+ #
+ class HTTPServiceUnavailable < HTTPServerError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Gateway Gem::Timeout</tt> responses (status code 504).
+ #
+ # The server was acting as a gateway or proxy
+ # and did not receive a timely response from the upstream server.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-504-gateway-timeout].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#504].
+ #
+ class HTTPGatewayTimeout < HTTPServerError
+ HAS_BODY = true
+ end
+ HTTPGatewayTimeOut = HTTPGatewayTimeout
+
+ # Response class for <tt>HTTP Version Not Supported</tt> responses (status code 505).
+ #
+ # The server does not support the HTTP version used in the request.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/505].
+ # - {RFC 9110}[https://www.rfc-editor.org/rfc/rfc9110.html#name-505-http-version-not-suppor].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#505].
+ #
+ class HTTPVersionNotSupported < HTTPServerError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Variant Also Negotiates</tt> responses (status code 506).
+ #
+ # Transparent content negotiation for the request results in a circular reference.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/506].
+ # - {RFC 2295}[https://www.rfc-editor.org/rfc/rfc2295#section-8.1].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#506].
+ #
+ class HTTPVariantAlsoNegotiates < HTTPServerError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Insufficient Storage (WebDAV)</tt> responses (status code 507).
+ #
+ # The server is unable to store the representation needed to complete the request.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/507].
+ # - {RFC 4918}[https://www.rfc-editor.org/rfc/rfc4918#section-11.5].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#507].
+ #
+ class HTTPInsufficientStorage < HTTPServerError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Loop Detected (WebDAV)</tt> responses (status code 508).
+ #
+ # The server detected an infinite loop while processing the request.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508].
+ # - {RFC 5942}[https://www.rfc-editor.org/rfc/rfc5842.html#section-7.2].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#508].
+ #
+ class HTTPLoopDetected < HTTPServerError
+ HAS_BODY = true
+ end
+ # 509 Bandwidth Limit Exceeded - Apache bw/limited extension
+
+ # Response class for <tt>Not Extended</tt> responses (status code 510).
+ #
+ # Further extensions to the request are required for the server to fulfill it.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/510].
+ # - {RFC 2774}[https://www.rfc-editor.org/rfc/rfc2774.html#section-7].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#510].
+ #
+ class HTTPNotExtended < HTTPServerError
+ HAS_BODY = true
+ end
+
+ # Response class for <tt>Network Authentication Required</tt> responses (status code 511).
+ #
+ # The client needs to authenticate to gain network access.
+ #
+ # :include: doc/net-http/included_getters.rdoc
+ #
+ # References:
+ #
+ # - {Mozilla}[https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/511].
+ # - {RFC 6585}[https://www.rfc-editor.org/rfc/rfc6585#section-6].
+ # - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#511].
+ #
+ class HTTPNetworkAuthenticationRequired < HTTPServerError
+ HAS_BODY = true
+ end
+
+end
+
+class Gem::Net::HTTPResponse
+ CODE_CLASS_TO_OBJ = {
+ '1' => Gem::Net::HTTPInformation,
+ '2' => Gem::Net::HTTPSuccess,
+ '3' => Gem::Net::HTTPRedirection,
+ '4' => Gem::Net::HTTPClientError,
+ '5' => Gem::Net::HTTPServerError
+ }
+ CODE_TO_OBJ = {
+ '100' => Gem::Net::HTTPContinue,
+ '101' => Gem::Net::HTTPSwitchProtocol,
+ '102' => Gem::Net::HTTPProcessing,
+ '103' => Gem::Net::HTTPEarlyHints,
+
+ '200' => Gem::Net::HTTPOK,
+ '201' => Gem::Net::HTTPCreated,
+ '202' => Gem::Net::HTTPAccepted,
+ '203' => Gem::Net::HTTPNonAuthoritativeInformation,
+ '204' => Gem::Net::HTTPNoContent,
+ '205' => Gem::Net::HTTPResetContent,
+ '206' => Gem::Net::HTTPPartialContent,
+ '207' => Gem::Net::HTTPMultiStatus,
+ '208' => Gem::Net::HTTPAlreadyReported,
+ '226' => Gem::Net::HTTPIMUsed,
+
+ '300' => Gem::Net::HTTPMultipleChoices,
+ '301' => Gem::Net::HTTPMovedPermanently,
+ '302' => Gem::Net::HTTPFound,
+ '303' => Gem::Net::HTTPSeeOther,
+ '304' => Gem::Net::HTTPNotModified,
+ '305' => Gem::Net::HTTPUseProxy,
+ '307' => Gem::Net::HTTPTemporaryRedirect,
+ '308' => Gem::Net::HTTPPermanentRedirect,
+
+ '400' => Gem::Net::HTTPBadRequest,
+ '401' => Gem::Net::HTTPUnauthorized,
+ '402' => Gem::Net::HTTPPaymentRequired,
+ '403' => Gem::Net::HTTPForbidden,
+ '404' => Gem::Net::HTTPNotFound,
+ '405' => Gem::Net::HTTPMethodNotAllowed,
+ '406' => Gem::Net::HTTPNotAcceptable,
+ '407' => Gem::Net::HTTPProxyAuthenticationRequired,
+ '408' => Gem::Net::HTTPRequestTimeout,
+ '409' => Gem::Net::HTTPConflict,
+ '410' => Gem::Net::HTTPGone,
+ '411' => Gem::Net::HTTPLengthRequired,
+ '412' => Gem::Net::HTTPPreconditionFailed,
+ '413' => Gem::Net::HTTPPayloadTooLarge,
+ '414' => Gem::Net::HTTPURITooLong,
+ '415' => Gem::Net::HTTPUnsupportedMediaType,
+ '416' => Gem::Net::HTTPRangeNotSatisfiable,
+ '417' => Gem::Net::HTTPExpectationFailed,
+ '421' => Gem::Net::HTTPMisdirectedRequest,
+ '422' => Gem::Net::HTTPUnprocessableEntity,
+ '423' => Gem::Net::HTTPLocked,
+ '424' => Gem::Net::HTTPFailedDependency,
+ '426' => Gem::Net::HTTPUpgradeRequired,
+ '428' => Gem::Net::HTTPPreconditionRequired,
+ '429' => Gem::Net::HTTPTooManyRequests,
+ '431' => Gem::Net::HTTPRequestHeaderFieldsTooLarge,
+ '451' => Gem::Net::HTTPUnavailableForLegalReasons,
+
+ '500' => Gem::Net::HTTPInternalServerError,
+ '501' => Gem::Net::HTTPNotImplemented,
+ '502' => Gem::Net::HTTPBadGateway,
+ '503' => Gem::Net::HTTPServiceUnavailable,
+ '504' => Gem::Net::HTTPGatewayTimeout,
+ '505' => Gem::Net::HTTPVersionNotSupported,
+ '506' => Gem::Net::HTTPVariantAlsoNegotiates,
+ '507' => Gem::Net::HTTPInsufficientStorage,
+ '508' => Gem::Net::HTTPLoopDetected,
+ '510' => Gem::Net::HTTPNotExtended,
+ '511' => Gem::Net::HTTPNetworkAuthenticationRequired,
+ }
+end
diff --git a/lib/rubygems/vendor/net-http/lib/net/http/status.rb b/lib/rubygems/vendor/net-http/lib/net/http/status.rb
new file mode 100644
index 0000000000..9110b108b8
--- /dev/null
+++ b/lib/rubygems/vendor/net-http/lib/net/http/status.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require_relative '../http'
+
+if $0 == __FILE__
+ require 'open-uri'
+ File.foreach(__FILE__) do |line|
+ puts line
+ break if line.start_with?('end')
+ end
+ puts
+ puts "Gem::Net::HTTP::STATUS_CODES = {"
+ url = "https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv"
+ Gem::URI(url).read.each_line do |line|
+ code, mes, = line.split(',')
+ next if ['(Unused)', 'Unassigned', 'Description'].include?(mes)
+ puts " #{code} => '#{mes}',"
+ end
+ puts "} # :nodoc:"
+end
+
+Gem::Net::HTTP::STATUS_CODES = {
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+ 102 => 'Processing',
+ 103 => 'Early Hints',
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+ 207 => 'Multi-Status',
+ 208 => 'Already Reported',
+ 226 => 'IM Used',
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+ 308 => 'Permanent Redirect',
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Content Too Large',
+ 414 => 'URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+ 421 => 'Misdirected Request',
+ 422 => 'Unprocessable Content',
+ 423 => 'Locked',
+ 424 => 'Failed Dependency',
+ 425 => 'Too Early',
+ 426 => 'Upgrade Required',
+ 428 => 'Precondition Required',
+ 429 => 'Too Many Requests',
+ 431 => 'Request Header Fields Too Large',
+ 451 => 'Unavailable For Legal Reasons',
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ 506 => 'Variant Also Negotiates',
+ 507 => 'Insufficient Storage',
+ 508 => 'Loop Detected',
+ 510 => 'Not Extended (OBSOLETED)',
+ 511 => 'Network Authentication Required',
+} # :nodoc: