lib/protocol/http1/body/chunked.rb in protocol-http1-0.21.0 vs lib/protocol/http1/body/chunked.rb in protocol-http1-0.22.0
- old
+ new
@@ -1,9 +1,9 @@
# frozen_string_literal: true
# Released under the MIT License.
-# Copyright, 2019-2023, by Samuel Williams.
+# Copyright, 2019-2024, by Samuel Williams.
# Copyright, 2023, by Thomas Morgan.
require 'protocol/http/body/readable'
module Protocol
@@ -21,55 +21,65 @@
@length = 0
@count = 0
end
def empty?
- @finished
+ @stream.nil?
end
def close(error = nil)
- # We only close the connection if we haven't completed reading the entire body:
- unless @finished
- @stream.close
- @finished = true
+ if @stream
+ # We only close the connection if we haven't completed reading the entire body:
+ unless @finished
+ @stream.close_read
+ end
+
+ @stream = nil
end
super
end
VALID_CHUNK_LENGTH = /\A[0-9a-fA-F]+\z/
# Follows the procedure outlined in https://tools.ietf.org/html/rfc7230#section-4.1.3
def read
- return nil if @finished
-
- length, _extensions = read_line.split(";", 2)
-
- unless length =~ VALID_CHUNK_LENGTH
- raise BadRequest, "Invalid chunk length: #{length.inspect}"
- end
-
- # It is possible this line contains chunk extension, so we use `to_i` to only consider the initial integral part:
- length = Integer(length, 16)
-
- if length == 0
- @finished = true
+ if !@finished
+ if @stream
+ length, _extensions = read_line.split(";", 2)
+
+ unless length =~ VALID_CHUNK_LENGTH
+ raise BadRequest, "Invalid chunk length: #{length.inspect}"
+ end
+
+ # It is possible this line contains chunk extension, so we use `to_i` to only consider the initial integral part:
+ length = Integer(length, 16)
+
+ if length == 0
+ read_trailer
+
+ # The final chunk has been read and the stream is now closed:
+ @stream = nil
+ @finished = true
+
+ return nil
+ end
+
+ # Read trailing CRLF:
+ chunk = @stream.read(length + 2)
+
+ # ...and chomp it off:
+ chunk.chomp!(CRLF)
+
+ @length += length
+ @count += 1
+
+ return chunk
+ end
- read_trailer
-
- return nil
+ # If the stream has been closed before we have read the final chunk, raise an error:
+ raise EOFError, "Stream closed before expected length was read!"
end
-
- # Read trailing CRLF:
- chunk = @stream.read(length + 2)
-
- # ...and chomp it off:
- chunk.chomp!(CRLF)
-
- @length += length
- @count += 1
-
- return chunk
end
def inspect
"\#<#{self.class} #{@length} bytes read in #{@count} chunks>"
end