lib/http/response/io_body.rb
module HTTP class Response # A Body class that wraps an IO, rather than a the client # object. class IoBody include Enumerable extend Forwardable # @return [String,nil] the next `size` octets part of the # body, or nil if whole body has already been read. def readpartial(size = HTTP::Connection::BUFFER_SIZE) stream! return nil if stream.eof? stream.readpartial(size) end # Iterate over the body, allowing it to be enumerable def each while (part = readpartial) yield part end end # @return [String] eagerly consume the entire body as a string def to_s @contents ||= readall end alias_method :to_str, :to_s def_delegator :to_s, :empty? # Assert that the body is actively being streamed def stream! fail StateError, "body has already been consumed" if @streaming == false @streaming = true end # Easier to interpret string inspect def inspect "#<#{self.class}:#{object_id.to_s(16)} @streaming=#{!!@streaming}>" end protected def initialize(an_io) @streaming = nil @stream = an_io end attr_reader :contents, :stream def readall fail StateError, "body is being streamed" unless @streaming.nil? @streaming = false "".tap do |buf| buf << stream.read until stream.eof? end end end end end