class Protocol::HTTP::Headers
Headers
are an array of key-value pairs. Some header keys represent multiple values.
Constants
- Multiple
- POLICY
- Split
- TRAILER
Attributes
An array of `[key, value]` pairs.
Public Class Methods
Construct an instance from a headers Array or Hash. No-op if already an instance of `Headers`. If the underlying array is frozen, it will be duped. @return [Headers] an instance of headers.
# File lib/protocol/http/headers.rb, line 44 def self.[] headers if headers.nil? return self.new end if headers.is_a?(self) if headers.frozen? return headers.dup else return headers end end fields = headers.to_a if fields.frozen? fields = fields.dup end return self.new(fields) end
# File lib/protocol/http/headers.rb, line 66 def initialize(fields = [], indexed = nil) @fields = fields @indexed = indexed # Marks where trailer start in the @fields array. @tail = nil end
Public Instance Methods
# File lib/protocol/http/headers.rb, line 309 def == other case other when Hash to_h == other when Headers @fields == other.fields else @fields == other end end
# File lib/protocol/http/headers.rb, line 292 def [] key to_h[key] end
Append the value to the given key. Some values can be appended multiple times, others can only be set once. @param key [String] The header key. @param value The header value.
# File lib/protocol/http/headers.rb, line 205 def []= key, value if @indexed merge_into(@indexed, key.downcase, value) end @fields << [key, value] end
Add the specified header key value pair.
@param key [String] the header key. @param value [String] the header value to assign.
# File lib/protocol/http/headers.rb, line 177 def add(key, value) self[key] = value end
# File lib/protocol/http/headers.rb, line 81 def clear @fields.clear @indexed = nil @tail = nil end
Delete all headers with the given key, and return the merged value.
# File lib/protocol/http/headers.rb, line 255 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
# File lib/protocol/http/headers.rb, line 147 def each(&block) @fields.each(&block) end
# File lib/protocol/http/headers.rb, line 143 def empty? @fields.empty? end
# File lib/protocol/http/headers.rb, line 159 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
# File lib/protocol/http/headers.rb, line 97 def flatten self.dup.flatten! end
Flatten trailer into the headers.
# File lib/protocol/http/headers.rb, line 88 def flatten! if @tail self.delete(TRAILER) @tail = nil end return self end
# File lib/protocol/http/headers.rb, line 131 def freeze return if frozen? # Ensure @indexed is generated: self.to_h @fields.freeze @indexed.freeze super end
# File lib/protocol/http/headers.rb, line 151 def include? key self[key] != nil end
# File lib/protocol/http/headers.rb, line 74 def initialize_dup(other) super @fields = @fields.dup @indexed = @indexed.dup end
# File lib/protocol/http/headers.rb, line 305 def inspect "#<#{self.class} #{@fields.inspect}>" end
# File lib/protocol/http/headers.rb, line 155 def keys self.to_h.keys end
# File lib/protocol/http/headers.rb, line 198 def merge(headers) self.dup.merge!(headers) end
# File lib/protocol/http/headers.rb, line 190 def merge!(headers) headers.each do |key, value| self[key] = value end return self end
Set the specified header key to the specified value, replacing any existing header keys with the same name. @param key [String] the header key to replace. @param value [String] the header value to assign.
# File lib/protocol/http/headers.rb, line 184 def set(key, value) # TODO This could be a bit more efficient: self.delete(key) self.add(key, value) end
A hash table of `{key, policy.map(values)}`
# File lib/protocol/http/headers.rb, line 297 def to_h @indexed ||= @fields.inject({}) do |hash, (key, value)| merge_into(hash, key.downcase, value) hash end end
Enumerate all headers in the trailer, if there are any.
# File lib/protocol/http/headers.rb, line 123 def trailer(&block) return to_enum(:trailer) unless block_given? if @tail @fields.drop(@tail).each(&block) end end
Record the current headers, and prepare to receive trailer.
# File lib/protocol/http/headers.rb, line 110 def trailer!(&block) return nil unless self.include?(TRAILER) @tail ||= @fields.size return to_enum(:trailer!) unless block_given? if @tail @fields.drop(@tail).each(&block) end end
@return the trailer if there are any.
# File lib/protocol/http/headers.rb, line 105 def trailer? @tail != nil end
Protected Instance Methods
# File lib/protocol/http/headers.rb, line 279 def merge_into(hash, key, value) if policy = POLICY[key] if current_value = hash[key] current_value << value else hash[key] = policy.new(value) end else # We can't merge these, we only expose the last one set. hash[key] = value end end