lib/async/http/body.rb in async-http-0.14.0 vs lib/async/http/body.rb in async-http-0.15.0

- old
+ new

@@ -24,28 +24,38 @@ module HTTP class Body < Async::Queue def initialize super - @closed = false + @finished = false end - def closed? - @closed + def finished? + @finished end def each - return if @closed + return if @finished while chunk = self.dequeue yield chunk end - @closed = true + @finished = true end def read + return if @finished + + unless chunk = self.dequeue + @finished = true + end + + return chunk + end + + def join buffer = Async::IO::BinaryString.new self.each do |chunk| buffer << chunk end @@ -57,86 +67,160 @@ def write(chunk) self.enqueue(chunk) end - def close + def finish self.enqueue(nil) end end class BufferedBody def initialize(body) @chunks = [] + @index = 0 body.each do |chunk| @chunks << chunk end end def each(&block) - @chunks.each(&block) + while @index < @chunks.count + yield @chunks[@index] + @index += 1 + end end def read - @buffer ||= @chunks.join + if chunk = @chunks[@index] + @index += 1 + end + + return chunk end - alias join read + def join + buffer = Async::IO::BinaryString.new + + self.each do |chunk| + buffer << chunk + end + + return buffer + end - def closed? + def rewind + @index = 0 + end + + def finished? true end module Reader def read - self.body ? self.body.read : nil + self.body ? self.body.join : nil end - def close - return if self.body.nil? or self.body.closed? + def finish + return if self.body.nil? or self.body.finished? unless self.body.is_a? BufferedBody self.body = BufferedBody.new(self.body) end end end end - class FixedBody - CHUNK_LENGTH = 1024*1024 + class ChunkedBody + def initialize(protocol) + @protocol = protocol + @finished = false + end + def finished? + @finished + end + + def read + return nil if @finished + + size = @protocol.read_line.to_i(16) + + if size == 0 + @protocol.read_line + + @finished = true + + return nil + end + + chunk = @protocol.stream.read(size) + @protocol.read_line # Consume the trailing CRLF + + return chunk + end + + def each + while chunk = self.read + yield chunk + end + end + + def join + buffer = Async::IO::BinaryString.new + + self.each do |chunk| + buffer << chunk + end + + return buffer + end + + def finish + self.each {} + end + end + + class FixedBody def initialize(length, stream) @length = length @remaining = length @stream = stream end - def closed? + def finished? @remaining == 0 end def each - while @remaining > 0 - if chunk = @stream.read(CHUNK_LENGTH) + while chunk = self.read + yield chunk + end + end + + def read + if @remaining > 0 + if chunk = @stream.read(@remaining) @remaining -= chunk.bytesize - yield chunk + return chunk end end end - def read + def join buffer = @stream.read(@remaining) @remaining = 0 return buffer end alias join read - def close + def finish read end end end end