Skip to content

Commit 213fec7

Browse files
Expanded interface Head.for(body, length) to support nil body and optional length. (#83)
1 parent fd9d606 commit 213fec7

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

lib/protocol/http/body/head.rb

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,24 @@ module Body
1212
# Represents a body suitable for HEAD requests, in other words, a body that is empty and has a known length.
1313
class Head < Readable
1414
# Create a head body for the given body, capturing its length and then closing it.
15-
def self.for(body)
16-
head = self.new(body.length)
17-
18-
body.close
15+
#
16+
# If a body is provided, the length is determined from the body, and the body is closed.
17+
# If no body is provided, and the content length is provided, a head body is created with that length.
18+
# This is useful for creating a head body when you only know the content length but not the actual body, which may happen in adapters for HTTP applications where the application may not provide a body for HEAD requests, but the content length is known.
19+
#
20+
# @parameter body [Readable | Nil] the body to create a head for.
21+
# @parameter length [Integer | Nil] the content length of the body, if known.
22+
# @returns [Head | Nil] the head body, or nil if the body is nil.
23+
def self.for(body, length = nil)
24+
if body
25+
head = self.new(body.length)
26+
body.close
27+
return head
28+
elsif length
29+
return self.new(length)
30+
end
1931

20-
return head
32+
return nil
2133
end
2234

2335
# Initialize the head body with the given length.

releases.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- `Protocol::HTTP::Headers` now raise a `DuplicateHeaderError` when a duplicate singleton header (e.g. `content-length`) is added.
66
- `Protocol::HTTP::Headers#add` now coerces the value to a string when adding a header, ensuring consistent behaviour.
7+
- `Protocol::HTTP::Body::Head.for` now accepts an optional `length` parameter, allowing it to create a head body even when the body is not provided, based on the known content length.
78

89
## v0.50.0
910

test/protocol/http/body/head.rb

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,33 @@
4646
end
4747

4848
with ".for" do
49-
let(:source) {Protocol::HTTP::Body::Buffered.wrap("!")}
50-
let(:body) {subject.for(source)}
49+
with "body" do
50+
let(:source) {Protocol::HTTP::Body::Buffered.wrap("!")}
51+
let(:body) {subject.for(source)}
52+
53+
it "captures length and closes existing body" do
54+
expect(source).to receive(:close)
55+
56+
expect(body).to have_attributes(length: be == 1)
57+
body.close
58+
end
59+
end
5160

52-
it "captures length and closes existing body" do
53-
expect(source).to receive(:close)
61+
with "content length" do
62+
let(:body) {subject.for(nil, 42)}
5463

55-
expect(body).to have_attributes(length: be == 1)
56-
body.close
64+
it "uses the content length if no body is provided" do
65+
expect(body).to have_attributes(length: be == 42)
66+
expect(body).to be(:empty?)
67+
expect(body).to be(:ready?)
68+
end
69+
end
70+
end
71+
72+
with ".for with nil body" do
73+
it "returns nil when body is nil" do
74+
body = subject.for(nil)
75+
expect(body).to be_nil
5776
end
5877
end
5978
end

0 commit comments

Comments
 (0)