class Rubhttp::Headers

Constants

CANONICAL_NAME_RE

Matches HTTP header names when in “Canonical-Http-Format”.

COMPLIANT_NAME_RE

Matches valid header field name according to RFC. @see tools.ietf.org/html/rfc7230#section-3.2

Public Class Methods

new() click to toggle source
# File lib/rubhttp/headers.rb, line 12
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

Public Instance Methods

[](name) click to toggle source

Smart version of {#get}.

@return [nil] if header was not set @return [String] if header has exactly one value @return [Array<String>] if header has more than one value

# File lib/rubhttp/headers.rb, line 44
def [](name)
  values = get(name)
  case values.count
  when 0 then nil
  when 1 then values.first
  else values
  end
end
[]=(name, value)
Alias for: set
add(name, value) click to toggle source

Appends header.

@param [String, Symbol] name header name @param [Array<#to_s>, to_s] value header value(s) to be appended @return [void]

# File lib/rubhttp/headers.rb, line 58
def add(name, value)
  lookup_name = normalize_header_name(name.to_s)
  wire_name =
    case name
    when String then name
    when Symbol then lookup_name
    else raise HeaderError, "HTTP header must be a String or Symbol: #{name.inspect}"
    end
  Array(value).each do |v|
    @pile << [lookup_name, wire_name, v.to_s]
  end
end
delete(name) click to toggle source

Removes header.

@param [#to_s] name header name @return [void]

# File lib/rubhttp/headers.rb, line 75
def delete(name)
  name = normalize_header_name(name.to_s)
  @pile.delete_if { |k, _| k == name }
end
get(name) click to toggle source

Returns list of header values if any.

@return [Array<String>]

# File lib/rubhttp/headers.rb, line 34
def get(name)
  name = normalize_header_name(name.to_s)
  @pile.select { |k, _| k == name }.map { |_, _, v| v }
end
inspect() click to toggle source

Returns human-readable representation of `self` instance.

@return [String]

# File lib/rubhttp/headers.rb, line 98
def inspect
  "#<#{self.class} #{to_h.inspect}>"
end
keys() click to toggle source

Returns list of header names.

@return [Array<String>]

# File lib/rubhttp/headers.rb, line 105
def keys
  @pile.map { |_, k, _| k }.uniq
end
set(name, value) click to toggle source

Sets header.

@param (see add) @return [void]

# File lib/rubhttp/headers.rb, line 25
def set(name, value)
  delete(name)
  add(name, value)
end
Also aliased as: []=
to_a() click to toggle source

Returns headers key/value pairs.

@return [Array<[String, String]>]

# File lib/rubhttp/headers.rb, line 91
def to_a
  @pile.map { |item| item[1..2] }
end
to_h() click to toggle source

Returns Rack-compatible headers Hash.

@return [Hash]

# File lib/rubhttp/headers.rb, line 83
def to_h
  Hash[keys.map { |k| [k, self[k]] }]
end
Also aliased as: to_hash
to_hash()
Alias for: to_h

Private Instance Methods

normalize_header_name(name) click to toggle source

Transforms `name` to canonical HTTP header capitalization

@param [String] name @return [String] canonical HTTP header name

# File lib/rubhttp/headers.rb, line 115
def normalize_header_name(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