Class: Protocol::HTTP::Headers
- Inherits:
-
Object
- Object
- Protocol::HTTP::Headers
- Defined in:
- lib/protocol/http/headers.rb
Overview
Headers are an array of key-value pairs. Some header keys represent multiple values.
Defined Under Namespace
Classes: Merged
Constant Summary collapse
- Split =
Header::Split
- Multiple =
Header::Multiple
- TRAILERS =
'trailers'
- POLICY =
{ # Headers which may only be specified once. 'content-type' => false, 'content-disposition' => false, 'content-length' => false, 'user-agent' => false, 'referer' => false, 'host' => false, 'authorization' => false, 'proxy-authorization' => false, 'if-modified-since' => false, 'if-unmodified-since' => false, 'from' => false, 'location' => false, 'max-forwards' => false, # Custom headers: 'connection' => Header::Connection, 'cache-control' => Header::CacheControl, 'vary' => Header::Vary, # Headers specifically for proxies: 'via' => Split, 'x-forwarded-for' => Split, # Cache validations: 'etag' => Header::ETag, 'if-match' => Header::ETags, 'if-none-match' => Header::ETags, # Headers which may be specified multiple times, but which can't be concatenated: 'www-authenticate' => Multiple, 'proxy-authenticate' => Multiple, # Custom headers: 'set-cookie' => Header::SetCookie, 'cookie' => Header::Cookie, }.tap{|hash| hash.default = Split}
Instance Attribute Summary collapse
-
#fields ⇒ Object
readonly
An array of ‘[key, value]` pairs.
Class Method Summary collapse
-
.[](headers) ⇒ Headers
Construct an instance from a headers Array or Hash.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #[](key) ⇒ Object
-
#[]=(key, value) ⇒ Object
Append the value to the given key.
-
#add(key, value) ⇒ Object
Add the specified header key value pair.
- #clear ⇒ Object
-
#delete(key) ⇒ Object
Delete all headers with the given key, and return the merged value.
- #each(&block) ⇒ Object
- #empty? ⇒ Boolean
- #extract(keys) ⇒ Object
- #freeze ⇒ Object
- #include?(key) ⇒ Boolean
-
#initialize(fields = [], indexed = nil) ⇒ Headers
constructor
A new instance of Headers.
- #initialize_dup(other) ⇒ Object
- #inspect ⇒ Object
- #keys ⇒ Object
- #merge(headers) ⇒ Object
- #merge!(headers) ⇒ Object
-
#set(key, value) ⇒ Object
Set the specified header key to the specified value, replacing any existing header keys with the same name.
-
#to_h ⇒ Object
A hash table of ‘policy.map(values)`.
-
#trailers(&block) ⇒ Object
Enumerate all trailers, including evaluating all deferred headers.
-
#trailers! ⇒ Object
Mark the subsequent headers as trailers.
-
#trailers? ⇒ Boolean
The trailers if there are any.
Constructor Details
#initialize(fields = [], indexed = nil) ⇒ Headers
Returns a new instance of Headers.
50 51 52 53 54 55 56 |
# File 'lib/protocol/http/headers.rb', line 50 def initialize(fields = [], indexed = nil) @fields = fields @indexed = indexed # Marks where trailers start in the @fields array. @tail = nil end |
Instance Attribute Details
#fields ⇒ Object (readonly)
An array of ‘[key, value]` pairs.
73 74 75 |
# File 'lib/protocol/http/headers.rb', line 73 def fields @fields end |
Class Method Details
.[](headers) ⇒ Headers
Construct an instance from a headers Array or Hash. No-op if already an instance of ‘Headers`.
42 43 44 45 46 47 48 |
# File 'lib/protocol/http/headers.rb', line 42 def self.[] headers if headers.is_a?(self) headers else self.new(headers.to_a) end end |
Instance Method Details
#==(other) ⇒ Object
273 274 275 276 277 278 279 280 281 282 |
# File 'lib/protocol/http/headers.rb', line 273 def == other case other when Hash to_h == other when Headers @fields == other.fields else @fields == other end end |
#[](key) ⇒ Object
256 257 258 |
# File 'lib/protocol/http/headers.rb', line 256 def [] key to_h[key] end |
#[]=(key, value) ⇒ Object
Append the value to the given key. Some values can be appended multiple times, others can only be set once.
171 172 173 174 175 176 177 |
# File 'lib/protocol/http/headers.rb', line 171 def []= key, value if @indexed merge_into(@indexed, key.downcase, value) end @fields << [key, value] end |
#add(key, value) ⇒ Object
Add the specified header key value pair.
143 144 145 |
# File 'lib/protocol/http/headers.rb', line 143 def add(key, value) self[key] = value end |
#clear ⇒ Object
66 67 68 69 70 |
# File 'lib/protocol/http/headers.rb', line 66 def clear @fields.clear @indexed = nil @tail = nil end |
#delete(key) ⇒ Object
Delete all headers with the given key, and return the merged value.
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/protocol/http/headers.rb', line 219 def delete(key) deleted, @fields = @fields.partition do |field| field.first.downcase == key end if deleted.empty? return nil end if @indexed return @indexed.delete(key) elsif policy = POLICY[key] (key, value), *tail = deleted merged = policy.new(value) tail.each{|k,v| merged << v} return merged else key, value = deleted.last return value end end |
#each(&block) ⇒ Object
114 115 116 |
# File 'lib/protocol/http/headers.rb', line 114 def each(&block) @fields.each(&block) end |
#empty? ⇒ Boolean
110 111 112 |
# File 'lib/protocol/http/headers.rb', line 110 def empty? @fields.empty? end |
#extract(keys) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/protocol/http/headers.rb', line 126 def extract(keys) deleted, @fields = @fields.partition do |field| keys.include?(field.first.downcase) end if @indexed keys.each do |key| @indexed.delete(key) end end return deleted end |
#freeze ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/protocol/http/headers.rb', line 98 def freeze return if frozen? # Ensure @indexed is generated: self.to_h @fields.freeze @indexed.freeze super end |
#include?(key) ⇒ Boolean
118 119 120 |
# File 'lib/protocol/http/headers.rb', line 118 def include? key self[key] != nil end |
#initialize_dup(other) ⇒ Object
58 59 60 61 62 63 64 |
# File 'lib/protocol/http/headers.rb', line 58 def initialize_dup(other) super @fields = @fields.dup @indexed = @indexed.dup @tail = nil end |
#inspect ⇒ Object
269 270 271 |
# File 'lib/protocol/http/headers.rb', line 269 def inspect "#<#{self.class} #{@fields.inspect}>" end |
#keys ⇒ Object
122 123 124 |
# File 'lib/protocol/http/headers.rb', line 122 def keys self.to_h.keys end |
#merge(headers) ⇒ Object
164 165 166 |
# File 'lib/protocol/http/headers.rb', line 164 def merge(headers) self.dup.merge!(headers) end |
#merge!(headers) ⇒ Object
156 157 158 159 160 161 162 |
# File 'lib/protocol/http/headers.rb', line 156 def merge!(headers) headers.each do |key, value| self[key] = value end return self end |
#set(key, value) ⇒ Object
Set the specified header key to the specified value, replacing any existing header keys with the same name.
150 151 152 153 154 |
# File 'lib/protocol/http/headers.rb', line 150 def set(key, value) # TODO This could be a bit more efficient: self.delete(key) self.add(key, value) end |
#to_h ⇒ Object
A hash table of ‘policy.map(values)`
261 262 263 264 265 266 267 |
# File 'lib/protocol/http/headers.rb', line 261 def to_h @indexed ||= @fields.inject({}) do |hash, (key, value)| merge_into(hash, key.downcase, value) hash end end |
#trailers(&block) ⇒ Object
Enumerate all trailers, including evaluating all deferred headers.
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/protocol/http/headers.rb', line 86 def trailers(&block) return nil unless self.include?(TRAILERS) trailers! return to_enum(:trailers) unless block_given? if @tail @fields.drop(@tail).each(&block) end end |
#trailers! ⇒ Object
Mark the subsequent headers as trailers.
76 77 78 |
# File 'lib/protocol/http/headers.rb', line 76 def trailers! @tail ||= @fields.size end |
#trailers? ⇒ Boolean
Returns the trailers if there are any.
81 82 83 |
# File 'lib/protocol/http/headers.rb', line 81 def trailers? @tail != nil end |