aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBurdetteLamar <burdettelamar@yahoo.com>2022-11-15 18:07:46 +0000
committerPeter Zhu <peter@peterzhu.ca>2022-11-19 10:17:53 -0500
commit951eabdcf2f0a8c8b0f23904b65bbaf93cde8d82 (patch)
treef2cd2e8745522d358c5f7fe315ac99f9254644b1 /lib
parent50c6cabadca44b7b034eae5dcc8017154a2858bd (diff)
downloadruby-951eabdcf2f0a8c8b0f23904b65bbaf93cde8d82.tar.gz
[ruby/net-http] Enhanced RDoc for Net::HTTP
https://github.com/ruby/net-http/commit/6b30c5310b
Diffstat (limited to 'lib')
-rw-r--r--lib/net/http.rb675
-rw-r--r--lib/net/http/request.rb83
-rw-r--r--lib/net/http/response.rb158
3 files changed, 596 insertions, 320 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 16137cebf2..535ca10a0e 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -32,110 +32,290 @@ module Net #:nodoc:
class HTTPHeaderSyntaxError < StandardError; end
# :startdoc:
- # == An HTTP client API for Ruby.
+ # \Class \Net::HTTP provides a rich library that implements the client
+ # in a client-server model that uses the \HTTP request-response protocol.
+ # 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].
+ #
+ # Note: If you are performing only a few GET requests, consider using
+ # {OpenURI}[rdoc-ref:OpenURI];
+ # otherwise, read on.
+ #
+ # == Synopsis
+ #
+ # If you are already familiar with \HTTP, this synopsis may be helpful.
+ #
+ # {Session}[rdoc-ref:Net::HTTP@Sessions] with multiple requests for
+ # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
+ #
+ # Net::HTTP.start(hostname) do |http|
+ # # Session started automatically before block execution.
+ # http.get(path_or_uri, headers = {})
+ # http.head(path_or_uri, headers = {})
+ # http.post(path_or_uri, data, headers = {}) # Can also have a block.
+ # http.put(path_or_uri, data, headers = {})
+ # http.delete(path_or_uri, headers = {Depth: 'Infinity'})
+ # http.options(path_or_uri, headers = {})
+ # http.trace(path_or_uri, headers = {})
+ # http.patch(path_or_uri, data, headers = {}) # Can also have a block.
+ # # Session finished automatically at block exit.
+ # end
+ #
+ # {Session}[rdoc-ref:Net::HTTP@Sessions] with multiple requests for
+ # {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
+ #
+ # Net::HTTP.start(hostname) do |http|
+ # # Session started automatically before block execution.
+ # http.copy(path_or_uri, headers = {})
+ # http.lock(path_or_uri, body, headers = {})
+ # http.mkcol(path_or_uri, body = nil, headers = {})
+ # http.move(path_or_uri, headers = {})
+ # http.propfind(path_or_uri, body = nil, headers = {'Depth' => '0'})
+ # http.proppatch(path_or_uri, body, headers = {})
+ # http.unlock(path_or_uri, body, headers = {})
+ # # Session finished automatically at block exit.
+ # end
+ #
+ # Each of the following methods automatically starts and finishes
+ # a {session}[rdoc-ref:Net::HTTP@Sessions] that sends a single request:
#
- # Net::HTTP provides a rich library which can be used to build HTTP
- # user-agents. For more details about HTTP see
- # [RFC2616](http://www.ietf.org/rfc/rfc2616.txt).
+ # # Return string response body.
+ # Net::HTTP.get(hostname, path, port = 80)
+ # Net::HTTP.get(uri, headers = {}, port = 80)
#
- # Net::HTTP is designed to work closely with URI. URI::HTTP#host,
- # URI::HTTP#port and URI::HTTP#request_uri are designed to work with
- # Net::HTTP.
+ # # Write string response body to $stdout.
+ # Net::HTTP.get_print(hostname, path_or_uri, port = 80)
+ # Net::HTTP.get_print(uri, headers = {}, port = 80)
#
- # If you are only performing a few GET requests you should try OpenURI.
+ # # Return response as Net::HTTPResponse object.
+ # Net::HTTP.get_response(hostname, path_or_uri, port = 80)
+ # Net::HTTP.get_response(uri, headers = {}, port = 80)
#
- # == Simple Examples
+ # Net::HTTP.post(uri, data, headers = {})
+ # Net::HTTP.post_form(uri, params)
#
- # All examples assume you have loaded Net::HTTP with:
+ # == About the Examples
+ #
+ # Examples here assume that <tt>net/http</tt> has been required
+ # (which also requires +uri+):
#
# require 'net/http'
#
- # This will also require 'uri' so you don't need to require it separately.
+ # Many code examples here use these example websites:
#
- # The Net::HTTP methods in the following section do not persist
- # connections. They are not recommended if you are performing many HTTP
- # requests.
+ # - https://jsonplaceholder.typicode.com.
+ # - http:example.com.
#
- # === GET
+ # Some examples also assume these variables:
#
- # Net::HTTP.get('example.com', '/index.html') # => String
+ # uri = URI('https://jsonplaceholder.typicode.com')
+ # uri.freeze # Examples may not modify.
+ # hostname = uri.hostname # => "jsonplaceholder.typicode.com"
+ # port = uri.port # => 443
#
- # === GET by URI
+ # So that example requests may be written as:
#
- # uri = URI('http://example.com/index.html?count=10')
- # Net::HTTP.get(uri) # => String
+ # Net::HTTP.get(uri)
+ # Net::HTTP.get(hostname, '/index.html')
+ # Net::HTTP.start(hostname) do |http|
+ # http.get('/todos/1')
+ # http.get('/todos/2')
+ # end
#
- # === GET with Dynamic Parameters
+ # An example that needs a modified URI first duplicates +uri+, then modifies:
#
- # uri = URI('http://example.com/index.html')
- # params = { :limit => 10, :page => 3 }
- # uri.query = URI.encode_www_form(params)
+ # _uri = uri.dup
+ # _uri.path = '/todos/1'
#
- # res = Net::HTTP.get_response(uri)
- # puts res.body if res.is_a?(Net::HTTPSuccess)
+ # == URIs
#
- # === POST
+ # On the internet, a URI
+ # ({Universal Resource Identifier}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier])
+ # is a string that identifies a particular resource.
+ # It consists of some or all of: scheme, hostname, path, query, and fragment;
+ # see {URI syntax}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax].
#
- # uri = URI('http://www.example.com/search.cgi')
- # res = Net::HTTP.post_form(uri, 'q' => 'ruby', 'max' => '50')
- # puts res.body
+ # A Ruby {URI::Generic}[]https://docs.ruby-lang.org/en/master/URI/Generic.html] object
+ # represents an internet URI.
+ # It provides, among others, methods
+ # +scheme+, +hostname+, +path+, +query+, and +fragment+.
#
- # === POST with Multiple Values
+ # === Schemes
#
- # uri = URI('http://www.example.com/search.cgi')
- # res = Net::HTTP.post_form(uri, 'q' => ['ruby', 'perl'], 'max' => '50')
- # puts res.body
+ # An internet \URI has
+ # a {scheme}[https://en.wikipedia.org/wiki/List_of_URI_schemes].
#
- # == How to use Net::HTTP
+ # The two schemes supported in \Net::HTTP are <tt>'https'</tt> and <tt>'http'</tt>:
#
- # The following example code can be used as the basis of an HTTP user-agent
- # which can perform a variety of request types using persistent
- # connections.
+ # uri.scheme # => "https"
+ # URI('http://example.com').scheme # => "http"
#
- # uri = URI('http://example.com/some_path?query=string')
+ # === Hostnames
#
- # Net::HTTP.start(uri.host, uri.port) do |http|
- # request = Net::HTTP::Get.new uri
+ # A hostname identifies a server (host) to which requests may be sent:
#
- # response = http.request request # Net::HTTPResponse object
+ # hostname = uri.hostname # => "jsonplaceholder.typicode.com"
+ # Net::HTTP.start(hostname) do |http|
+ # # Some HTTP stuff.
# end
#
- # Net::HTTP::start immediately creates a connection to an HTTP server which
- # is kept open for the duration of the block. The connection will remain
- # open for multiple requests in the block if the server indicates it
- # supports persistent connections.
+ # === Paths
#
- # If you wish to re-use a connection across multiple HTTP requests without
- # automatically closing it you can use ::new and then call #start and
- # #finish manually.
+ # A host-specific path identifies a resource on the host:
#
- # The request types Net::HTTP supports are listed below in the section "HTTP
- # Request Classes".
+ # _uri = uri.dup
+ # _uri.path = '/todos/1'
+ # hostname = _uri.hostname
+ # path = _uri.path
+ # Net::HTTP.get(hostname, path)
#
- # For all the Net::HTTP request objects and shortcut request methods you may
- # supply either a String for the request path or a URI from which Net::HTTP
- # will extract the request path.
+ # === Queries
#
- # === Response Data
+ # A host-specific query adds name/value pairs to the URI:
#
- # uri = URI('http://example.com/index.html')
- # res = Net::HTTP.get_response(uri)
+ # _uri = uri.dup
+ # params = {userId: 1, completed: false}
+ # _uri.query = URI.encode_www_form(params)
+ # _uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com?userId=1&completed=false>
+ # Net::HTTP.get(_uri)
#
- # # Headers
- # res['Set-Cookie'] # => String
- # res.get_fields('set-cookie') # => Array
- # res.to_hash['set-cookie'] # => Array
- # puts "Headers: #{res.to_hash.inspect}"
+ # === Fragments
#
- # # Status
- # puts res.code # => '200'
- # puts res.message # => 'OK'
- # puts res.class.name # => 'HTTPOK'
+ # A {URI fragment}[https://en.wikipedia.org/wiki/URI_fragment] has no effect
+ # in \Net::HTTP;
+ # the same data is returned, regardless of whether a fragment is included.
#
- # # Body
- # puts res.body
+ # == Request Headers
+ #
+ # Request headers may be used to pass additional information to the host,
+ # similar to arguments passed in a method call;
+ # each header is a name/value pair.
+ #
+ # Each of the \Net::HTTP methods that sends a request to the host
+ # has optional argument +headers+,
+ # where the headers are expressed as a hash of field-name/value pairs:
+ #
+ # headers = {Accept: 'application/json', Connection: 'Keep-Alive'}
+ # Net::HTTP.get(uri, headers)
+ #
+ # See lists of both standard request fields and common request fields at
+ # {Request Fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields].
+ # A host may also accept other custom fields.
+ #
+ # The following example performs a conditional GET using the
+ # <tt>If-Modified-Since</tt> header:
+ #
+ # - If the file +cached_response+ has been modified since the time
+ # put into the header,
+ # the return is a \Net::HTTPSuccess object,
+ # and the file is overwritten with the response body.
+ # - Otherwise, the return is a \Net::HTTPNotModified object,
+ # and the file remains unchanged.
+ #
+ # The code:
+ #
+ # path = 'cached_response'
+ # File.write(path, '') unless File.exist?(path)
+ # file = File.stat(path)
+ # req = Net::HTTP::Get.new(uri)
+ # req['If-Modified-Since'] = file.mtime.rfc2822
+ # res = Net::HTTP.start(hostname) do |http|
+ # http.request(req)
+ # end
+ # if res.is_a?(Net::HTTPSuccess)
+ # File.write(path, res.body)
+ # end
+ #
+ # == Sessions
+ #
+ # A _session_ is a connection between a server (host) and a client that:
+ #
+ # - Is begun by instance method Net::HTTP#start.
+ # - May contain any number of requests.
+ # - Is ended by instance method Net::HTTP#finish.
+ #
+ # See example sessions at the {Synopsis}[rdoc-ref:Net::HTTP@Synopsis].
+ #
+ # === Session Using \Net::HTTP.start
+ #
+ # If you have many requests to make to a single host (and port),
+ # consider using singleton method Net::HTTP.start with a block;
+ # the method handles the session automatically by:
+ #
+ # - Calling #start before block execution.
+ # - Executing the block.
+ # - Calling #finish after block execution.
+ #
+ # 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]:
+ #
+ # - #get, #request_get: GET.
+ # - #head, #request_head: HEAD.
+ # - #post, #request_post: POST.
+ # - #delete: DELETE.
+ # - #options: OPTIONS.
+ # - #trace: TRACE.
+ # - #patch: PATCH.
+ #
+ # - {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
+ #
+ # - #copy: COPY.
+ # - #lock: LOCK.
+ # - #mkcol: MKCOL.
+ # - #move: MOVE.
+ # - #propfind: PROPFIND.
+ # - #proppatch: PROPPATCH.
+ # - #unlock: UNLOCK.
+ #
+ # === Session Using \Net::HTTP.start and \Net::HTTP.finish
+ #
+ # You can manage a session manually using methods #start and #finish:
+ #
+ # http = Net::HTTP.new(hostname)
+ # http.start
+ # http.get('/todos/1')
+ # http.get('/todos/2')
+ # http.delete('/posts/1')
+ # http.finish # Needed to free resources.
+ #
+ # === Single-Request Session
+ #
+ # Certain convenience methods automatically handle a session by:
+ #
+ # - Creating an \HTTP object
+ # - Starting a session.
+ # - Sending a single request.
+ # - Finishing the session.
+ # - Destroying the object.
+ #
+ # Such methods that send GET requests:
+ #
+ # - ::get: Returns the string response body.
+ # - ::get_print: Writes the string response body to $stdout.
+ # - ::get_response: Returns a Net::HTTPResponse object.
+ #
+ # Such methods that send POST requests:
+ #
+ # - ::post: Posts data to the host.
+ # - ::post_form: Posts form data to the host.
+ #
+ # == \HTTP Requests and Responses
+ #
+ # Many of the methods above are convenience methods,
+ # each of which sends a request and returns a string
+ # without directly using \Net::HTTPRequest and \Net::HTTPResponse objects.
+ #
+ # You can, however, directly create a request object, send the request,
+ # and retrieve the response object; see:
+ #
+ # - Net::HTTPRequest.
+ # - Net::HTTPResponse.
#
- # === Following Redirection
+ # == Following Redirection
#
# Each Net::HTTPResponse object belongs to a class for its response code.
#
@@ -167,56 +347,7 @@ module Net #:nodoc:
#
# print fetch('http://www.ruby-lang.org')
#
- # === POST
- #
- # A POST can be made using the Net::HTTP::Post request class. This example
- # creates a URL encoded POST body:
- #
- # uri = URI('http://www.example.com/todo.cgi')
- # req = Net::HTTP::Post.new(uri)
- # req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')
- #
- # res = Net::HTTP.start(uri.hostname, uri.port) do |http|
- # http.request(req)
- # end
- #
- # case res
- # when Net::HTTPSuccess, Net::HTTPRedirection
- # # OK
- # else
- # res.value
- # end
- #
- # To send multipart/form-data use Net::HTTPHeader#set_form:
- #
- # req = Net::HTTP::Post.new(uri)
- # req.set_form([['upload', File.open('foo.bar')]], 'multipart/form-data')
- #
- # Other requests that can contain a body such as PUT can be created in the
- # same way using the corresponding request class (Net::HTTP::Put).
- #
- # === Setting Headers
- #
- # The following example performs a conditional GET using the
- # If-Modified-Since header. If the files has not been modified since the
- # time in the header a Not Modified response will be returned. See RFC 2616
- # section 9.3 for further details.
- #
- # uri = URI('http://example.com/cached_response')
- # file = File.stat 'cached_response'
- #
- # req = Net::HTTP::Get.new(uri)
- # req['If-Modified-Since'] = file.mtime.rfc2822
- #
- # res = Net::HTTP.start(uri.hostname, uri.port) {|http|
- # http.request(req)
- # }
- #
- # open 'cached_response', 'w' do |io|
- # io.write res.body
- # end if res.is_a?(Net::HTTPSuccess)
- #
- # === Basic Authentication
+ # == Basic Authentication
#
# Basic authentication is performed according to
# [RFC2617](http://www.ietf.org/rfc/rfc2617.txt).
@@ -231,7 +362,7 @@ module Net #:nodoc:
# }
# puts res.body
#
- # === Streaming Response Bodies
+ # == Streaming Response Bodies
#
# By default Net::HTTP reads an entire response into memory. If you are
# handling large files or wish to implement a progress bar you can instead
@@ -251,7 +382,7 @@ module Net #:nodoc:
# end
# end
#
- # === HTTPS
+ # == HTTPS
#
# HTTPS is enabled for an HTTP connection by Net::HTTP#use_ssl=.
#
@@ -272,7 +403,7 @@ module Net #:nodoc:
# In previous versions of Ruby you would need to require 'net/https' to use
# HTTPS. This is no longer true.
#
- # === Proxies
+ # == Proxies
#
# Net::HTTP will automatically create a proxy from the +http_proxy+
# environment variable if it is present. To disable use of +http_proxy+,
@@ -290,7 +421,7 @@ module Net #:nodoc:
# See Net::HTTP.new for further details and examples such as proxies that
# require a username and password.
#
- # === Compression
+ # == Compression
#
# Net::HTTP automatically adds Accept-Encoding for compression of response
# bodies and automatically decompresses gzip and deflate responses unless a
@@ -298,114 +429,6 @@ module Net #:nodoc:
#
# Compression can be disabled through the Accept-Encoding: identity header.
#
- # == \HTTP Request Classes
- #
- # Here is the hierarchy of \HTTP request classes
- #
- # - Net::HTTPRequest
- #
- # - Net::HTTP::Get
- # - Net::HTTP::Head
- # - Net::HTTP::Post
- # - Net::HTTP::Patch
- # - Net::HTTP::Put
- # - Net::HTTP::Proppatch
- # - Net::HTTP::Lock
- # - Net::HTTP::Unlock
- # - Net::HTTP::Options
- # - Net::HTTP::Propfind
- # - Net::HTTP::Delete
- # - Net::HTTP::Move
- # - Net::HTTP::Copy
- # - Net::HTTP::Mkcol
- # - Net::HTTP::Trace
- #
- # == \HTTP Response Classes
- #
- # Here is the \HTTP response class hierarchy (with status codes):
- #
- # - Net::HTTPResponse:
- #
- # - Net::HTTPUnknownResponse (for unhandled \HTTP extensions).
- #
- # - Net::HTTPInformation:
- #
- # - Net::HTTPContinue (100)
- # - Net::HTTPSwitchProtocol (101)
- # - Net::HTTPProcessing (102)
- # - Net::HTTPEarlyHints (103)
- #
- # - Net::HTTPSuccess:
- #
- # - Net::HTTPOK (200)
- # - Net::HTTPCreated (201)
- # - Net::HTTPAccepted (202)
- # - Net::HTTPNonAuthoritativeInformation (203)
- # - Net::HTTPNoContent (204)
- # - Net::HTTPResetContent (205)
- # - Net::HTTPPartialContent (206)
- # - Net::HTTPMultiStatus (207)
- # - Net::HTTPAlreadyReported (208)
- # - Net::HTTPIMUsed (226)
- #
- # - Net::HTTPRedirection:
- #
- # - Net::HTTPMultipleChoices (300)
- # - Net::HTTPMovedPermanently (301)
- # - Net::HTTPFound (302)
- # - Net::HTTPSeeOther (303)
- # - Net::HTTPNotModified (304)
- # - Net::HTTPUseProxy (305)
- # - Net::HTTPTemporaryRedirect (307)
- # - Net::HTTPPermanentRedirect (308)
- #
- # - Net::HTTPClientError:
- #
- # - Net::HTTPBadRequest (400)
- # - Net::HTTPUnauthorized (401)
- # - Net::HTTPPaymentRequired (402)
- # - Net::HTTPForbidden (403)
- # - Net::HTTPNotFound (404)
- # - Net::HTTPMethodNotAllowed (405)
- # - Net::HTTPNotAcceptable (406)
- # - Net::HTTPProxyAuthenticationRequired (407)
- # - Net::HTTPRequestTimeOut (408)
- # - Net::HTTPConflict (409)
- # - Net::HTTPGone (410)
- # - Net::HTTPLengthRequired (411)
- # - Net::HTTPPreconditionFailed (412)
- # - Net::HTTPRequestEntityTooLarge (413)
- # - Net::HTTPRequestURITooLong (414)
- # - Net::HTTPUnsupportedMediaType (415)
- # - Net::HTTPRequestedRangeNotSatisfiable (416)
- # - Net::HTTPExpectationFailed (417)
- # - Net::HTTPMisdirectedRequest (421)
- # - Net::HTTPUnprocessableEntity (422)
- # - Net::HTTPLocked (423)
- # - Net::HTTPFailedDependency (424)
- # - Net::HTTPUpgradeRequired (426)
- # - Net::HTTPPreconditionRequired (428)
- # - Net::HTTPTooManyRequests (429)
- # - Net::HTTPRequestHeaderFieldsTooLarge (431)
- # - Net::HTTPUnavailableForLegalReasons (451)
- #
- # - Net::HTTPServerError:
- #
- # - Net::HTTPInternalServerError (500)
- # - Net::HTTPNotImplemented (501)
- # - Net::HTTPBadGateway (502)
- # - Net::HTTPServiceUnavailable (503)
- # - Net::HTTPGatewayTimeOut (504)
- # - Net::HTTPVersionNotSupported (505)
- # - Net::HTTPVariantAlsoNegotiates (506)
- # - Net::HTTPInsufficientStorage (507)
- # - Net::HTTPLoopDetected (508)
- # - Net::HTTPNotExtended (510)
- # - Net::HTTPNetworkAuthenticationRequired (511)
- #
- # There is also the Net::HTTPBadResponse exception which is raised when
- # there is a protocol error.
- #
class HTTP < Protocol
# :stopdoc:
@@ -420,18 +443,17 @@ module Net #:nodoc:
end
# :startdoc:
- # Turns on net/http 1.2 (Ruby 1.8) features.
- # Defaults to ON in Ruby 1.8 or later.
+ # Returns +true+; retained for compatibility.
def HTTP.version_1_2
true
end
- # Returns true if net/http is in version 1.2 mode.
- # Defaults to true.
+ # Returns +true+; retained for compatibility.
def HTTP.version_1_2?
true
end
+ # Returns +false+; retained for compatibility.
def HTTP.version_1_1? #:nodoc:
false
end
@@ -441,25 +463,12 @@ module Net #:nodoc:
alias is_version_1_2? version_1_2? #:nodoc:
end
+ # :call-seq:
+ # Net::HTTP.get_print(hostname, path, port = 80) -> nil
+ # Net::HTTP:get_print(uri, headers = {}, port = 80) -> nil
#
- # short cut methods
- #
-
- #
- # Gets the body text from the target and outputs it to $stdout. The
- # target can either be specified as
- # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
- #
- # Net::HTTP.get_print URI('http://www.example.com/index.html')
- #
- # or:
- #
- # Net::HTTP.get_print 'www.example.com', '/index.html'
- #
- # you can also specify request headers:
- #
- # Net::HTTP.get_print URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' }
- #
+ # Like Net::HTTP.get, but writes the returned body to $stdout;
+ # returns +nil+.
def HTTP.get_print(uri_or_host, path_or_headers = nil, port = nil)
get_response(uri_or_host, path_or_headers, port) {|res|
res.read_body do |chunk|
@@ -469,40 +478,54 @@ module Net #:nodoc:
nil
end
- # Sends a GET request to the target and returns the HTTP response
- # as a string. The target can either be specified as
- # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
- #
- # print Net::HTTP.get(URI('http://www.example.com/index.html'))
+ # :call-seq:
+ # Net::HTTP.get(hostname, path, port = 80) -> body
+ # Net::HTTP:get(uri, headers = {}, port = 80) -> body
#
- # or:
+ # Sends a GET request and returns the \HTTP response body as a string.
#
- # print Net::HTTP.get('www.example.com', '/index.html')
+ # With string arguments +hostname+ and +path+:
#
- # you can also specify request headers:
+ # hostname = 'jsonplaceholder.typicode.com'
+ # path = '/todos/1'
+ # puts Net::HTTP.get(hostname, path)
#
- # Net::HTTP.get(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
+ # Output:
#
- def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
- get_response(uri_or_host, path_or_headers, port).body
- end
-
- # Sends a GET request to the target and returns the HTTP response
- # as a Net::HTTPResponse object. The target can either be specified as
- # (+uri+, +headers+), or as (+host+, +path+, +port+ = 80); so:
+ # {
+ # "userId": 1,
+ # "id": 1,
+ # "title": "delectus aut autem",
+ # "completed":
+ # }
#
- # res = Net::HTTP.get_response(URI('http://www.example.com/index.html'))
- # print res.body
+ # With URI object +uri+ and optional hash argument +headers+:
#
- # or:
+ # uri = URI('https://jsonplaceholder.typicode.com/todos/1')
+ # headers = {Accept: 'text/html'}
+ # puts Net::HTTP.get(uri, headers)
#
- # res = Net::HTTP.get_response('www.example.com', '/index.html')
- # print res.body
+ # Output:
#
- # you can also specify request headers:
+ # {
+ # "userId": 1,
+ # "id": 1,
+ # "title": "delectus aut autem",
+ # "completed": false
+ # }
#
- # Net::HTTP.get_response(URI('http://www.example.com/index.html'), { 'Accept' => 'text/html' })
+ # In either case, the third argument is an integer port number,
+ # which defaults to 80.
+ def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
+ get_response(uri_or_host, path_or_headers, port).body
+ end
+
+ # :call-seq:
+ # Net::HTTP.get_response(hostname, path, port = 80) -> http_response
+ # Net::HTTP:get_response(uri, headers = {}, port = 80) -> http_response
#
+ # Like Net::HTTP.get, but returns an Net::HTTPResponse object
+ # instead of the body string.
def HTTP.get_response(uri_or_host, path_or_headers = nil, port = nil, &block)
if path_or_headers && !path_or_headers.is_a?(Hash)
host = uri_or_host
@@ -588,36 +611,78 @@ module Net #:nodoc:
BufferedIO
end
- # :call-seq:
- # HTTP.start(address, port, p_addr, p_port, p_user, p_pass, &block)
- # HTTP.start(address, port=nil, p_addr=:ENV, p_port=nil, p_user=nil, p_pass=nil, opt, &block)
- #
- # Creates a new Net::HTTP object, then additionally opens the TCP
- # connection and HTTP session.
- #
- # Arguments are the following:
- # _address_ :: hostname or IP address of the server
- # _port_ :: port of the server
- # _p_addr_ :: address of proxy
- # _p_port_ :: port of proxy
- # _p_user_ :: user of proxy
- # _p_pass_ :: pass of proxy
- # _opt_ :: optional hash
- #
- # _opt_ sets following values by its accessor.
- # The keys are ipaddr, ca_file, ca_path, cert, cert_store, ciphers, keep_alive_timeout,
- # close_on_empty_response, key, open_timeout, read_timeout, write_timeout, ssl_timeout,
- # ssl_version, use_ssl, verify_callback, verify_depth and verify_mode.
- # If you set :use_ssl as true, you can use https and default value of
- # verify_mode is set as OpenSSL::SSL::VERIFY_PEER.
- #
- # If the optional block is given, the newly
- # created Net::HTTP object is passed to it and closed when the
- # block finishes. In this case, the return value of this method
- # is the return value of the block. If no block is given, the
- # return value of this method is the newly created Net::HTTP object
- # itself, and the caller is responsible for closing it upon completion
- # using the finish() method.
+ # Creates a new \Net::HTTP object,
+ # opens a TCP connection and \HTTP session.
+ #
+ # Argument +address+ is the hostname or IP address of the server.
+ #
+ # With a block given:
+ #
+ # - Passes the object to the given block,
+ # which may make any number of requests to the host.
+ # - Closes the \HTTP session on block exit.
+ # - Returns the block's value.
+ #
+ # Example:
+ #
+ # hostname = 'jsonplaceholder.typicode.com'
+ # Net::HTTP.start(hostname) do |http|
+ # puts http.get('/todos/1').body
+ # puts http.get('/todos/2').body
+ # end
+ #
+ # Output:
+ #
+ # {
+ # "userId": 1,
+ # "id": 1,
+ # "title": "delectus aut autem",
+ # "completed": false
+ # }
+ # {
+ # "userId": 1,
+ # "id": 2,
+ # "title": "quis ut nam facilis et officia qui",
+ # "completed": false
+ # }
+ #
+ # With no block given, returns the \Net::HTTP object;
+ # the caller should call #finish to close the session.
+ #
+ # Other arguments:
+ #
+ # - +port+: Server port number.
+ # - +p_addr+: Proxy address.
+ # - +p_port+: Proxy port.
+ # - +p_user+: Proxy user name.
+ # - +p_pass+: Proxy password.
+ # - +opts+: Optional options hash.
+ #
+ # The options hash +opts+ sets certain values,
+ # where each key is a method or accessor to be called,
+ # and its value is the value to be set.
+ #
+ # The keys may include:
+ #
+ # - #ca_file
+ # - #ca_path
+ # - #cert
+ # - #cert_store
+ # - #ciphers
+ # - #close_on_empty_response
+ # - +ipaddr+ (calls #ipaddr=)
+ # - #keep_alive_timeout
+ # - #key
+ # - #open_timeout
+ # - #read_timeout
+ # - #ssl_timeout
+ # - #ssl_version
+ # - +use_ssl+ (calls #use_ssl=)
+ # - #verify_callback
+ # - #verify_depth
+ # - #verify_mode
+ # - #write_timeout
+ #
def HTTP.start(address, *arg, &block) # :yield: +http+
arg.pop if opt = Hash.try_convert(arg[-1])
port, p_addr, p_port, p_user, p_pass = *arg
diff --git a/lib/net/http/request.rb b/lib/net/http/request.rb
index 1e86f3e4b4..55099019d6 100644
--- a/lib/net/http/request.rb
+++ b/lib/net/http/request.rb
@@ -1,8 +1,83 @@
# frozen_string_literal: false
-# HTTP request class.
-# This class wraps together the request header and the request path.
-# You cannot use this class directly. Instead, you should use one of its
-# subclasses: Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Head.
+
+# This class is the base class for \Net::HTTP request classes;
+# it wraps together the request path and the request headers.
+#
+# The class should not be used directly;
+# instead you should use its subclasses, which are covered in the sections below.
+#
+# == About the Examples
+#
+# Examples here assume that <tt>net/http</tt> has been required
+# (which also requires +uri+):
+#
+# require 'net/http'
+#
+# Many code examples here use these example websites:
+#
+# - https://jsonplaceholder.typicode.com.
+# - http:example.com.
+#
+# Some examples also assume these variables:
+#
+# uri = URI('https://jsonplaceholder.typicode.com')
+# uri.freeze # Examples may not modify.
+# hostname = uri.hostname # => "jsonplaceholder.typicode.com"
+# port = uri.port # => 443
+#
+# An example that needs a modified URI first duplicates +uri+, then modifies:
+#
+# _uri = uri.dup
+# _uri.path = '/todos/1'
+#
+# == Requests
+#
+# === \Net::HTTP::Get
+#
+# A GET request may be sent using request class \Net::HTTP::Get:
+#
+# req = Net::HTTP::Get.new(uri) # => #<Net::HTTP::Get GET>
+# Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end # => #<Net::HTTPOK 200 OK readbody=true>
+#
+# === \Net::HTTP::Head
+#
+# A HEAD request may be sent using request class \Net::HTTP::Head:
+#
+# req = Net::HTTP::Head.new(uri) # => #<Net::HTTP::Head HEAD>
+# Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end # => #<Net::HTTPOK 200 OK readbody=true>
+#
+# === \Net::HTTP::Post
+#
+# A POST request may be sent using request class \Net::HTTP::Post:
+#
+# require 'json'
+# json = JSON.generate({title: 'foo', body: 'bar', userId: 1})
+# # => "{\"title\":\"foo\",\"body\":\"bar\",\"userId\":1}"
+# _uri = uri.dup
+# _uri.path = '/posts'
+# req = Net::HTTP::Post.new(_uri) # => #<Net::HTTP::Post POST>
+# req.body = json
+# req['Content-type'] = 'application/json; charset=UTF-8'
+# Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end # => # => #<Net::HTTPCreated 201 Created readbody=true>
+#
+# === \Net::HTTP::Patch
+# === \Net::HTTP::Put
+# === \Net::HTTP::Proppatch
+# === \Net::HTTP::Lock
+# === \Net::HTTP::Unlock
+# === \Net::HTTP::Options
+# === \Net::HTTP::Propfind
+# === \Net::HTTP::Delete
+# === \Net::HTTP::Move
+# === \Net::HTTP::Copy
+# === \Net::HTTP::Mkcol
+# === \Net::HTTP::Trace
#
class Net::HTTPRequest < Net::HTTPGenericRequest
# Creates an HTTP request object for +path+.
diff --git a/lib/net/http/response.rb b/lib/net/http/response.rb
index f8b522f1ff..043672d3e2 100644
--- a/lib/net/http/response.rb
+++ b/lib/net/http/response.rb
@@ -1,20 +1,156 @@
# frozen_string_literal: false
-# HTTP response class.
+
+# This class is the base class for \Net::HTTP request classes.
+#
+# == About the Examples
+#
+# Examples here assume that <tt>net/http</tt> has been required
+# (which also requires +uri+):
+#
+# require 'net/http'
+#
+# Many code examples here use these example websites:
+#
+# - https://jsonplaceholder.typicode.com.
+# - http:example.com.
+#
+# Some examples also assume these variables:
+#
+# uri = URI('https://jsonplaceholder.typicode.com')
+# uri.freeze # Examples may not modify.
+# hostname = uri.hostname # => "jsonplaceholder.typicode.com"
+# port = uri.port # => 443
+#
+# An example that needs a modified URI first duplicates +uri+, then modifies:
+#
+# _uri = uri.dup
+# _uri.path = '/todos/1'
+#
+# == Returned Responses
+#
+# \Method Net::HTTP.get_response returns
+# an instance of one of the subclasses of \Net::HTTPResponse:
+#
+# Net::HTTP.get_response(uri)
+# # => #<Net::HTTPOK 200 OK readbody=true>
+# Net::HTTP.get_response(hostname, '/nosuch')
+# # => #<Net::HTTPNotFound 404 Not Found readbody=true>
+#
+# As does method Net::HTTP#request:
+#
+# req = Net::HTTP::Get.new(uri)
+# Net::HTTP.start(hostname) do |http|
+# http.request(req)
+# end # => #<Net::HTTPOK 200 OK readbody=true>
+#
+# \Class \Net::HTTPResponse includes module 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 = Net::HTTP.get_response(uri) # => #<Net::HTTPOK 200 OK readbody=true>
+# res['Content-Type'] # => "text/html; charset=UTF-8"
+# res.content_type # => "text/html"
+#
+# == Response Subclasses
+#
+# \Class \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:
+#
+# Net::HTTPResponse::CODE_TO_OBJ['200'] # => Net::HTTPOK
+# Net::HTTPResponse::CODE_TO_OBJ['400'] # => Net::HTTPBadRequest
+# Net::HTTPResponse::CODE_TO_OBJ['404'] # => Net::HTTPNotFound
+#
+# And you can retrieve the status code for a response object:
+#
+# Net::HTTP.get_response(uri).code # => "200"
+# Net::HTTP.get_response(hostname, '/nosuch').code # => "404"
+#
+# The response subclasses (indentation shows class hierarchy):
+#
+# - Net::HTTPUnknownResponse (for unhandled \HTTP extensions).
+#
+# - Net::HTTPInformation:
+#
+# - Net::HTTPContinue (100)
+# - Net::HTTPSwitchProtocol (101)
+# - Net::HTTPProcessing (102)
+# - Net::HTTPEarlyHints (103)
+#
+# - Net::HTTPSuccess:
+#
+# - Net::HTTPOK (200)
+# - Net::HTTPCreated (201)
+# - Net::HTTPAccepted (202)
+# - Net::HTTPNonAuthoritativeInformation (203)
+# - Net::HTTPNoContent (204)
+# - Net::HTTPResetContent (205)
+# - Net::HTTPPartialContent (206)
+# - Net::HTTPMultiStatus (207)
+# - Net::HTTPAlreadyReported (208)
+# - Net::HTTPIMUsed (226)
+#
+# - HTTPRedirection:
+#
+# - Net::HTTPMultipleChoices (300)
+# - Net::HTTPMovedPermanently (301)
+# - Net::HTTPFound (302)
+# - Net::HTTPSeeOther (303)
+# - Net::HTTPNotModified (304)
+# - Net::HTTPUseProxy (305)
+# - Net::HTTPTemporaryRedirect (307)
+# - Net::HTTPPermanentRedirect (308)
#
-# This class wraps together the response header and the response body (the
-# entity requested).
+# - Net::HTTPClientError:
#
-# It mixes in the HTTPHeader module, which provides access to response
-# header values both via hash-like methods and via individual readers.
+# - Net::HTTPBadRequest (400)
+# - Net::HTTPUnauthorized (401)
+# - Net::HTTPPaymentRequired (402)
+# - Net::HTTPForbidden (403)
+# - Net::HTTPNotFound (404)
+# - Net::HTTPMethodNotAllowed (405)
+# - Net::HTTPNotAcceptable (406)
+# - Net::HTTPProxyAuthenticationRequired (407)
+# - Net::HTTPRequestTimeOut (408)
+# - Net::HTTPConflict (409)
+# - Net::HTTPGone (410)
+# - Net::HTTPLengthRequired (411)
+# - Net::HTTPPreconditionFailed (412)
+# - Net::HTTPRequestEntityTooLarge (413)
+# - Net::HTTPRequestURITooLong (414)
+# - Net::HTTPUnsupportedMediaType (415)
+# - Net::HTTPRequestedRangeNotSatisfiable (416)
+# - Net::HTTPExpectationFailed (417)
+# - Net::HTTPMisdirectedRequest (421)
+# - Net::HTTPUnprocessableEntity (422)
+# - Net::HTTPLocked (423)
+# - Net::HTTPFailedDependency (424)
+# - Net::HTTPUpgradeRequired (426)
+# - Net::HTTPPreconditionRequired (428)
+# - Net::HTTPTooManyRequests (429)
+# - Net::HTTPRequestHeaderFieldsTooLarge (431)
+# - Net::HTTPUnavailableForLegalReasons (451)
#
-# Note that each possible HTTP response code defines its own
-# HTTPResponse subclass. All classes are defined under the Net module.
-# Indentation indicates inheritance. For a list of the classes see Net::HTTP.
+# - Net::HTTPServerError:
#
-# Correspondence <code>HTTP code => class</code> is stored in CODE_TO_OBJ
-# constant:
+# - Net::HTTPInternalServerError (500)
+# - Net::HTTPNotImplemented (501)
+# - Net::HTTPBadGateway (502)
+# - Net::HTTPServiceUnavailable (503)
+# - Net::HTTPGatewayTimeOut (504)
+# - Net::HTTPVersionNotSupported (505)
+# - Net::HTTPVariantAlsoNegotiates (506)
+# - Net::HTTPInsufficientStorage (507)
+# - Net::HTTPLoopDetected (508)
+# - Net::HTTPNotExtended (510)
+# - Net::HTTPNetworkAuthenticationRequired (511)
#
-# Net::HTTPResponse::CODE_TO_OBJ['404'] #=> Net::HTTPNotFound
+# There is also the Net::HTTPBadResponse exception which is raised when
+# there is a protocol error.
#
class Net::HTTPResponse
class << self