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