class HTTP::Headers
HTTP Headers container.
def ==(other)
-
(Boolean)
-
def ==(other) return false unless other.respond_to? :to_a to_a == other.to_a end
def [](name)
-
(Array
- if header has more than one value) -
(String)
- if header has exactly one value -
(nil)
- if header was not set
def [](name) values = get(name) case values.count when 0 then nil when 1 then values.first else values end end
def add(name, value)
-
(void)
-
Parameters:
-
value
(Array<#to_s>, #to_s
) -- header value(s) to be appended -
name
(String, Symbol
) -- header name. When specified as a string, the
def add(name, value) lookup_name = normalize_header(name.to_s) wire_name = case name when String name when Symbol lookup_name else raise HTTP::HeaderError, "HTTP header must be a String or Symbol: #{name.inspect}" end Array(value).each do |v| @pile << [ lookup_name, wire_name, validate_value(v) ] end end
def coerce(object)
-
(Headers)
-
Parameters:
-
object
(#to_hash, #to_h, #to_a
) --
Raises:
-
(Error)
- if object can't be coerced
def coerce(object) unless object.is_a? self object = case when object.respond_to?(:to_hash) then object.to_hash when object.respond_to?(:to_h) then object.to_h when object.respond_to?(:to_a) then object.to_a else raise Error, "Can't coerce #{object.inspect} to Headers" end end headers = new object.each { |k, v| headers.add k, v } headers end
def delete(name)
-
(void)
-
Parameters:
-
name
(#to_s
) -- header name
def delete(name) name = normalize_header name.to_s @pile.delete_if { |k, _| k == name } end
def each
-
(Headers)
- self-reference -
(Enumerator)
- if no block given
def each return to_enum(__method__) unless block_given? @pile.each { |item| yield(item[1..2]) } self end
def get(name)
-
(Array
-)
def get(name) name = normalize_header name.to_s @pile.select { |k, _| k == name }.map { |_, _, v| v } end
def include?(name)
-
(Boolean)
-
def include?(name) name = normalize_header name.to_s @pile.any? { |k, _| k == name } end
def initialize
def initialize # The @pile stores each header value using a three element array: # 0 - the normalized header key, used for lookup # 1 - the header key as it will be sent with a request # 2 - the value @pile = [] end
def initialize_copy(orig)
- Api: - private
def initialize_copy(orig) super @pile = @pile.map(&:dup) end
def inspect
-
(String)
-
def inspect "#<#{self.class} #{to_h.inspect}>" end
def keys
-
(Array
-)
def keys @pile.map { |_, k, _| k }.uniq end
def merge(other)
-
(Headers)
-
Other tags:
- See: #merge! -
def merge(other) dup.tap { |dupped| dupped.merge! other } end
def merge!(other)
-
(void)
-
Other tags:
- See: #merge -
def merge!(other) self.class.coerce(other).to_h.each { |name, values| set name, values } end
def normalize_header(name)
-
(String)
- canonical HTTP header name
Raises:
-
(HeaderError)
- if normalized name does not
Parameters:
-
name
(String
) --
def normalize_header(name) return name if name =~ CANONICAL_NAME_RE normalized = name.split(/[\-_]/).each(&:capitalize!).join("-") return normalized if normalized =~ COMPLIANT_NAME_RE raise HeaderError, "Invalid HTTP header field name: #{name.inspect}" end
def set(name, value)
-
(void)
-
Parameters:
-
(
) --
def set(name, value) delete(name) add(name, value) end
def to_a
-
(Array<[String, String]>)
-
def to_a @pile.map { |item| item[1..2] } end
def to_h
-
(Hash)
-
def to_h Hash[keys.map { |k| [k, self[k]] }] end
def validate_value(value)
-
(String)
- stringified header value
Raises:
-
(HeaderError)
- if value includes new line character
Parameters:
-
value
(String
) --
def validate_value(value) v = value.to_s return v unless v.include?("\n") raise HeaderError, "Invalid HTTP header field value: #{v.inspect}" end