Skip to content

Commit 06baa24

Browse files
committed
Improved documentation for Protocol::HTTP::Headers.
1 parent d16c545 commit 06baa24

File tree

1 file changed

+76
-19
lines changed

1 file changed

+76
-19
lines changed

lib/protocol/http/headers.rb

+76-19
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Headers
2525
TRAILER = "trailer"
2626

2727
# 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.
28+
#
2829
# @return [Headers] an instance of headers.
2930
def self.[] headers
3031
if headers.nil?
@@ -48,6 +49,10 @@ def self.[] headers
4849
return self.new(fields)
4950
end
5051

52+
# Initialize the headers with the specified fields.
53+
#
54+
# @parameter fields [Array] An array of `[key, value]` pairs.
55+
# @parameter indexed [Hash] A hash table of normalized headers, if available.
5156
def initialize(fields = [], indexed = nil)
5257
@fields = fields
5358
@indexed = indexed
@@ -56,20 +61,24 @@ def initialize(fields = [], indexed = nil)
5661
@tail = nil
5762
end
5863

64+
# Initialize a copy of the headers.
65+
#
66+
# @parameter other [Headers] The headers to copy.
5967
def initialize_dup(other)
6068
super
6169

6270
@fields = @fields.dup
6371
@indexed = @indexed.dup
6472
end
6573

74+
# Clear all headers.
6675
def clear
6776
@fields.clear
6877
@indexed = nil
6978
@tail = nil
7079
end
7180

72-
# Flatten trailer into the headers.
81+
# Flatten trailer into the headers, in-place.
7382
def flatten!
7483
if @tail
7584
self.delete(TRAILER)
@@ -79,29 +88,27 @@ def flatten!
7988
return self
8089
end
8190

91+
# Flatten trailer into the headers, returning a new instance of {Headers}.
8292
def flatten
8393
self.dup.flatten!
8494
end
8595

86-
# An array of `[key, value]` pairs.
96+
# @attribute [Array] An array of `[key, value]` pairs.
8797
attr :fields
8898

89-
# @returns Whether there are any trailers.
99+
# @returns [Boolean] Whether there are any trailers.
90100
def trailer?
91101
@tail != nil
92102
end
93103

94104
# Record the current headers, and prepare to add trailers.
95105
#
96-
# This method is typically used after headers are sent to capture any
97-
# additional headers which should then be sent as trailers.
106+
# This method is typically used after headers are sent to capture any additional headers which should then be sent as trailers.
98107
#
99-
# A sender that intends to generate one or more trailer fields in a
100-
# message should generate a trailer header field in the header section of
101-
# that message to indicate which fields might be present in the trailers.
108+
# A sender that intends to generate one or more trailer fields in a message should generate a trailer header field in the header section of that message to indicate which fields might be present in the trailers.
102109
#
103110
# @parameter names [Array] The trailer header names which will be added later.
104-
# @yields block {|name, value| ...} The trailer headers if any.
111+
# @yields {|name, value| ...} the trailing headers if a block is given.
105112
# @returns An enumerator which is suitable for iterating over trailers.
106113
def trailer!(&block)
107114
@tail ||= @fields.size
@@ -118,6 +125,7 @@ def trailer(&block)
118125
end
119126
end
120127

128+
# Freeze the headers, and ensure the indexed hash is generated.
121129
def freeze
122130
return if frozen?
123131

@@ -130,24 +138,35 @@ def freeze
130138
super
131139
end
132140

141+
# @returns [Boolean] Whether the headers are empty.
133142
def empty?
134143
@fields.empty?
135144
end
136145

146+
# Enumerate all header keys and values.
147+
#
148+
# @yields {|key, value| ...}
149+
# @parameter key [String] The header key.
150+
# @parameter value [String] The header value.
137151
def each(&block)
138152
@fields.each(&block)
139153
end
140154

155+
# @returns [Boolean] Whether the headers include the specified key.
141156
def include? key
142157
self[key] != nil
143158
end
144159

145160
alias key? include?
146161

162+
# @returns [Array] All the keys of the headers.
147163
def keys
148164
self.to_h.keys
149165
end
150166

167+
# Extract the specified keys from the headers.
168+
#
169+
# @parameter keys [Array] The keys to extract.
151170
def extract(keys)
152171
deleted, @fields = @fields.partition do |field|
153172
keys.include?(field.first.downcase)
@@ -164,21 +183,23 @@ def extract(keys)
164183

165184
# Add the specified header key value pair.
166185
#
167-
# @param key [String] the header key.
168-
# @param value [String] the header value to assign.
186+
# @parameter key [String] the header key.
187+
# @parameter value [String] the header value to assign.
169188
def add(key, value)
170189
self[key] = value
171190
end
172191

173192
# Set the specified header key to the specified value, replacing any existing header keys with the same name.
174-
# @param key [String] the header key to replace.
175-
# @param value [String] the header value to assign.
193+
#
194+
# @parameter key [String] the header key to replace.
195+
# @parameter value [String] the header value to assign.
176196
def set(key, value)
177197
# TODO This could be a bit more efficient:
178198
self.delete(key)
179199
self.add(key, value)
180200
end
181201

202+
# Merge the headers into this instance.
182203
def merge!(headers)
183204
headers.each do |key, value|
184205
self[key] = value
@@ -187,13 +208,15 @@ def merge!(headers)
187208
return self
188209
end
189210

211+
# Merge the headers into a new instance of {Headers}.
190212
def merge(headers)
191213
self.dup.merge!(headers)
192214
end
193215

194216
# Append the value to the given key. Some values can be appended multiple times, others can only be set once.
195-
# @param key [String] The header key.
196-
# @param value The header value.
217+
#
218+
# @parameter key [String] The header key.
219+
# @parameter value [String] The header value.
197220
def []= key, value
198221
if @indexed
199222
merge_into(@indexed, key.downcase, value)
@@ -202,8 +225,9 @@ def []= key, value
202225
@fields << [key, value]
203226
end
204227

228+
# The policy for various headers, including how they are merged and normalized.
205229
POLICY = {
206-
# Headers which may only be specified once.
230+
# Headers which may only be specified once:
207231
"content-type" => false,
208232
"content-disposition" => false,
209233
"content-length" => false,
@@ -251,7 +275,10 @@ def []= key, value
251275
"if-unmodified-since" => Header::Date,
252276
}.tap{|hash| hash.default = Split}
253277

254-
# Delete all headers with the given key, and return the merged value.
278+
# Delete all header values for the given key, and return the merged value.
279+
#
280+
# @parameter key [String] The header key.
281+
# @returns [String | Array | Object] The merged header value.
255282
def delete(key)
256283
deleted, @fields = @fields.partition do |field|
257284
field.first.downcase == key
@@ -276,6 +303,11 @@ def delete(key)
276303
end
277304
end
278305

306+
# Merge the value into the hash according to the policy for the given key.
307+
#
308+
# @parameter hash [Hash] The hash to merge into.
309+
# @parameter key [String] The header key.
310+
# @parameter value [String] The raw header value.
279311
protected def merge_into(hash, key, value)
280312
if policy = POLICY[key]
281313
if current_value = hash[key]
@@ -289,11 +321,17 @@ def delete(key)
289321
end
290322
end
291323

324+
# Get the value of the specified header key.
325+
#
326+
# @parameter key [String] The header key.
327+
# @returns [String | Array | Object] The header value.
292328
def [] key
293329
to_h[key]
294330
end
295331

296-
# A hash table of `{key, policy[key].map(values)}`
332+
# Compute a hash table of headers, where the keys are normalized to lower case and the values are normalized according to the policy for that header.
333+
#
334+
# @returns [Hash] A hash table of `{key, value}` pairs.
297335
def to_h
298336
@indexed ||= @fields.inject({}) do |hash, (key, value)|
299337
merge_into(hash, key.downcase, value)
@@ -304,10 +342,16 @@ def to_h
304342

305343
alias as_json to_h
306344

345+
# Inspect the headers.
346+
#
347+
# @returns [String] A string representation of the headers.
307348
def inspect
308349
"#<#{self.class} #{@fields.inspect}>"
309350
end
310351

352+
# Compare this object to another object. May depend on the order of the fields.
353+
#
354+
# @returns [Boolean] Whether the other object is equal to this one.
311355
def == other
312356
case other
313357
when Hash
@@ -323,29 +367,42 @@ def == other
323367
class Merged
324368
include Enumerable
325369

370+
# Construct a merged list of headers.
371+
#
372+
# @parameter *all [Array] An array of all headers to merge.
326373
def initialize(*all)
327374
@all = all
328375
end
329376

377+
# @returns [Array] A list of all headers, in the order they were added, as `[key, value]` pairs.
330378
def fields
331379
each.to_a
332380
end
333381

382+
# @returns [Headers] A new instance of {Headers} containing all the merged headers.
334383
def flatten
335384
Headers.new(fields)
336385
end
337386

387+
# Clear the references to all headers.
338388
def clear
339389
@all.clear
340390
end
341391

392+
# Add a new set of headers to the merged list.
393+
#
394+
# @parameter headers [Headers | Array | Hash] A list of headers to add.
342395
def << headers
343396
@all << headers
344397

345398
return self
346399
end
347400

348-
# @yields [String, String] header key (lower case string) and value (as string).
401+
# Enumerate all headers in the merged list.
402+
#
403+
# @yields {|key, value| ...} The header key and value.
404+
# @parameter key [String] The header key (lower case).
405+
# @parameter value [String] The header value.
349406
def each(&block)
350407
return to_enum unless block_given?
351408

0 commit comments

Comments
 (0)