diff --git a/lib/net/http/header.rb b/lib/net/http/header.rb
index d7e53a5f..3c95ee33 100644
--- a/lib/net/http/header.rb
+++ b/lib/net/http/header.rb
@@ -126,38 +126,49 @@
# Various convenience methods retrieve values, set values, query values,
# set form values, or iterate over fields.
#
+# === Setters
+#
+# \Method #[]= can set any field, but does little to validate the new value;
+# some of the other setter methods provide some validation:
+#
+# - #[]=: Sets the string or array value for the given key.
+# - #add_field: Creates or adds to the array value for the given key.
+# - #basic_auth: Sets the string authorization header for 'Authorization'.
+# - #content_length=: Sets the integer length for field 'Content-Length.
+# - #content_type=: Sets the string value for field 'Content-Type'.
+# - #proxy_basic_auth: Sets the string authorization header for 'Proxy-Authorization'.
+# - #set_range: Sets the value for field 'Range'.
+#
+# === Form Setters
+#
+# - #set_form: Sets an HTML form data set.
+# - #set_form_data: Sets header fields and a body from HTML form data.
+#
# === Getters
#
-# - #[]: Returns the string value for the given field.
+# \Method #[] can retrieve the value of any field that exists,
+# but always as a string;
+# some of the other getter methods return something different
+# from the simple string value:
+#
+# - #[]: Returns the string field value for the given key.
# - #content_length: Returns the integer value of field 'Content-Length'.
# - #content_range: Returns the Range value of field 'Content-Range'.
# - #content_type: Returns the string value of field 'Content-Type'.
+# - #fetch: Returns the string field value for the given key.
+# - #get_fields: Returns the array field value for the given +key+.
# - #main_type: Returns first part of the string value of field 'Content-Type'.
# - #sub_type: Returns second part of the string value of field 'Content-Type'.
# - #range: Returns an array of Range objects of field 'Range', or +nil+.
# - #range_length: Returns the integer length of the range given in field 'Content-Range'.
# - #type_params: Returns the string parameters for 'Content-Type'.
#
-# === Setters
-#
-# - #[]=: Sets the string or array value for the given field.
-# - #basic_auth: Sets the string authorization header for 'Authorization'.
-# - #content_length=: Sets the integer length for field 'Content-Length.
-# - #content_type=: Sets the string value for field 'Content-Type'.
-# - #proxy_basic_auth: Sets the string authorization header for 'Proxy-Authorization'.
-# - #set_range: Sets the value for field 'Range'.
-#
# === Queries
#
# - #chunked?: Returns whether field 'Transfer-Encoding' is set to 'chunked'.
# - #connection_close?: Returns whether field 'Connection' is set to 'close'.
# - #connection_keep_alive?: Returns whether field 'Connection' is set to 'keep-alive'.
-# - #key?: Returns whether a given field exists.
-#
-# === Form Setters
-#
-# - #set_form: Sets an HTML form data set.
-# - #set_form_data: Sets header fields and a body from HTML form data.
+# - #key?: Returns whether a given key exists.
#
# === Iterators
#
@@ -165,7 +176,7 @@
# - #each_capitalized_name: Passes each capitalized field name to the block.
# - #each_header: Passes each field name/value pair to the block.
# - #each_name: Passes each field name to the block.
-# - #each_value: Passes each field value to the block.
+# - #each_value: Passes each string field value to the block.
#
module Net::HTTPHeader
@@ -196,12 +207,14 @@ def size #:nodoc: obsolete
# or +nil+ if there is no such key;
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
#
- # req = Net::HTTP::Get.new(uri)
- # req['Accept'] # => "*/*"
- # req['Foo'] = %w[bar baz bat]
- # req['Foo'] # => "bar, baz, bat"
- # res['Nosuch'] # => nil
+ # res = Net::HTTP.start(hostname) do |http|
+ # http.get('/todos/1')
+ # end
+ # res['Connection'] # => "keep-alive"
+ # res['Nosuch'] # => nil
#
+ # Note that some field values may be retrieved via convenience methods;
+ # see {Getters}[rdoc-ref:Net::HTTPHeader@Getters].
def [](key)
a = @header[key.downcase.to_s] or return nil
a.join(', ')
@@ -216,6 +229,8 @@ def [](key)
# req['Accept'] = 'text/html'
# req['Accept'] # => "text/html"
#
+ # Note that some field values may be set via convenience methods;
+ # see {Setters}[rdoc-ref:Net::HTTPHeader@Setters].
def []=(key, val)
unless val
@header.delete key.downcase.to_s
@@ -278,12 +293,11 @@ def add_field(key, val)
# or +nil+ if there is no such field;
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
#
- # req = Net::HTTP::Get.new(uri)
- # req['Foo'] = 'bar'
- # req.get_fields('Foo') # => ["bar"]
- # req.add_field('Foo', 'baz')
- # req.get_fields('Foo') # => ["bar", "baz"]
- # req.get_fields('Nosuch') # => nil
+ # res = Net::HTTP.start(hostname) do |http|
+ # http.get('/todos/1')
+ # end
+ # res.get_fields('Connection') # => ["keep-alive"]
+ # res.get_fields('Nosuch') # => nil
#
def get_fields(key)
stringified_downcased_key = key.downcase.to_s
@@ -300,18 +314,27 @@ def get_fields(key)
# ignores the +default_val+;
# see {Fields}[rdoc-ref:Net::HTTPHeader@Fields]:
#
- # req = Net::HTTP::Get.new(uri)
- # req['Foo'] = 'bar'
- # req.fetch('Foo') {|key| key.capitalize } # => "bar"
- # req.fetch('Nosuch') {|key| key.capitalize } # => "Nosuch"
+ # res = Net::HTTP.start(hostname) do |http|
+ # http.get('/todos/1')
+ # end
+ #
+ # # Field exists; block not called.
+ # res.fetch('Connection') do |value|
+ # fail 'Cannot happen'
+ # end # => "keep-alive"
+ #
+ # # Field does not exist; block called.
+ # res.fetch('Nosuch') do |value|
+ # value.downcase
+ # end # => "nosuch"
#
# With no block, returns the string value for +key+ if it exists;
# otherwise, returns +default_val+ if it was given;
# otherwise raises an exception:
#
- # req.fetch('Foo') # => "bar"
- # req.fetch('Nosuch', :baz) # => :baz
- # req.fetch('Nosuch') # Raises KeyError.
+ # res.fetch('Connection', 'Foo') # => "keep-alive"
+ # res.fetch('Nosuch', 'Foo') # => "Foo"
+ # res.fetch('Nosuch') # Raises KeyError.
#
def fetch(key, *args, &block) #:yield: +key+
a = @header.fetch(key.downcase.to_s, *args, &block)
@@ -320,15 +343,20 @@ def fetch(key, *args, &block) #:yield: +key+
# Calls the block with each key/value pair:
#
- # req = Net::HTTP::Get.new(uri)
- # req.each_header {|key, value| p [key, value] }
+ # res = Net::HTTP.start(hostname) do |http|
+ # http.get('/todos/1')
+ # end
+ # res.each_header do |key, value|
+ # p [key, value] if key.start_with?('c')
+ # end
#
# Output:
#
- # ["accept-encoding", "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]
- # ["accept", "*/*"]
- # ["user-agent", "Ruby"]
- # ["host", "jsonplaceholder.typicode.com"]
+ # ["content-type", "application/json; charset=utf-8"]
+ # ["connection", "keep-alive"]
+ # ["cache-control", "max-age=43200"]
+ # ["cf-cache-status", "HIT"]
+ # ["cf-ray", "771d17e9bc542cf5-ORD"]
#
# Returns an enumerator if no block is given.
#
@@ -344,15 +372,20 @@ def each_header #:yield: +key+, +value+
# Calls the block with each field key:
#
- # req = Net::HTTP::Get.new(uri)
- # req.each_key {|key| p key }
+ # res = Net::HTTP.start(hostname) do |http|
+ # http.get('/todos/1')
+ # end
+ # res.each_key do |key|
+ # p key if key.start_with?('c')
+ # end
#
# Output:
#
- # "accept-encoding"
- # "accept"
- # "user-agent"
- # "host"
+ # "content-type"
+ # "connection"
+ # "cache-control"
+ # "cf-cache-status"
+ # "cf-ray"
#
# Returns an enumerator if no block is given.
#
@@ -366,15 +399,20 @@ def each_name(&block) #:yield: +key+
# Calls the block with each capitalized field name:
#
- # req = Net::HTTP::Get.new(uri)
- # req.each_capitalized_name {|key| p key }
+ # res = Net::HTTP.start(hostname) do |http|
+ # http.get('/todos/1')
+ # end
+ # res.each_capitalized_name do |key|
+ # p key if key.start_with?('C')
+ # end
#
# Output:
#
- # "Accept-Encoding"
- # "Accept"
- # "User-Agent"
- # "Host"
+ # "Content-Type"
+ # "Connection"
+ # "Cache-Control"
+ # "Cf-Cache-Status"
+ # "Cf-Ray"
#
# The capitalization is system-dependent;
# see {Case Mapping}[https://docs.ruby-lang.org/en/master/case_mapping_rdoc.html].
@@ -387,17 +425,20 @@ def each_capitalized_name #:yield: +key+
end
end
- # Calls the block with each field value:
+ # Calls the block with each string field value:
#
- # req = Net::HTTP::Get.new(uri)
- # req.each_value {|value| p value }
+ # res = Net::HTTP.start(hostname) do |http|
+ # http.get('/todos/1')
+ # end
+ # res.each_value do |value|
+ # p value if value.start_with?('c')
+ # end
#
# Output:
#
- # "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
- # "*/*"
- # "Ruby"
- # "jsonplaceholder.typicode.com"
+ # "chunked"
+ # "cf-q-config;dur=6.0000002122251e-06"
+ # "cloudflare"
#
# Returns an enumerator if no block is given.
def each_value #:yield: +value+
@@ -465,6 +506,7 @@ def capitalize(name)
# or +nil+ if there is no such field;
# see {Range request header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#range-request-header]:
#
+ # req = Net::HTTP::Get.new(uri)
# req['Range'] = 'bytes=0-99,200-299,400-499'
# req.range # => [0..99, 200..299, 400..499]
# req.delete('Range')
@@ -522,6 +564,7 @@ def range
#
# With argument +length+:
#
+ # req = Net::HTTP::Get.new(uri)
# req.set_range(100) # => 100
# req['Range'] # => "bytes=0-99"
#