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" #