Skip to content

Commit 220222f

Browse files
authored
Fix handling of rewind after reading all input. (#24)
1 parent e6a9c46 commit 220222f

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

lib/protocol/rack/input.rb

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ def rewind
6464
if @body and @body.respond_to?(:rewind)
6565
# If the body is not rewindable, this will fail.
6666
@body.rewind
67+
6768
@buffer = nil
6869
@finished = false
70+
@closed = false
6971

7072
return true
7173
end
@@ -93,14 +95,18 @@ def read_next
9395
# https://github.com/socketry/async-http/issues/183
9496
if @body.empty?
9597
@body.close
96-
@body = nil
98+
@closed = true
9799
end
98100

99101
return chunk
100102
else
101-
# So if we are at the end of the stream, we close it automatically:
102-
@body.close
103-
@body = nil
103+
unless @closed
104+
# So if we are at the end of the stream, we close it automatically:
105+
@body.close
106+
@closed = true
107+
end
108+
109+
return nil
104110
end
105111
elsif @closed
106112
raise IOError, "Stream is not readable, input has been closed!"

test/protocol/rack/input.rb

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,17 @@
4949
expect(input.read).to be == sample_data.join
5050
expect(input.read).to be == ""
5151

52-
expect(input.body).to be_nil
52+
expect(input).to be(:closed?)
53+
end
54+
55+
it "can rewind after reading all input" do
56+
expect(input.read).to be == sample_data.join
57+
expect(input).to be(:closed?)
58+
59+
input.rewind
60+
61+
expect(input).not.to be(:closed?)
62+
expect(input.read).to be == sample_data.join
5363
end
5464

5565
it "can read exactly the content length" do
@@ -69,13 +79,23 @@
6979
expect(input.read(3)).to be == "row"
7080
end
7181

82+
it "can rewind after reading partial input" do
83+
expect(input.read(3)).to be == "The"
84+
expect(input).not.to be(:closed?)
85+
86+
input.rewind
87+
88+
expect(input).not.to be(:closed?)
89+
expect(input.read(3)).to be == "The"
90+
end
91+
7292
it "can read all input" do
7393
expect(input.read(15)).to be == sample_data.join[0...15]
7494
expect(input.read).to be == sample_data.join[15..-1]
7595

7696
expect(input.read(1)).to be == nil
7797

78-
expect(input.body).to be_nil
98+
expect(input).to be(:closed?)
7999
end
80100

81101
it "can read partial input with buffer" do

0 commit comments

Comments
 (0)