Class: HTTP::Headers

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/http/headers.rb,
lib/http/headers/known.rb,
lib/http/headers/mixin.rb

Overview

HTTP Headers container.

Defined Under Namespace

Modules: Mixin

Constant Summary collapse

CANONICAL_NAME_RE =

Matches HTTP header names when in "Canonical-Http-Format"

/\A[A-Z][a-z]*(?:-[A-Z][a-z]*)*\z/.freeze
COMPLIANT_NAME_RE =

Matches valid header field name according to RFC.

/\A[A-Za-z0-9!#\$%&'*+\-.^_`|~]+\z/.freeze
ACCEPT =

Content-Types that are acceptable for the response.

"Accept"
ACCEPT_ENCODING =

Content-codings that are acceptable in the response.

"Accept-Encoding"
AGE =

The age the object has been in a proxy cache in seconds.

"Age"
AUTHORIZATION =

Authentication credentials for HTTP authentication.

"Authorization"
CACHE_CONTROL =

Used to specify directives that must be obeyed by all caching mechanisms along the request-response chain.

"Cache-Control"
"Cookie"
CONNECTION =

Control options for the current connection and list of hop-by-hop request fields.

"Connection"
CONTENT_LENGTH =

The length of the request body in octets (8-bit bytes).

"Content-Length"
CONTENT_TYPE =

The MIME type of the body of the request (used with POST and PUT requests).

"Content-Type"
DATE =

The date and time that the message was sent (in "HTTP-date" format as defined by RFC 7231 Date/Time Formats).

"Date"
ETAG =

An identifier for a specific version of a resource, often a message digest.

"ETag"
EXPIRES =

Gives the date/time after which the response is considered stale (in "HTTP-date" format as defined by RFC 7231).

"Expires"
HOST =

The domain name of the server (for virtual hosting), and the TCP port number on which the server is listening. The port number may be omitted if the port is the standard port for the service requested.

"Host"
IF_MODIFIED_SINCE =

Allows a 304 Not Modified to be returned if content is unchanged.

"If-Modified-Since"
IF_NONE_MATCH =

Allows a 304 Not Modified to be returned if content is unchanged.

"If-None-Match"
LAST_MODIFIED =

The last modified date for the requested object (in "HTTP-date" format as defined by RFC 7231).

"Last-Modified"
LOCATION =

Used in redirection, or when a new resource has been created.

"Location"
PROXY_AUTHORIZATION =

Authorization credentials for connecting to a proxy.

"Proxy-Authorization"
"Set-Cookie"
TRANSFER_ENCODING =

The form of encoding used to safely transfer the entity to the user. Currently defined methods are: chunked, compress, deflate, gzip, identity.

"Transfer-Encoding"
CONTENT_ENCODING =

Indicates what additional content codings have been applied to the entity-body.

"Content-Encoding"
USER_AGENT =

The user agent string of the user agent.

"User-Agent"
VARY =

Tells downstream proxies how to match future request headers to decide whether the cached response can be used rather than requesting a fresh one from the origin server.

"Vary"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeHeaders

Class constructor.


23
24
25
26
27
28
29
# File 'lib/http/headers.rb', line 23

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

Class Method Details

.coerce(object) ⇒ Headers Also known as: []

Coerces given object into Headers.

Parameters:

Returns:

Raises:

  • (Error)

    if object can't be coerced


203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/http/headers.rb', line 203

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

Instance Method Details

#==(other) ⇒ Boolean

Compares headers to another Headers or Array of key/value pairs

Returns:

  • (Boolean)

142
143
144
145
146
# File 'lib/http/headers.rb', line 142

def ==(other)
  return false unless other.respond_to? :to_a

  to_a == other.to_a
end

#[](name) ⇒ nil, ...

Smart version of #get.

Returns:

  • (nil)

    if header was not set

  • (String)

    if header has exactly one value

  • (Array<String>)

    if header has more than one value


92
93
94
95
96
97
98
99
100
# File 'lib/http/headers.rb', line 92

def [](name)
  values = get(name)

  case values.count
  when 0 then nil
  when 1 then values.first
  else        values
  end
end

#add(name, value) ⇒ void

This method returns an undefined value.

Appends header.

Parameters:

  • name (String, Symbol)

    header name. When specified as a string, the name is sent as-is. When specified as a symbol, the name is converted to a string of capitalized words separated by a dash. Word boundaries are determined by an underscore (_) or a dash (-). Ex: :content_type is sent as "Content-Type", and "auth_key" (string) is sent as "auth_key".

  • value (Array<#to_s>, #to_s)

    header value(s) to be appended


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/http/headers.rb', line 60

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

#delete(name) ⇒ void

This method returns an undefined value.

Removes header.

Parameters:

  • name (#to_s)

    header name


45
46
47
48
# File 'lib/http/headers.rb', line 45

def delete(name)
  name = normalize_header name.to_s
  @pile.delete_if { |k, _| k == name }
end

#eachEnumerator, Headers

Calls the given block once for each key/value pair in headers container.

Returns:

  • (Enumerator)

    if no block given

  • (Headers)

    self-reference


152
153
154
155
156
157
# File 'lib/http/headers.rb', line 152

def each
  return to_enum(__method__) unless block_given?

  @pile.each { |item| yield(item[1..2]) }
  self
end

#empty?Boolean

Returns true if self has no key/value pairs

Returns:

  • (Boolean)

163
# File 'lib/http/headers.rb', line 163

def_delegator :@pile, :empty?

#get(name) ⇒ Array<String>

Returns list of header values if any.

Returns:

  • (Array<String>)

82
83
84
85
# File 'lib/http/headers.rb', line 82

def get(name)
  name = normalize_header name.to_s
  @pile.select { |k, _| k == name }.map { |_, _, v| v }
end

#hashFixnum

Compute a hash-code for this headers container. Two containers with the same content will have the same hash code.


171
# File 'lib/http/headers.rb', line 171

def_delegator :@pile, :hash

#include?(name) ⇒ Boolean

Tells whenever header with given name is set or not.

Returns:

  • (Boolean)

105
106
107
108
# File 'lib/http/headers.rb', line 105

def include?(name)
  name = normalize_header name.to_s
  @pile.any? { |k, _| k == name }
end

#initialize_copy(orig) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Properly clones internal key/value storage.


176
177
178
179
# File 'lib/http/headers.rb', line 176

def initialize_copy(orig)
  super
  @pile = @pile.map(&:dup)
end

#inspectString

Returns human-readable representation of self instance.

Returns:

  • (String)

128
129
130
# File 'lib/http/headers.rb', line 128

def inspect
  "#<#{self.class} #{to_h.inspect}>"
end

#keysArray<String>

Returns list of header names.

Returns:

  • (Array<String>)

135
136
137
# File 'lib/http/headers.rb', line 135

def keys
  @pile.map { |_, k, _| k }.uniq
end

#merge(other) ⇒ Headers

Returns new instance with other headers merged in.

Returns:

See Also:


193
194
195
# File 'lib/http/headers.rb', line 193

def merge(other)
  dup.tap { |dupped| dupped.merge! other }
end

#merge!(other) ⇒ void

This method returns an undefined value.

Merges other headers into self.

See Also:


185
186
187
# File 'lib/http/headers.rb', line 185

def merge!(other)
  self.class.coerce(other).to_h.each { |name, values| set name, values }
end

#set(name, value) ⇒ void Also known as: []=

This method returns an undefined value.

Sets header.

Parameters:

  • name (String, Symbol)

    header name. When specified as a string, the name is sent as-is. When specified as a symbol, the name is converted to a string of capitalized words separated by a dash. Word boundaries are determined by an underscore (_) or a dash (-). Ex: :content_type is sent as "Content-Type", and "auth_key" (string) is sent as "auth_key".

  • value (Array<#to_s>, #to_s)

    header value(s) to be appended


35
36
37
38
# File 'lib/http/headers.rb', line 35

def set(name, value)
  delete(name)
  add(name, value)
end

#to_aArray<[String, String]>

Returns headers key/value pairs.

Returns:

  • (Array<[String, String]>)

121
122
123
# File 'lib/http/headers.rb', line 121

def to_a
  @pile.map { |item| item[1..2] }
end

#to_hHash Also known as: to_hash

Returns Rack-compatible headers Hash

Returns:

  • (Hash)

113
114
115
# File 'lib/http/headers.rb', line 113

def to_h
  Hash[keys.map { |k| [k, self[k]] }]
end