Skip to content

Commit

Permalink
Ensure the connection stream is ended when closing the body.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Sep 18, 2024
1 parent cd57f8c commit bf0c622
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 3 deletions.
11 changes: 11 additions & 0 deletions lib/protocol/http1/body/chunked.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ def initialize(connection, headers)
@count = 0
end

attr :count

def length
# We only know the length once we've read everything. This is because the length is not known until the final chunk is read.
if @finished
@length
end
end

def empty?
@connection.nil?
end
Expand All @@ -34,6 +43,8 @@ def discard
unless @finished
connection.close_read
end

connection.receive_end_stream!
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/protocol/http1/body/fixed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def discard
if @remaining != 0
connection.close_read
end

connection.receive_end_stream!
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/protocol/http1/body/remainder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def discard

# Ensure no further requests can be read from the connection, as we are discarding the body which may not be fully read:
connection.close_read

connection.receive_end_stream!
end
end

Expand Down
21 changes: 18 additions & 3 deletions test/protocol/http1/body/chunked.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
body.close

expect(body).to be(:empty?)
expect(connection).to be(:half_closed_remote?)
end

it "invokes close_read on the stream if closing with an error" do
Expand All @@ -41,6 +42,7 @@
body.close(EOFError)

expect(body).to be(:empty?)
expect(connection).to be(:half_closed_remote?)
end
end

Expand All @@ -50,13 +52,19 @@
expect(body.read).to be == nil
expect(body.read).to be == nil

expect(connection).to have_attributes(state: be == :half_closed_remote)
expect(connection).to be(:half_closed_remote?)
end

it "updates number of bytes retrieved" do
body.read
body.read # realizes there are no more chunks
expect(body).to have_attributes(length: be_nil, count: be == 0)

expect(body.read).to be == "Hello World"
expect(body.read).to be_nil # there are no more chunks

expect(body).to have_attributes(length: be == 11, count: be == 1)

expect(body).to be(:empty?)
expect(connection).to be(:half_closed_remote?)
end

with "trailer" do
Expand All @@ -70,6 +78,8 @@

expect(body.read).to be == nil
expect(headers["etag"]).to be == "abcd"

expect(connection).to be(:half_closed_remote?)
end
end

Expand All @@ -83,6 +93,9 @@
expect(headers["etag"]).to be_nil

expect{body.read}.to raise_exception(Protocol::HTTP1::BadHeader)

body.close
expect(connection).to be(:half_closed_remote?)
end
end

Expand All @@ -91,6 +104,8 @@

it "raises error" do
expect{body.read}.to raise_exception(EOFError)

expect(connection).to be(:half_closed_remote?)
end
end
end
Expand Down
18 changes: 18 additions & 0 deletions test/protocol/http1/body/fixed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,25 @@
it "closes the stream" do
body.close(EOFError)
expect(buffer).to be(:closed?)

expect(connection).to be(:half_closed_remote?)
end

it "doesn't close the stream when EOF was reached" do
body.read
body.close(EOFError)
expect(buffer).not.to be(:closed?)

expect(connection).to be(:half_closed_remote?)
end
end

with "#read" do
it "retrieves chunks of content" do
expect(body.read).to be == "Hello World"
expect(body.read).to be == nil

expect(connection).to be(:half_closed_remote?)
end

it "updates number of bytes retrieved" do
Expand All @@ -54,11 +60,19 @@
it "retrieves content up to provided length" do
expect(body.read).to be == "Hello"
expect(body.read).to be == nil

expect(connection).to be(:half_closed_remote?)
end

it "updates number of bytes retrieved" do
expect(body).to have_attributes(remaining: be == body.length)

body.read

expect(body).to have_attributes(remaining: be == 0)
expect(body).to be(:empty?)

expect(connection).to be(:half_closed_remote?)
end
end

Expand Down Expand Up @@ -89,6 +103,8 @@
length: be == chunk.bytesize,
remaining: be == 0
)

expect(connection).to be(:half_closed_remote?)
end
end

Expand All @@ -99,6 +115,8 @@
expect do
body.read
end.to raise_exception(EOFError)

expect(connection).to be(:half_closed_remote?)
end
end
end
10 changes: 10 additions & 0 deletions test/protocol/http1/body/remainder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@
it "closes the stream" do
body.close(EOFError)
expect(buffer).to be(:closed?)

expect(connection).to be(:half_closed_remote?)
end

it "closes the stream when EOF was reached" do
body.read
body.close(EOFError)
expect(buffer).to be(:closed?)

expect(connection).to be(:half_closed_remote?)
end
end

Expand All @@ -45,6 +49,8 @@
expect(body.read).to be == nil

expect(body).to be(:empty?)

expect(connection).to be(:half_closed_remote?)
end
end

Expand All @@ -53,6 +59,8 @@
stream = StringIO.new
body.call(stream)
expect(stream.string).to be == "Hello World"

expect(connection).to be(:half_closed_remote?)
end
end

Expand All @@ -63,6 +71,8 @@
expect(body.join).to be == "Hello World"

expect(body).to be(:empty?)

expect(connection).to be(:half_closed_remote?)
end
end
end

0 comments on commit bf0c622

Please sign in to comment.