summaryrefslogtreecommitdiff
path: root/lib/net
diff options
context:
space:
mode:
Diffstat (limited to 'lib/net')
-rw-r--r--lib/net/http.rb278
-rw-r--r--lib/net/http/backward.rb40
-rw-r--r--lib/net/http/exceptions.rb3
-rw-r--r--lib/net/http/generic_request.rb45
-rw-r--r--lib/net/http/header.rb14
-rw-r--r--lib/net/http/net-http.gemspec10
-rw-r--r--lib/net/http/requests.rb69
-rw-r--r--lib/net/http/response.rb3
-rw-r--r--lib/net/http/responses.rb72
-rw-r--r--lib/net/net-protocol.gemspec6
-rw-r--r--lib/net/protocol.rb15
11 files changed, 375 insertions, 180 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 387df4b8f4..53295fe90c 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -37,7 +37,7 @@ module Net #:nodoc:
# For information about \HTTP, see:
#
# - {Hypertext Transfer Protocol}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol].
- # - {Technical overview}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview].
+ # - {Technology}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technology].
#
# == About the Examples
#
@@ -67,10 +67,12 @@ module Net #:nodoc:
# Net::HTTP.post(uri, data)
# params = {title: 'foo', body: 'bar', userId: 1}
# Net::HTTP.post_form(uri, params)
+ # data = '{"title": "foo", "body": "bar", "userId": 1}'
+ # Net::HTTP.put(uri, data)
#
# - If performance is important, consider using sessions, which lower request overhead.
# This {session}[rdoc-ref:Net::HTTP@Sessions] has multiple requests for
- # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]
+ # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method]
# and {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
#
# Net::HTTP.start(hostname) do |http|
@@ -196,7 +198,7 @@ module Net #:nodoc:
# In the block, you can use these instance methods,
# each of which that sends a single request:
#
- # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
+ # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method]:
#
# - #get, #request_get: GET.
# - #head, #request_head: HEAD.
@@ -445,7 +447,7 @@ module Net #:nodoc:
# if the response has header <tt>'Content-Range'</tt>.
#
# Otherwise decompression (or not) depends on the value of header
- # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-encoding-response-header]:
+ # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Content-Encoding_2]:
#
# - <tt>'deflate'</tt>, <tt>'gzip'</tt>, or <tt>'x-gzip'</tt>:
# decompresses the body and deletes the header.
@@ -456,6 +458,10 @@ module Net #:nodoc:
#
# == What's Here
#
+ # First, what's elsewhere. Class Net::HTTP:
+ #
+ # - Inherits from {class Object}[rdoc-ref:Object#class-object-whats-here].
+ #
# This is a categorized summary of methods and attributes.
#
# === \Net::HTTP Objects
@@ -469,8 +475,7 @@ module Net #:nodoc:
#
# - {::start}[rdoc-ref:Net::HTTP.start]:
# Begins a new session in a new \Net::HTTP object.
- # - {#started?}[rdoc-ref:Net::HTTP#started?]
- # (aliased as {#active?}[rdoc-ref:Net::HTTP#active?]):
+ # - {#started?}[rdoc-ref:Net::HTTP#started?]:
# Returns whether in a session.
# - {#finish}[rdoc-ref:Net::HTTP#finish]:
# Ends an active session.
@@ -520,6 +525,8 @@ module Net #:nodoc:
# Sends a POST request with form data and returns a response object.
# - {::post}[rdoc-ref:Net::HTTP.post]:
# Sends a POST request with data and returns a response object.
+ # - {::put}[rdoc-ref:Net::HTTP.put]:
+ # Sends a PUT request with data and returns a response object.
# - {#copy}[rdoc-ref:Net::HTTP#copy]:
# Sends a COPY request and returns a response object.
# - {#delete}[rdoc-ref:Net::HTTP#delete]:
@@ -548,18 +555,15 @@ module Net #:nodoc:
# Sends a PUT request and returns a response object.
# - {#request}[rdoc-ref:Net::HTTP#request]:
# Sends a request and returns a response object.
- # - {#request_get}[rdoc-ref:Net::HTTP#request_get]
- # (aliased as {#get2}[rdoc-ref:Net::HTTP#get2]):
+ # - {#request_get}[rdoc-ref:Net::HTTP#request_get]:
# Sends a GET request and forms a response object;
# if a block given, calls the block with the object,
# otherwise returns the object.
- # - {#request_head}[rdoc-ref:Net::HTTP#request_head]
- # (aliased as {#head2}[rdoc-ref:Net::HTTP#head2]):
+ # - {#request_head}[rdoc-ref:Net::HTTP#request_head]:
# Sends a HEAD request and forms a response object;
# if a block given, calls the block with the object,
# otherwise returns the object.
- # - {#request_post}[rdoc-ref:Net::HTTP#request_post]
- # (aliased as {#post2}[rdoc-ref:Net::HTTP#post2]):
+ # - {#request_post}[rdoc-ref:Net::HTTP#request_post]:
# Sends a POST request and forms a response object;
# if a block given, calls the block with the object,
# otherwise returns the object.
@@ -597,8 +601,7 @@ module Net #:nodoc:
# Returns whether +self+ is a proxy class.
# - {#proxy?}[rdoc-ref:Net::HTTP#proxy?]:
# Returns whether +self+ has a proxy.
- # - {#proxy_address}[rdoc-ref:Net::HTTP#proxy_address]
- # (aliased as {#proxyaddr}[rdoc-ref:Net::HTTP#proxyaddr]):
+ # - {#proxy_address}[rdoc-ref:Net::HTTP#proxy_address]:
# Returns the proxy address.
# - {#proxy_from_env?}[rdoc-ref:Net::HTTP#proxy_from_env?]:
# Returns whether the proxy is taken from an environment variable.
@@ -710,8 +713,7 @@ module Net #:nodoc:
# === \HTTP Version
#
# - {::version_1_2?}[rdoc-ref:Net::HTTP.version_1_2?]
- # (aliased as {::is_version_1_2?}[rdoc-ref:Net::HTTP.is_version_1_2?]
- # and {::version_1_2}[rdoc-ref:Net::HTTP.version_1_2]):
+ # (aliased as {::version_1_2}[rdoc-ref:Net::HTTP.version_1_2]):
# Returns true; retained for compatibility.
#
# === Debugging
@@ -722,7 +724,7 @@ module Net #:nodoc:
class HTTP < Protocol
# :stopdoc:
- VERSION = "0.4.1"
+ VERSION = "0.9.1"
HTTPVersion = '1.1'
begin
require 'zlib'
@@ -889,6 +891,39 @@ module Net #:nodoc:
}
end
+ # Sends a PUT request to the server; returns a Net::HTTPResponse object.
+ #
+ # Argument +url+ must be a URL;
+ # argument +data+ must be a string:
+ #
+ # _uri = uri.dup
+ # _uri.path = '/posts'
+ # data = '{"title": "foo", "body": "bar", "userId": 1}'
+ # headers = {'content-type': 'application/json'}
+ # res = Net::HTTP.put(_uri, data, headers) # => #<Net::HTTPCreated 201 Created readbody=true>
+ # puts res.body
+ #
+ # Output:
+ #
+ # {
+ # "title": "foo",
+ # "body": "bar",
+ # "userId": 1,
+ # "id": 101
+ # }
+ #
+ # Related:
+ #
+ # - Net::HTTP::Put: request class for \HTTP method +PUT+.
+ # - Net::HTTP#put: convenience method for \HTTP method +PUT+.
+ #
+ def HTTP.put(url, data, header = nil)
+ start(url.hostname, url.port,
+ :use_ssl => url.scheme == 'https' ) {|http|
+ http.put(url, data, header)
+ }
+ end
+
#
# \HTTP session management
#
@@ -1062,7 +1097,7 @@ module Net #:nodoc:
# For proxy-defining arguments +p_addr+ through +p_no_proxy+,
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
#
- def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
+ def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil, p_use_ssl = nil)
http = super address, port
if proxy_class? then # from Net::HTTP::Proxy()
@@ -1071,6 +1106,7 @@ module Net #:nodoc:
http.proxy_port = @proxy_port
http.proxy_user = @proxy_user
http.proxy_pass = @proxy_pass
+ http.proxy_use_ssl = @proxy_use_ssl
elsif p_addr == :ENV then
http.proxy_from_env = true
else
@@ -1082,34 +1118,68 @@ module Net #:nodoc:
http.proxy_port = p_port || default_port
http.proxy_user = p_user
http.proxy_pass = p_pass
+ http.proxy_use_ssl = p_use_ssl
end
http
end
+ class << HTTP
+ # Allows to set the default configuration that will be used
+ # when creating a new connection.
+ #
+ # Example:
+ #
+ # Net::HTTP.default_configuration = {
+ # read_timeout: 1,
+ # write_timeout: 1
+ # }
+ # http = Net::HTTP.new(hostname)
+ # http.open_timeout # => 60
+ # http.read_timeout # => 1
+ # http.write_timeout # => 1
+ #
+ attr_accessor :default_configuration
+ end
+
# Creates a new \Net::HTTP object for the specified server address,
# without opening the TCP connection or initializing the \HTTP session.
# The +address+ should be a DNS hostname or IP address.
def initialize(address, port = nil) # :nodoc:
+ defaults = {
+ keep_alive_timeout: 2,
+ close_on_empty_response: false,
+ open_timeout: 60,
+ read_timeout: 60,
+ write_timeout: 60,
+ continue_timeout: nil,
+ max_retries: 1,
+ debug_output: nil,
+ response_body_encoding: false,
+ ignore_eof: true
+ }
+ options = defaults.merge(self.class.default_configuration || {})
+
@address = address
@port = (port || HTTP.default_port)
@ipaddr = nil
@local_host = nil
@local_port = nil
@curr_http_version = HTTPVersion
- @keep_alive_timeout = 2
+ @keep_alive_timeout = options[:keep_alive_timeout]
@last_communicated = nil
- @close_on_empty_response = false
+ @close_on_empty_response = options[:close_on_empty_response]
@socket = nil
@started = false
- @open_timeout = 60
- @read_timeout = 60
- @write_timeout = 60
- @continue_timeout = nil
- @max_retries = 1
- @debug_output = nil
- @response_body_encoding = false
- @ignore_eof = true
+ @open_timeout = options[:open_timeout]
+ @read_timeout = options[:read_timeout]
+ @write_timeout = options[:write_timeout]
+ @continue_timeout = options[:continue_timeout]
+ @max_retries = options[:max_retries]
+ @debug_output = options[:debug_output]
+ @response_body_encoding = options[:response_body_encoding]
+ @ignore_eof = options[:ignore_eof]
+ @tcpsocket_supports_open_timeout = nil
@proxy_from_env = false
@proxy_uri = nil
@@ -1117,6 +1187,7 @@ module Net #:nodoc:
@proxy_port = nil
@proxy_user = nil
@proxy_pass = nil
+ @proxy_use_ssl = nil
@use_ssl = false
@ssl_context = nil
@@ -1233,7 +1304,7 @@ module Net #:nodoc:
# Sets whether to determine the proxy from environment variable
# '<tt>ENV['http_proxy']</tt>';
- # see {Proxy Using ENV['http_proxy']}[rdoc-ref:Net::HTTP@Proxy+Using+-27ENV-5B-27http_proxy-27-5D-27].
+ # see {Proxy Using ENV['http_proxy']}[rdoc-ref:Net::HTTP@Proxy+Using+ENVHTTPProxy].
attr_writer :proxy_from_env
# Sets the proxy address;
@@ -1252,6 +1323,10 @@ module Net #:nodoc:
# see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
attr_writer :proxy_pass
+ # Sets whether the proxy uses SSL;
+ # see {Proxy Server}[rdoc-ref:Net::HTTP@Proxy+Server].
+ attr_writer :proxy_use_ssl
+
# Returns the IP address for the connection.
#
# If the session has not been started,
@@ -1440,23 +1515,6 @@ module Net #:nodoc:
@use_ssl = flag
end
- SSL_IVNAMES = [
- :@ca_file,
- :@ca_path,
- :@cert,
- :@cert_store,
- :@ciphers,
- :@extra_chain_cert,
- :@key,
- :@ssl_timeout,
- :@ssl_version,
- :@min_version,
- :@max_version,
- :@verify_callback,
- :@verify_depth,
- :@verify_mode,
- :@verify_hostname,
- ] # :nodoc:
SSL_ATTRIBUTES = [
:ca_file,
:ca_path,
@@ -1473,7 +1531,9 @@ module Net #:nodoc:
:verify_depth,
:verify_mode,
:verify_hostname,
- ] # :nodoc:
+ ].freeze # :nodoc:
+
+ SSL_IVNAMES = SSL_ATTRIBUTES.map { |a| "@#{a}".to_sym }.freeze # :nodoc:
# Sets or returns the path to a CA certification file in PEM format.
attr_accessor :ca_file
@@ -1490,11 +1550,11 @@ module Net #:nodoc:
attr_accessor :cert_store
# Sets or returns the available SSL ciphers.
- # See {OpenSSL::SSL::SSLContext#ciphers=}[rdoc-ref:OpenSSL::SSL::SSLContext#ciphers-3D].
+ # See {OpenSSL::SSL::SSLContext#ciphers=}[OpenSSL::SSL::SSL::Context#ciphers=].
attr_accessor :ciphers
# Sets or returns the extra X509 certificates to be added to the certificate chain.
- # See {OpenSSL::SSL::SSLContext#add_certificate}[rdoc-ref:OpenSSL::SSL::SSLContext#add_certificate].
+ # See {OpenSSL::SSL::SSLContext#add_certificate}[OpenSSL::SSL::SSL::Context#add_certificate].
attr_accessor :extra_chain_cert
# Sets or returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
@@ -1504,15 +1564,15 @@ module Net #:nodoc:
attr_accessor :ssl_timeout
# Sets or returns the SSL version.
- # See {OpenSSL::SSL::SSLContext#ssl_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#ssl_version-3D].
+ # See {OpenSSL::SSL::SSLContext#ssl_version=}[OpenSSL::SSL::SSL::Context#ssl_version=].
attr_accessor :ssl_version
# Sets or returns the minimum SSL version.
- # See {OpenSSL::SSL::SSLContext#min_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#min_version-3D].
+ # See {OpenSSL::SSL::SSLContext#min_version=}[OpenSSL::SSL::SSL::Context#min_version=].
attr_accessor :min_version
# Sets or returns the maximum SSL version.
- # See {OpenSSL::SSL::SSLContext#max_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#max_version-3D].
+ # See {OpenSSL::SSL::SSLContext#max_version=}[OpenSSL::SSL::SSL::Context#max_version=].
attr_accessor :max_version
# Sets or returns the callback for the server certification verification.
@@ -1528,7 +1588,7 @@ module Net #:nodoc:
# Sets or returns whether to verify that the server certificate is valid
# for the hostname.
- # See {OpenSSL::SSL::SSLContext#verify_hostname=}[rdoc-ref:OpenSSL::SSL::SSLContext#attribute-i-verify_mode].
+ # See {OpenSSL::SSL::SSLContext#verify_hostname=}[OpenSSL::SSL::SSL::Context#verify_hostname=].
attr_accessor :verify_hostname
# Returns the X509 certificate chain (an array of strings)
@@ -1576,6 +1636,21 @@ module Net #:nodoc:
self
end
+ # Finishes the \HTTP session:
+ #
+ # http = Net::HTTP.new(hostname)
+ # http.start
+ # http.started? # => true
+ # http.finish # => nil
+ # http.started? # => false
+ #
+ # Raises IOError if not in a session.
+ def finish
+ raise IOError, 'HTTP session not yet started' unless started?
+ do_finish
+ end
+
+ # :stopdoc:
def do_start
connect
@started = true
@@ -1598,19 +1673,26 @@ module Net #:nodoc:
end
debug "opening connection to #{conn_addr}:#{conn_port}..."
- s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
- begin
- TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
- rescue => e
- raise e, "Failed to open TCP connection to " +
- "#{conn_addr}:#{conn_port} (#{e.message})"
+ begin
+ s = timeouted_connect(conn_addr, conn_port)
+ rescue => e
+ if (defined?(IO::TimeoutError) && e.is_a?(IO::TimeoutError)) || e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions
+ e = Net::OpenTimeout.new(e)
end
- }
+ raise e, "Failed to open TCP connection to " +
+ "#{conn_addr}:#{conn_port} (#{e.message})"
+ end
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
debug "opened"
if use_ssl?
if proxy?
- plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
+ if @proxy_use_ssl
+ proxy_sock = OpenSSL::SSL::SSLSocket.new(s)
+ ssl_socket_connect(proxy_sock, @open_timeout)
+ else
+ proxy_sock = s
+ end
+ proxy_sock = BufferedIO.new(proxy_sock, read_timeout: @read_timeout,
write_timeout: @write_timeout,
continue_timeout: @continue_timeout,
debug_output: @debug_output)
@@ -1621,8 +1703,8 @@ module Net #:nodoc:
buf << "Proxy-Authorization: Basic #{credential}\r\n"
end
buf << "\r\n"
- plain_sock.write(buf)
- HTTPResponse.read_new(plain_sock).value
+ proxy_sock.write(buf)
+ HTTPResponse.read_new(proxy_sock).value
# assuming nothing left in buffers after successful CONNECT response
end
@@ -1692,23 +1774,30 @@ module Net #:nodoc:
end
private :connect
- def on_connect
+ tcp_socket_parameters = TCPSocket.instance_method(:initialize).parameters
+ TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT = if tcp_socket_parameters != [[:rest]]
+ tcp_socket_parameters.include?([:key, :open_timeout])
+ else
+ # Use Socket.tcp to find out since there is no parameters information for TCPSocket#initialize
+ # See discussion in https://github.com/ruby/net-http/pull/224
+ Socket.method(:tcp).parameters.include?([:key, :open_timeout])
end
- private :on_connect
+ private_constant :TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
- # Finishes the \HTTP session:
- #
- # http = Net::HTTP.new(hostname)
- # http.start
- # http.started? # => true
- # http.finish # => nil
- # http.started? # => false
- #
- # Raises IOError if not in a session.
- def finish
- raise IOError, 'HTTP session not yet started' unless started?
- do_finish
+ def timeouted_connect(conn_addr, conn_port)
+ if TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout)
+ else
+ Timeout.timeout(@open_timeout, Net::OpenTimeout) {
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
+ }
+ end
+ end
+ private :timeouted_connect
+
+ def on_connect
end
+ private :on_connect
def do_finish
@started = false
@@ -1730,13 +1819,14 @@ module Net #:nodoc:
@proxy_port = nil
@proxy_user = nil
@proxy_pass = nil
+ @proxy_use_ssl = nil
# Creates an \HTTP proxy class which behaves like \Net::HTTP, but
# performs all access via the specified proxy.
#
# This class is obsolete. You may pass these same parameters directly to
# \Net::HTTP.new. See Net::HTTP.new for details of the arguments.
- def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil) #:nodoc:
+ def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_use_ssl = nil) #:nodoc:
return self unless p_addr
Class.new(self) {
@@ -1754,9 +1844,12 @@ module Net #:nodoc:
@proxy_user = p_user
@proxy_pass = p_pass
+ @proxy_use_ssl = p_use_ssl
}
end
+ # :startdoc:
+
class << HTTP
# Returns true if self is a class which was created by HTTP::Proxy.
def proxy_class?
@@ -1778,6 +1871,9 @@ module Net #:nodoc:
# Returns the password for accessing the proxy, or +nil+ if none;
# see Net::HTTP@Proxy+Server.
attr_reader :proxy_pass
+
+ # Use SSL when talking to the proxy. If Net::HTTP does not use a proxy, nil.
+ attr_reader :proxy_use_ssl
end
# Returns +true+ if a proxy server is defined, +false+ otherwise;
@@ -1848,9 +1944,11 @@ module Net #:nodoc:
alias proxyport proxy_port #:nodoc: obsolete
private
+ # :stopdoc:
def unescape(value)
- require 'cgi/util'
+ require 'cgi/escape'
+ require 'cgi/util' unless defined?(CGI::EscapeExt)
CGI.unescape(value)
end
@@ -1875,6 +1973,7 @@ module Net #:nodoc:
path
end
end
+ # :startdoc:
#
# HTTP operations
@@ -2012,6 +2111,11 @@ module Net #:nodoc:
# http = Net::HTTP.new(hostname)
# http.put('/todos/1', data) # => #<Net::HTTPOK 200 OK readbody=true>
#
+ # Related:
+ #
+ # - Net::HTTP::Put: request class for \HTTP method PUT.
+ # - Net::HTTP.put: sends PUT request, returns response body.
+ #
def put(path, data, initheader = nil)
request(Put.new(path, initheader), data)
end
@@ -2324,7 +2428,9 @@ module Net #:nodoc:
res
end
- IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE/ # :nodoc:
+ # :stopdoc:
+
+ IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE/.freeze # :nodoc:
def transport_request(req)
count = 0
@@ -2350,7 +2456,10 @@ module Net #:nodoc:
res
}
res.reading_body(@socket, req.response_body_permitted?) {
- yield res if block_given?
+ if block_given?
+ count = max_retries # Don't restart in the middle of a download
+ yield res
+ end
}
rescue Net::OpenTimeout
raise
@@ -2478,6 +2587,11 @@ module Net #:nodoc:
alias_method :D, :debug
end
+ # for backward compatibility until Ruby 4.0
+ # https://bugs.ruby-lang.org/issues/20900
+ # https://github.com/bblimke/webmock/pull/1081
+ HTTPSession = HTTP
+ deprecate_constant :HTTPSession
end
require_relative 'http/exceptions'
@@ -2492,5 +2606,3 @@ require_relative 'http/response'
require_relative 'http/responses'
require_relative 'http/proxy_delta'
-
-require_relative 'http/backward'
diff --git a/lib/net/http/backward.rb b/lib/net/http/backward.rb
deleted file mode 100644
index b44577edbd..0000000000
--- a/lib/net/http/backward.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-# for backward compatibility
-
-# :enddoc:
-
-class Net::HTTP
- ProxyMod = ProxyDelta
- deprecate_constant :ProxyMod
-end
-
-module Net::NetPrivate
- HTTPRequest = ::Net::HTTPRequest
- deprecate_constant :HTTPRequest
-end
-
-module 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/net/http/exceptions.rb b/lib/net/http/exceptions.rb
index ceec8f7b0a..4342cfc0ef 100644
--- a/lib/net/http/exceptions.rb
+++ b/lib/net/http/exceptions.rb
@@ -3,7 +3,7 @@ module Net
# Net::HTTP exception class.
# You cannot use Net::HTTPExceptions directly; instead, you must use
# its subclasses.
- module HTTPExceptions
+ module HTTPExceptions # :nodoc:
def initialize(msg, res) #:nodoc:
super msg
@response = res
@@ -12,6 +12,7 @@ module Net
alias data response #:nodoc: obsolete
end
+ # :stopdoc:
class HTTPError < ProtocolError
include HTTPExceptions
end
diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb
index 44e329a0c8..5b01ea4abd 100644
--- a/lib/net/http/generic_request.rb
+++ b/lib/net/http/generic_request.rb
@@ -19,16 +19,13 @@ class Net::HTTPGenericRequest
if URI === uri_or_path then
raise ArgumentError, "not an HTTP URI" unless URI::HTTP === uri_or_path
- hostname = uri_or_path.hostname
+ hostname = uri_or_path.host
raise ArgumentError, "no host component for URI" unless (hostname && hostname.length > 0)
@uri = uri_or_path.dup
- host = @uri.hostname.dup
- host << ":" << @uri.port.to_s if @uri.port != @uri.default_port
@path = uri_or_path.request_uri
raise ArgumentError, "no HTTP request path given" unless @path
else
@uri = nil
- host = nil
raise ArgumentError, "no HTTP request path given" unless uri_or_path
raise ArgumentError, "HTTP request path is empty" if uri_or_path.empty?
@path = uri_or_path.dup
@@ -51,7 +48,7 @@ class Net::HTTPGenericRequest
initialize_http_header initheader
self['Accept'] ||= '*/*'
self['User-Agent'] ||= 'Ruby'
- self['Host'] ||= host if host
+ self['Host'] ||= @uri.authority if @uri
@body = nil
@body_stream = nil
@body_data = nil
@@ -102,6 +99,31 @@ class Net::HTTPGenericRequest
"\#<#{self.class} #{@method}>"
end
+ # Returns a string representation of the request with the details for pp:
+ #
+ # require 'pp'
+ # post = Net::HTTP::Post.new(uri)
+ # post.inspect # => "#<Net::HTTP::Post POST>"
+ # post.pretty_inspect
+ # # => #<Net::HTTP::Post
+ # POST
+ # path="/"
+ # headers={"accept-encoding" => ["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"],
+ # "accept" => ["*/*"],
+ # "user-agent" => ["Ruby"],
+ # "host" => ["www.ruby-lang.org"]}>
+ #
+ def pretty_print(q)
+ q.object_group(self) {
+ q.breakable
+ q.text @method
+ q.breakable
+ q.text "path="; q.pp @path
+ q.breakable
+ q.text "headers="; q.pp to_hash
+ }
+ end
+
##
# Don't automatically decode response content-encoding if the user indicates
# they want to handle it.
@@ -220,7 +242,7 @@ class Net::HTTPGenericRequest
end
if host = self['host']
- host.sub!(/:.*/m, '')
+ host = URI.parse("//#{host}").host # Remove a port component from the existing Host header
elsif host = @uri.host
else
host = addr
@@ -239,6 +261,8 @@ class Net::HTTPGenericRequest
private
+ # :stopdoc:
+
class Chunker #:nodoc:
def initialize(sock)
@sock = sock
@@ -260,7 +284,6 @@ class Net::HTTPGenericRequest
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
@@ -271,7 +294,6 @@ class Net::HTTPGenericRequest
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?
@@ -373,12 +395,6 @@ class Net::HTTPGenericRequest
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.
@@ -411,4 +427,3 @@ class Net::HTTPGenericRequest
end
end
-
diff --git a/lib/net/http/header.rb b/lib/net/http/header.rb
index 6660c8075a..5dcdcc7d74 100644
--- a/lib/net/http/header.rb
+++ b/lib/net/http/header.rb
@@ -179,7 +179,9 @@
# - #each_value: Passes each string field value to the block.
#
module Net::HTTPHeader
+ # The maximum length of HTTP header keys.
MAX_KEY_LENGTH = 1024
+ # The maximum length of HTTP header values.
MAX_FIELD_LENGTH = 65536
def initialize_http_header(initheader) #:nodoc:
@@ -267,6 +269,7 @@ module Net::HTTPHeader
end
end
+ # :stopdoc:
private def set_field(key, val)
case val
when Enumerable
@@ -294,6 +297,7 @@ module Net::HTTPHeader
ary.push val
end
end
+ # :startdoc:
# Returns the array field value for the given +key+,
# or +nil+ if there is no such field;
@@ -490,8 +494,8 @@ module Net::HTTPHeader
alias canonical_each each_capitalized
- def capitalize(name)
- name.to_s.split(/-/).map {|s| s.capitalize }.join('-')
+ def capitalize(name) # :nodoc:
+ name.to_s.split('-'.freeze).map {|s| s.capitalize }.join('-'.freeze)
end
private :capitalize
@@ -957,12 +961,12 @@ module Net::HTTPHeader
@header['proxy-authorization'] = [basic_encode(account, password)]
end
- def basic_encode(account, password)
+ def basic_encode(account, password) # :nodoc:
'Basic ' + ["#{account}:#{password}"].pack('m0')
end
private :basic_encode
-# Returns whether the HTTP session is to be closed.
+ # Returns whether the HTTP session is to be closed.
def connection_close?
token = /(?:\A|,)\s*close\s*(?:\z|,)/i
@header['connection']&.grep(token) {return true}
@@ -970,7 +974,7 @@ module Net::HTTPHeader
false
end
-# Returns whether the HTTP session is to be kept alive.
+ # Returns whether the HTTP session is to be kept alive.
def connection_keep_alive?
token = /(?:\A|,)\s*keep-alive\s*(?:\z|,)/i
@header['connection']&.grep(token) {return true}
diff --git a/lib/net/http/net-http.gemspec b/lib/net/http/net-http.gemspec
index 0021136793..d59d5c3b74 100644
--- a/lib/net/http/net-http.gemspec
+++ b/lib/net/http/net-http.gemspec
@@ -21,19 +21,19 @@ Gem::Specification.new do |spec|
spec.summary = %q{HTTP client api for Ruby.}
spec.description = %q{HTTP client api for Ruby.}
spec.homepage = "https://github.com/ruby/net-http"
- spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
spec.licenses = ["Ruby", "BSD-2-Clause"]
+ spec.metadata["changelog_uri"] = spec.homepage + "/releases"
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{\A(?:(?:test|spec|features)/|\.git)}) }
- end
+ excludes = %W[/.git* /bin /test /test_sig /*file /#{File.basename(__FILE__)}]
+ spec.files = IO.popen(%W[git -C #{__dir__} ls-files -z --] + excludes.map {|e| ":^#{e}"}, &:read).split("\x0")
spec.bindir = "exe"
spec.require_paths = ["lib"]
- spec.add_dependency "uri"
+ spec.add_dependency "uri", ">= 0.11.1"
end
diff --git a/lib/net/http/requests.rb b/lib/net/http/requests.rb
index 5724164205..8dc79a9f66 100644
--- a/lib/net/http/requests.rb
+++ b/lib/net/http/requests.rb
@@ -19,9 +19,9 @@
#
# - Request body: optional.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
#
# Related:
#
@@ -29,6 +29,7 @@
# - Net::HTTP#get: sends +GET+ request, returns response object.
#
class Net::HTTP::Get < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'GET'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -51,15 +52,16 @@ end
#
# - Request body: optional.
# - Response body: no.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
#
# Related:
#
# - Net::HTTP#head: sends +HEAD+ request, returns response object.
#
class Net::HTTP::Head < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'HEAD'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = false
@@ -85,9 +87,9 @@ end
#
# - Request body: yes.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: no.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: yes.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: no.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
#
# Related:
#
@@ -95,6 +97,7 @@ end
# - Net::HTTP#post: sends +POST+ request, returns response object.
#
class Net::HTTP::Post < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'POST'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -120,11 +123,17 @@ end
#
# - Request body: yes.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
+#
+# Related:
+#
+# - Net::HTTP.put: sends +PUT+ request, returns response object.
+# - Net::HTTP#put: sends +PUT+ request, returns response object.
#
class Net::HTTP::Put < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'PUT'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -148,15 +157,16 @@ end
#
# - Request body: optional.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
# - Net::HTTP#delete: sends +DELETE+ request, returns response object.
#
class Net::HTTP::Delete < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'DELETE'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -179,15 +189,16 @@ end
#
# - Request body: optional.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
# - Net::HTTP#options: sends +OPTIONS+ request, returns response object.
#
class Net::HTTP::Options < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'OPTIONS'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -210,15 +221,16 @@ end
#
# - Request body: no.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: yes.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: yes.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
# - Net::HTTP#trace: sends +TRACE+ request, returns response object.
#
class Net::HTTP::Trace < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'TRACE'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -244,15 +256,16 @@ end
#
# - Request body: yes.
# - Response body: yes.
-# - {Safe}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods]: no.
-# - {Idempotent}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods]: no.
-# - {Cacheable}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Cacheable_methods]: no.
+# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
+# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: no.
+# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
#
# Related:
#
# - Net::HTTP#patch: sends +PATCH+ request, returns response object.
#
class Net::HTTP::Patch < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'PATCH'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -280,6 +293,7 @@ end
# - Net::HTTP#propfind: sends +PROPFIND+ request, returns response object.
#
class Net::HTTP::Propfind < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'PROPFIND'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -303,6 +317,7 @@ end
# - Net::HTTP#proppatch: sends +PROPPATCH+ request, returns response object.
#
class Net::HTTP::Proppatch < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'PROPPATCH'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -326,6 +341,7 @@ end
# - Net::HTTP#mkcol: sends +MKCOL+ request, returns response object.
#
class Net::HTTP::Mkcol < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'MKCOL'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -349,6 +365,7 @@ end
# - Net::HTTP#copy: sends +COPY+ request, returns response object.
#
class Net::HTTP::Copy < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'COPY'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -372,6 +389,7 @@ end
# - Net::HTTP#move: sends +MOVE+ request, returns response object.
#
class Net::HTTP::Move < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'MOVE'
REQUEST_HAS_BODY = false
RESPONSE_HAS_BODY = true
@@ -395,6 +413,7 @@ end
# - Net::HTTP#lock: sends +LOCK+ request, returns response object.
#
class Net::HTTP::Lock < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'LOCK'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
@@ -418,8 +437,8 @@ end
# - Net::HTTP#unlock: sends +UNLOCK+ request, returns response object.
#
class Net::HTTP::Unlock < Net::HTTPRequest
+ # :stopdoc:
METHOD = 'UNLOCK'
REQUEST_HAS_BODY = true
RESPONSE_HAS_BODY = true
end
-
diff --git a/lib/net/http/response.rb b/lib/net/http/response.rb
index 40de963868..8804a99c9e 100644
--- a/lib/net/http/response.rb
+++ b/lib/net/http/response.rb
@@ -153,6 +153,7 @@ class Net::HTTPResponse
end
private
+ # :stopdoc:
def read_status_line(sock)
str = sock.readline
@@ -259,7 +260,7 @@ class Net::HTTPResponse
# header.
attr_accessor :ignore_eof
- def inspect
+ def inspect # :nodoc:
"#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
end
diff --git a/lib/net/http/responses.rb b/lib/net/http/responses.rb
index 6f6fb8d055..941a6fed80 100644
--- a/lib/net/http/responses.rb
+++ b/lib/net/http/responses.rb
@@ -4,7 +4,9 @@
module Net
+ # Unknown HTTP response
class HTTPUnknownResponse < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPError #
end
@@ -19,6 +21,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#1xx_informational_response].
#
class HTTPInformation < HTTPResponse
+ # :stopdoc:
HAS_BODY = false
EXCEPTION_TYPE = HTTPError #
end
@@ -34,6 +37,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_success].
#
class HTTPSuccess < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPError #
end
@@ -49,6 +53,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_redirection].
#
class HTTPRedirection < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPRetriableError #
end
@@ -63,6 +68,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors].
#
class HTTPClientError < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPClientException #
end
@@ -77,6 +83,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_server_errors].
#
class HTTPServerError < HTTPResponse
+ # :stopdoc:
HAS_BODY = true
EXCEPTION_TYPE = HTTPFatalError #
end
@@ -94,6 +101,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#100].
#
class HTTPContinue < HTTPInformation
+ # :stopdoc:
HAS_BODY = false
end
@@ -111,6 +119,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#101].
#
class HTTPSwitchProtocol < HTTPInformation
+ # :stopdoc:
HAS_BODY = false
end
@@ -127,6 +136,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#102].
#
class HTTPProcessing < HTTPInformation
+ # :stopdoc:
HAS_BODY = false
end
@@ -145,6 +155,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#103].
#
class HTTPEarlyHints < HTTPInformation
+ # :stopdoc:
HAS_BODY = false
end
@@ -162,6 +173,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#200].
#
class HTTPOK < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -179,6 +191,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#201].
#
class HTTPCreated < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -196,6 +209,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#202].
#
class HTTPAccepted < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -215,6 +229,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#203].
#
class HTTPNonAuthoritativeInformation < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -232,6 +247,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#204].
#
class HTTPNoContent < HTTPSuccess
+ # :stopdoc:
HAS_BODY = false
end
@@ -250,6 +266,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#205].
#
class HTTPResetContent < HTTPSuccess
+ # :stopdoc:
HAS_BODY = false
end
@@ -268,6 +285,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#206].
#
class HTTPPartialContent < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -285,6 +303,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#207].
#
class HTTPMultiStatus < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -304,6 +323,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#208].
#
class HTTPAlreadyReported < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -321,6 +341,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#226].
#
class HTTPIMUsed < HTTPSuccess
+ # :stopdoc:
HAS_BODY = true
end
@@ -338,6 +359,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#300].
#
class HTTPMultipleChoices < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
HTTPMultipleChoice = HTTPMultipleChoices
@@ -356,6 +378,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#301].
#
class HTTPMovedPermanently < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
@@ -373,6 +396,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#302].
#
class HTTPFound < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
HTTPMovedTemporarily = HTTPFound
@@ -390,6 +414,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#303].
#
class HTTPSeeOther < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
@@ -407,6 +432,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#304].
#
class HTTPNotModified < HTTPRedirection
+ # :stopdoc:
HAS_BODY = false
end
@@ -423,6 +449,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#305].
#
class HTTPUseProxy < HTTPRedirection
+ # :stopdoc:
HAS_BODY = false
end
@@ -440,6 +467,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#307].
#
class HTTPTemporaryRedirect < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
@@ -456,6 +484,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#308].
#
class HTTPPermanentRedirect < HTTPRedirection
+ # :stopdoc:
HAS_BODY = true
end
@@ -472,6 +501,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#400].
#
class HTTPBadRequest < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -488,6 +518,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#401].
#
class HTTPUnauthorized < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -504,6 +535,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#402].
#
class HTTPPaymentRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -521,6 +553,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#403].
#
class HTTPForbidden < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -537,6 +570,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#404].
#
class HTTPNotFound < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -553,6 +587,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#405].
#
class HTTPMethodNotAllowed < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -570,6 +605,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#406].
#
class HTTPNotAcceptable < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -586,6 +622,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#407].
#
class HTTPProxyAuthenticationRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -602,6 +639,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#408].
#
class HTTPRequestTimeout < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
HTTPRequestTimeOut = HTTPRequestTimeout
@@ -619,6 +657,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#409].
#
class HTTPConflict < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -636,6 +675,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#410].
#
class HTTPGone < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -653,6 +693,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#411].
#
class HTTPLengthRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -670,6 +711,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#412].
#
class HTTPPreconditionFailed < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -686,6 +728,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#413].
#
class HTTPPayloadTooLarge < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
HTTPRequestEntityTooLarge = HTTPPayloadTooLarge
@@ -703,6 +746,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#414].
#
class HTTPURITooLong < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
HTTPRequestURITooLong = HTTPURITooLong
@@ -721,6 +765,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#415].
#
class HTTPUnsupportedMediaType < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -737,6 +782,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#416].
#
class HTTPRangeNotSatisfiable < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
HTTPRequestedRangeNotSatisfiable = HTTPRangeNotSatisfiable
@@ -754,6 +800,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#417].
#
class HTTPExpectationFailed < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -774,6 +821,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#421].
#
class HTTPMisdirectedRequest < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -790,6 +838,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#422].
#
class HTTPUnprocessableEntity < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -805,6 +854,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#423].
#
class HTTPLocked < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -821,6 +871,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#424].
#
class HTTPFailedDependency < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -840,6 +891,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#426].
#
class HTTPUpgradeRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -856,6 +908,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#428].
#
class HTTPPreconditionRequired < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -872,6 +925,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#429].
#
class HTTPTooManyRequests < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -889,6 +943,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#431].
#
class HTTPRequestHeaderFieldsTooLarge < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
@@ -906,6 +961,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#451].
#
class HTTPUnavailableForLegalReasons < HTTPClientError
+ # :stopdoc:
HAS_BODY = true
end
# 444 No Response - Nginx
@@ -926,6 +982,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#500].
#
class HTTPInternalServerError < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -943,6 +1000,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#501].
#
class HTTPNotImplemented < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -960,6 +1018,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#502].
#
class HTTPBadGateway < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -977,6 +1036,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#503].
#
class HTTPServiceUnavailable < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -994,6 +1054,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#504].
#
class HTTPGatewayTimeout < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
HTTPGatewayTimeOut = HTTPGatewayTimeout
@@ -1011,6 +1072,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#505].
#
class HTTPVersionNotSupported < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -1027,6 +1089,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#506].
#
class HTTPVariantAlsoNegotiates < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -1043,6 +1106,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#507].
#
class HTTPInsufficientStorage < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -1059,6 +1123,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#508].
#
class HTTPLoopDetected < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
# 509 Bandwidth Limit Exceeded - Apache bw/limited extension
@@ -1076,6 +1141,7 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#510].
#
class HTTPNotExtended < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
@@ -1092,19 +1158,21 @@ module Net
# - {Wikipedia}[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#511].
#
class HTTPNetworkAuthenticationRequired < HTTPServerError
+ # :stopdoc:
HAS_BODY = true
end
end
class Net::HTTPResponse
+ # :stopdoc:
CODE_CLASS_TO_OBJ = {
'1' => Net::HTTPInformation,
'2' => Net::HTTPSuccess,
'3' => Net::HTTPRedirection,
'4' => Net::HTTPClientError,
'5' => Net::HTTPServerError
- }
+ }.freeze
CODE_TO_OBJ = {
'100' => Net::HTTPContinue,
'101' => Net::HTTPSwitchProtocol,
@@ -1170,5 +1238,5 @@ class Net::HTTPResponse
'508' => Net::HTTPLoopDetected,
'510' => Net::HTTPNotExtended,
'511' => Net::HTTPNetworkAuthenticationRequired,
- }
+ }.freeze
end
diff --git a/lib/net/net-protocol.gemspec b/lib/net/net-protocol.gemspec
index 29ad2504eb..2d911a966c 100644
--- a/lib/net/net-protocol.gemspec
+++ b/lib/net/net-protocol.gemspec
@@ -21,12 +21,12 @@ Gem::Specification.new do |spec|
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
+ spec.metadata["changelog_uri"] = spec.homepage + "/releases"
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
- `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
- end
+ excludes = %W[/.git* /bin /test /*file /#{File.basename(__FILE__)}]
+ spec.files = IO.popen(%W[git -C #{__dir__} ls-files -z --] + excludes.map {|e| ":^#{e}"}, &:read).split("\x0")
spec.require_paths = ["lib"]
spec.add_dependency "timeout"
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 197ea09089..8c81298c0e 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -54,9 +54,20 @@ module Net # :nodoc:
s.connect
end
end
+
+ tcp_socket_parameters = TCPSocket.instance_method(:initialize).parameters
+ TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT = if tcp_socket_parameters != [[:rest]]
+ tcp_socket_parameters.include?([:key, :open_timeout])
+ else
+ # Use Socket.tcp to find out since there is no parameters information for TCPSocket#initialize
+ # See discussion in https://github.com/ruby/net-http/pull/224
+ Socket.method(:tcp).parameters.include?([:key, :open_timeout])
+ end
+ private_constant :TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
end
+ # :stopdoc:
class ProtocolError < StandardError; end
class ProtoSyntaxError < ProtocolError; end
class ProtoFatalError < ProtocolError; end
@@ -66,6 +77,7 @@ module Net # :nodoc:
class ProtoCommandError < ProtocolError; end
class ProtoRetriableError < ProtocolError; end
ProtocRetryError = ProtoRetriableError
+ # :startdoc:
##
# OpenTimeout, a subclass of Timeout::Error, is raised if a connection cannot
@@ -78,6 +90,7 @@ module Net # :nodoc:
# response cannot be read within the read_timeout.
class ReadTimeout < Timeout::Error
+ # :stopdoc:
def initialize(io = nil)
@io = io
end
@@ -97,6 +110,7 @@ module Net # :nodoc:
# response cannot be written within the write_timeout. Not raised on Windows.
class WriteTimeout < Timeout::Error
+ # :stopdoc:
def initialize(io = nil)
@io = io
end
@@ -484,6 +498,7 @@ module Net # :nodoc:
# The writer adapter class
#
class WriteAdapter
+ # :stopdoc:
def initialize(writer)
@writer = writer
end