class Protocol::HTTP::Body::Stream

The input stream is an IO-like object which contains the raw HTTP POST data. When applicable, its external encoding must be “ASCII-8BIT” and it must be opened in binary mode, for Ruby 1.9 compatibility. The input stream must respond to gets, each, read and rewind.

Attributes

input[R]
output[R]

Public Class Methods

new(input, output) click to toggle source
# File lib/protocol/http/body/stream.rb, line 28
def initialize(input, output)
        @input = input
        @output = output
        
        # Will hold remaining data in `#read`.
        @buffer = nil
        @closed = false
end

Public Instance Methods

close() click to toggle source

Close the input and output bodies.

# File lib/protocol/http/body/stream.rb, line 115
def close
        self.close_read
        self.close_write
ensure
        @closed = true
end
close_read() click to toggle source
# File lib/protocol/http/body/stream.rb, line 105
def close_read
        @input&.close
end
close_write() click to toggle source

close must never be called on the input stream. huh?

# File lib/protocol/http/body/stream.rb, line 110
def close_write
        @output&.close
end
closed?() click to toggle source

Whether the stream has been closed.

# File lib/protocol/http/body/stream.rb, line 123
def closed?
        @closed
end
empty?() click to toggle source

Whether there are any output chunks remaining?

# File lib/protocol/http/body/stream.rb, line 128
def empty?
        @output.empty?
end
flush() click to toggle source
# File lib/protocol/http/body/stream.rb, line 102
def flush
end
read(length = nil, buffer = nil) click to toggle source

read behaves like IO#read. Its signature is read([length, [buffer]]). If given, length must be a non-negative Integer (>= 0) or nil, and buffer must be a String and may not be nil. If length is given and not nil, then this method reads at most length bytes from the input stream. If length is not given or nil, then this method reads all data until EOF. When EOF is reached, this method returns nil if length is given and not nil, or “” if length is not given or is nil. If buffer is given, then the read data will be placed into buffer instead of a newly created String object. @param length [Integer] the amount of data to read @param buffer [String] the buffer which will receive the data @return a buffer containing the data

# File lib/protocol/http/body/stream.rb, line 47
def read(length = nil, buffer = nil)
        buffer ||= Async::IO::Buffer.new
        buffer.clear
        
        until buffer.bytesize == length
                @buffer = read_next if @buffer.nil?
                break if @buffer.nil?
                
                remaining_length = length - buffer.bytesize if length
                
                if remaining_length && remaining_length < @buffer.bytesize
                        # We know that we are not going to reuse the original buffer.
                        # But byteslice will generate a hidden copy. So let's freeze it first:
                        @buffer.freeze
                        
                        buffer << @buffer.byteslice(0, remaining_length)
                        @buffer = @buffer.byteslice(remaining_length, @buffer.bytesize)
                else
                        buffer << @buffer
                        @buffer = nil
                end
        end
        
        return nil if buffer.empty? && length && length > 0
        
        return buffer
end
read_nonblock(length, buffer = nil) click to toggle source
# File lib/protocol/http/body/stream.rb, line 75
def read_nonblock(length, buffer = nil)
        @buffer ||= read_next
        chunk = nil
        
        if @buffer.bytesize > length
                chunk = @buffer.byteslice(0, length)
                @buffer = @buffer.byteslice(length, @buffer.bytesize)
        else
                chunk = @buffer
                @buffer = nil
        end
        
        if buffer
                buffer.replace(chunk)
        else
                buffer = chunk
        end
        
        return buffer
end
write(buffer) click to toggle source
# File lib/protocol/http/body/stream.rb, line 96
def write(buffer)
        @output.write(buffer)
end
Also aliased as: write_nonblock
write_nonblock(buffer)
Alias for: write

Private Instance Methods

read_next() click to toggle source
# File lib/protocol/http/body/stream.rb, line 134
def read_next
        if chunk = @input&.read
                return chunk
        else
                @input = nil
                return nil
        end
end