Class: Faraday::Utils::Headers

Inherits:
Hash
  • Object
show all
Defined in:
lib/faraday/utils/headers.rb

Overview

A case-insensitive Hash that preserves the original case of a header when set.

Adapted from Rack::Utils::HeaderHash

Constant Summary collapse

KeyMap =

symbol -> string mapper + cache

Hash.new do |map, key|
  value = if key.respond_to?(:to_str)
            key
          else
            key.to_s.split('_') # user_agent: %w(user agent)
               .each(&:capitalize!) # => %w(User Agent)
               .join('-') # => "User-Agent"
          end
  keymap_mutex.synchronize { map[key] = value }
end

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash = nil) ⇒ Headers

Returns a new instance of Headers.



20
21
22
23
24
# File 'lib/faraday/utils/headers.rb', line 20

def initialize(hash = nil)
  super()
  @names = {}
  update(hash || {})
end

Class Method Details

.allocateObject



14
15
16
17
18
# File 'lib/faraday/utils/headers.rb', line 14

def self.allocate
  new_self = super
  new_self.initialize_names
  new_self
end

.from(value) ⇒ Object



10
11
12
# File 'lib/faraday/utils/headers.rb', line 10

def self.from(value)
  new(value)
end

Instance Method Details

#[](key) ⇒ Object



52
53
54
55
# File 'lib/faraday/utils/headers.rb', line 52

def [](key)
  key = KeyMap[key]
  super(key) || super(@names[key.downcase])
end

#[]=(key, val) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/faraday/utils/headers.rb', line 57

def []=(key, val)
  key = KeyMap[key]
  key = (@names[key.downcase] ||= key)
  # join multiple values with a comma
  val = val.to_ary.join(', ') if val.respond_to?(:to_ary)
  super(key, val)
end

#delete(key) ⇒ Object



71
72
73
74
75
76
77
78
# File 'lib/faraday/utils/headers.rb', line 71

def delete(key)
  key = KeyMap[key]
  key = @names[key.downcase]
  return unless key

  @names.delete key.downcase
  super(key)
end

#fetch(key, *args, &block) ⇒ Object



65
66
67
68
69
# File 'lib/faraday/utils/headers.rb', line 65

def fetch(key, *args, &block)
  key = KeyMap[key]
  key = @names.fetch(key.downcase, key)
  super(key, *args, &block)
end

#include?(key) ⇒ Boolean Also known as: has_key?, member?, key?

Returns:

  • (Boolean)


80
81
82
# File 'lib/faraday/utils/headers.rb', line 80

def include?(key)
  @names.include? key.downcase
end

#initialize_copy(other) ⇒ Object

on dup/clone, we need to duplicate @names hash



31
32
33
34
# File 'lib/faraday/utils/headers.rb', line 31

def initialize_copy(other)
  super
  @names = other.names.dup
end

#initialize_namesObject



26
27
28
# File 'lib/faraday/utils/headers.rb', line 26

def initialize_names
  @names = {}
end

#merge(other) ⇒ Object



95
96
97
98
# File 'lib/faraday/utils/headers.rb', line 95

def merge(other)
  hash = dup
  hash.merge! other
end

#merge!(other) ⇒ Object Also known as: update



88
89
90
91
# File 'lib/faraday/utils/headers.rb', line 88

def merge!(other)
  other.each { |k, v| self[k] = v }
  self
end

#parse(header_string) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/faraday/utils/headers.rb', line 111

def parse(header_string)
  return unless header_string && !header_string.empty?

  headers = header_string.split("\r\n")

  # Find the last set of response headers.
  start_index = headers.rindex { |x| x.start_with?('HTTP/') } || 0
  last_response = headers.slice(start_index, headers.size)

  last_response
    .tap { |a| a.shift if a.first.start_with?('HTTP/') }
    .map { |h| h.split(/:\s*/, 2) } # split key and value
    .reject { |p| p[0].nil? } # ignore blank lines
    .each { |key, value| add_parsed(key, value) }
end

#replace(other) ⇒ Object



100
101
102
103
104
105
# File 'lib/faraday/utils/headers.rb', line 100

def replace(other)
  clear
  @names.clear
  update other
  self
end

#to_hashObject



107
108
109
# File 'lib/faraday/utils/headers.rb', line 107

def to_hash
  {}.update(self)
end