diff --git a/lib/protocol/http1/body/chunked.rb b/lib/protocol/http1/body/chunked.rb index a10e5fd..2c8b19e 100644 --- a/lib/protocol/http1/body/chunked.rb +++ b/lib/protocol/http1/body/chunked.rb @@ -128,7 +128,7 @@ def read connection.close_read end - raise EOFError, "Connection closed before expected length was read!" + raise end # @returns [String] a human-readable representation of the body. @@ -149,7 +149,7 @@ def as_json(...) # Read the trailer from the connection, and add any headers to the trailer. def read_trailer - while line = @connection.read_line? + while line = @connection.read_line # Empty line indicates end of trailer: break if line.empty? diff --git a/releases.md b/releases.md index 9fa16ca..e73c854 100644 --- a/releases.md +++ b/releases.md @@ -1,5 +1,9 @@ # Releases +## Unreleased + + - Handle unexpected EOF while reading chunked trailers. + ## v0.40.1 - Bound fixed-length and chunked body reads, and validate chunk terminators. diff --git a/test/protocol/http1/body/chunked.rb b/test/protocol/http1/body/chunked.rb index 25003b8..3d4580f 100644 --- a/test/protocol/http1/body/chunked.rb +++ b/test/protocol/http1/body/chunked.rb @@ -128,6 +128,16 @@ end end + with "incomplete trailer" do + let(:buffer) {StringIO.new("0\r\n")} + + it "raises EOFError when the final CRLF is missing" do + expect{body.read}.to raise_exception(EOFError) + + expect(connection).to be(:half_closed_remote?) + end + end + with "bad trailers" do let(:postfix) {":ETag abcd\r\n"}