diff options
Diffstat (limited to 'lib/net/http.rb')
| -rw-r--r-- | lib/net/http.rb | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb index 797de6aaf5..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 # @@ -72,7 +72,7 @@ module Net #:nodoc: # # - 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| @@ -198,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. @@ -447,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. @@ -460,7 +460,7 @@ module Net #:nodoc: # # First, what's elsewhere. Class Net::HTTP: # - # - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here]. + # - Inherits from {class Object}[rdoc-ref:Object#class-object-whats-here]. # # This is a categorized summary of methods and attributes. # @@ -724,7 +724,7 @@ module Net #:nodoc: class HTTP < Protocol # :stopdoc: - VERSION = "0.6.0" + VERSION = "0.9.1" HTTPVersion = '1.1' begin require 'zlib' @@ -1179,6 +1179,7 @@ module Net #:nodoc: @debug_output = options[:debug_output] @response_body_encoding = options[:response_body_encoding] @ignore_eof = options[:ignore_eof] + @tcpsocket_supports_open_timeout = nil @proxy_from_env = false @proxy_uri = nil @@ -1303,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; @@ -1321,6 +1322,9 @@ module Net #:nodoc: # Sets the proxy password; # 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. @@ -1527,9 +1531,9 @@ module Net #:nodoc: :verify_depth, :verify_mode, :verify_hostname, - ] # :nodoc: + ].freeze # :nodoc: - SSL_IVNAMES = SSL_ATTRIBUTES.map { |a| "@#{a}".to_sym } # :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 @@ -1632,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 @@ -1654,14 +1673,15 @@ 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? @@ -1754,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 @@ -1821,6 +1848,8 @@ module Net #:nodoc: } end + # :startdoc: + class << HTTP # Returns true if self is a class which was created by HTTP::Proxy. def proxy_class? @@ -1915,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 @@ -1942,6 +1973,7 @@ module Net #:nodoc: path end end + # :startdoc: # # HTTP operations @@ -2396,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 @@ -2553,7 +2587,7 @@ module Net #:nodoc: alias_method :D, :debug end - # for backward compatibility until Ruby 3.5 + # for backward compatibility until Ruby 4.0 # https://bugs.ruby-lang.org/issues/20900 # https://github.com/bblimke/webmock/pull/1081 HTTPSession = HTTP |
