lib/protocol/http/headers.rb in protocol-http-0.17.0 vs lib/protocol/http/headers.rb in protocol-http-0.18.0
- old
+ new
@@ -33,20 +33,35 @@
module HTTP
# Headers are an array of key-value pairs. Some header keys represent multiple values.
class Headers
Split = Header::Split
Multiple = Header::Multiple
+
TRAILERS = 'trailers'
- # Construct an instance from a headers Array or Hash. No-op if already an instance of `Headers`.
+ # 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.
def self.[] headers
+ if headers.nil?
+ return self.new
+ end
+
if headers.is_a?(self)
- headers
- else
- self.new(headers.to_a)
+ 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 initialize(fields = [], indexed = nil)
@fields = fields
@indexed = indexed
@@ -58,37 +73,54 @@
def initialize_dup(other)
super
@fields = @fields.dup
@indexed = @indexed.dup
- @tail = nil
end
def clear
@fields.clear
@indexed = nil
@tail = nil
end
- # An array of `[key, value]` pairs.
- attr :fields
+ # Flatten trailers into the headers.
+ def flatten!
+ if @tail
+ self.delete(TRAILERS)
+ @tail = nil
+ end
+
+ return self
+ end
- # Mark the subsequent headers as trailers.
- def trailers!
- @tail ||= @fields.size
+ def flatten
+ self.dup.flatten!
end
+ # An array of `[key, value]` pairs.
+ attr :fields
+
# @return the trailers if there are any.
def trailers?
@tail != nil
end
- # Enumerate all trailers, including evaluating all deferred headers.
- def trailers(&block)
+ # Record the current headers, and prepare to receive trailers.
+ def trailers!(&block)
return nil unless self.include?(TRAILERS)
- trailers!
+ @tail ||= @fields.size
+ return to_enum(:trailers!) unless block_given?
+
+ if @tail
+ @fields.drop(@tail).each(&block)
+ end
+ end
+
+ # Enumerate all trailers, if there are any.
+ def trailers(&block)
return to_enum(:trailers) unless block_given?
if @tail
@fields.drop(@tail).each(&block)
end