class Protocol::HTTP::Headers

Headers are an array of key-value pairs. Some header keys represent multiple values.

def self.[] headers

Returns:
  • (Headers) - an instance of headers.
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

def == other

def == other
	case other
	when Hash
		to_h == other
	when Headers
		@fields == other.fields
	else
		@fields == other
	end
end

def [] key

def [] key
	to_h[key]
end

def []= key, value

Parameters:
  • value () -- The header value.
  • key (String) -- The header key.
def []= key, value
	if @indexed
		merge_into(@indexed, key.downcase, value)
	end
	
	@fields << [key, value]
end

def add(key, value)

Parameters:
  • value (String) -- the header value to assign.
  • key (String) -- the header key.
def add(key, value)
	self[key] = value
end

def clear

def clear
	@fields.clear
	@indexed = nil
	@tail = nil
end

def delete(key)

Delete all headers with the given key, and return the merged value.
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

def each(&block)

def each(&block)
	@fields.each(&block)
end

def empty?

def empty?
	@fields.empty?
end

def extract(keys)

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

def flatten

def flatten
	self.dup.flatten!
end

def flatten!

Flatten trailer into the headers.
def flatten!
	if @tail
		self.delete(TRAILER)
		@tail = nil
	end
	
	return self
end

def freeze

def freeze
	return if frozen?
	
	# Ensure @indexed is generated:
	self.to_h
	
	@fields.freeze
	@indexed.freeze
	
	super
end

def include? key

def include? key
	self[key] != nil
end

def initialize(fields = [], indexed = nil)

def initialize(fields = [], indexed = nil)
	@fields = fields
	@indexed = indexed
	
	# Marks where trailer start in the @fields array.
	@tail = nil
end

def initialize_dup(other)

def initialize_dup(other)
	super
	
	@fields = @fields.dup
	@indexed = @indexed.dup
end

def inspect

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

def keys

def keys
	self.to_h.keys
end

def merge(headers)

def merge(headers)
	self.dup.merge!(headers)
end

def merge!(headers)

def merge!(headers)
	headers.each do |key, value|
		self[key] = value
	end
	
	return self
end

def merge_into(hash, key, value)

def merge_into(hash, key, value)
 = POLICY[key]
nt_value = hash[key]
_value << value
y] = policy.new(value)
't merge these, we only expose the last one set.
] = value

def set(key, value)

Parameters:
  • value (String) -- the header value to assign.
  • key (String) -- the header key to replace.
def set(key, value)
	# TODO This could be a bit more efficient:
	self.delete(key)
	self.add(key, value)
end

def to_h

A hash table of `{key, policy[key].map(values)}`
def to_h
	@indexed ||= @fields.inject({}) do |hash, (key, value)|
		merge_into(hash, key.downcase, value)
		
		hash
	end
end

def trailer(&block)

Enumerate all headers in the trailer, if there are any.
def trailer(&block)
	return to_enum(:trailer) unless block_given?
	
	if @tail
		@fields.drop(@tail).each(&block)
	end
end

def trailer!(&block)

@returns An enumerator which is suitable for iterating over trailers.
@yields block {|name, value| ...} The trailer headers if any.
@parameter names [Array] The trailer header names which will be added later.

that message to indicate which fields might be present in the trailers.
message should generate a trailer header field in the header section of
A sender that intends to generate one or more trailer fields in a

additional headers which should then be sent as trailers.
This method is typically used after headers are sent to capture any

Record the current headers, and prepare to add trailers.
def trailer!(&block)
	@tail ||= @fields.size
	
	return trailer(&block)
end

def trailer?

@returns Whether there are any trailers.
def trailer?
	@tail != nil
end