Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DOC] Enhanced RDoc for Net::HTTPHeader #83

Merged
merged 2 commits into from
Dec 1, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 103 additions & 60 deletions lib/net/http/header.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,46 +126,57 @@
# Various convenience methods retrieve values, set values, query values,
# set form values, or iterate over fields.
#
# === Setters
#
# \Method #[]= can set any field, but does little to validate the new value;
# some of the other setter methods provide some validation:
#
# - #[]=: Sets the string or array value for the given key.
# - #add_field: Creates or adds to the array value for the given key.
# - #basic_auth: Sets the string authorization header for <tt>'Authorization'</tt>.
# - #content_length=: Sets the integer length for field <tt>'Content-Length</tt>.
# - #content_type=: Sets the string value for field <tt>'Content-Type'</tt>.
# - #proxy_basic_auth: Sets the string authorization header for <tt>'Proxy-Authorization'</tt>.
# - #set_range: Sets the value for field <tt>'Range'</tt>.
#
# === Form Setters
#
# - #set_form: Sets an HTML form data set.
# - #set_form_data: Sets header fields and a body from HTML form data.
#
# === Getters
#
# - #[]: 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 <tt>'Content-Length'</tt>.
# - #content_range: Returns the Range value of field <tt>'Content-Range'</tt>.
# - #content_type: Returns the string value of field <tt>'Content-Type'</tt>.
# - #fetch: Returns the string field value for the given key.
# - #get_fields: Returns the array field value for the given +key+.
# - #main_type: Returns first part of the string value of field <tt>'Content-Type'</tt>.
# - #sub_type: Returns second part of the string value of field <tt>'Content-Type'</tt>.
# - #range: Returns an array of Range objects of field <tt>'Range'</tt>, or +nil+.
# - #range_length: Returns the integer length of the range given in field <tt>'Content-Range'</tt>.
# - #type_params: Returns the string parameters for <tt>'Content-Type'</tt>.
#
# === Setters
#
# - #[]=: Sets the string or array value for the given field.
# - #basic_auth: Sets the string authorization header for <tt>'Authorization'</tt>.
# - #content_length=: Sets the integer length for field <tt>'Content-Length</tt>.
# - #content_type=: Sets the string value for field <tt>'Content-Type'</tt>.
# - #proxy_basic_auth: Sets the string authorization header for <tt>'Proxy-Authorization'</tt>.
# - #set_range: Sets the value for field <tt>'Range'</tt>.
#
# === Queries
#
# - #chunked?: Returns whether field <tt>'Transfer-Encoding'</tt> is set to <tt>'chunked'</tt>.
# - #connection_close?: Returns whether field <tt>'Connection'</tt> is set to <tt>'close'</tt>.
# - #connection_keep_alive?: Returns whether field <tt>'Connection'</tt> is set to <tt>'keep-alive'</tt>.
# - #key?: Returns whether a given 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
#
# - #each_capitalized: Passes each field capitalized-name/value pair to the block.
# - #each_capitalized_name: Passes each capitalized field name to the block.
# - #each_header: Passes each field name/value pair to the block.
# - #each_name: Passes each field name to the block.
# - #each_value: Passes each field value to the block.
# - #each_value: Passes each string field value to the block.
#
module Net::HTTPHeader

Expand Down Expand Up @@ -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(', ')
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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.
#
Expand All @@ -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.
#
Expand All @@ -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].
Expand All @@ -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+
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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"
#
Expand Down