class 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.
Nested
Definitions
NEWLINE = "\n"
The default line separator, used by gets
.
def initialize(input = nil, output = Buffered.new)
Initialize the stream with the given input and output.
Signature
-
parameter
input
Readable
The input stream.
-
parameter
output
Writable
The output stream.
Implementation
def initialize(input = nil, output = Buffered.new)
@input = input
@output = output
raise ArgumentError, "Non-writable output!" unless output.respond_to?(:write)
# Will hold remaining data in `#read`.
@buffer = nil
@closed = false
@closed_read = false
end
attr :input
Signature
-
attribute
Readable
The input stream.
attr :output
Signature
-
attribute
Writable
The output stream.
def write(buffer)
Write data to the underlying stream.
Signature
-
parameter
buffer
String
The data to write.
-
raises
IOError
If the stream is not writable.
-
returns
Integer
The number of bytes written.
Implementation
def write(buffer)
if @output
@output.write(buffer)
return buffer.bytesize
else
raise IOError, "Stream is not writable, output has been closed!"
end
end
def write_nonblock(buffer, exception: nil)
Write data to the stream using Protocol::HTTP::Body::Stream#write
.
Provided for compatibility with IO-like objects.
Signature
-
parameter
buffer
String
The data to write.
-
parameter
exception
Boolean
Whether to raise an exception if the write would block, currently ignored.
-
returns
Integer
The number of bytes written.
Implementation
def write_nonblock(buffer, exception: nil)
write(buffer)
end
def <<(buffer)
Write data to the stream using Protocol::HTTP::Body::Stream#write
.
Implementation
def <<(buffer)
write(buffer)
end
def puts(*arguments, separator: NEWLINE)
Write lines to the stream.
The current implementation buffers the lines and writes them in a single operation.
Signature
-
parameter
arguments
Array(String)
The lines to write.
-
parameter
separator
String
The line separator, defaults to
\n
.
Implementation
def puts(*arguments, separator: NEWLINE)
buffer = ::String.new
arguments.each do |argument|
buffer << argument << separator
end
write(buffer)
end
def flush
Flush the output stream.
This is currently a no-op.
Implementation
def flush
end
def close_read(error = nil)
Close the input body.
If, while processing the data that was read from this stream, an error is encountered, it should be passed to this method.
Signature
-
parameter
error
Exception | Nil
The error that was encountered, if any.
Implementation
def close_read(error = nil)
if input = @input
@input = nil
@closed_read = true
@buffer = nil
input.close(error)
end
end
def close_write(error = nil)
Close the output body.
If, while generating the data that is written to this stream, an error is encountered, it should be passed to this method.
Signature
-
parameter
error
Exception | Nil
The error that was encountered, if any.
Implementation
def close_write(error = nil)
if output = @output
@output = nil
output.close_write(error)
end
end
def close(error = nil)
Close the input and output bodies.
Signature
-
parameter
error
Exception | Nil
The error that caused this stream to be closed, if any.
Implementation
def close(error = nil)
self.close_read(error)
self.close_write(error)
return nil
ensure
@closed = true
end
def closed?
Signature
-
returns
Boolean
Whether the stream has been closed.
Implementation
def closed?
@closed
end
def empty?
Signature
-
returns
Boolean
Whether there are any output chunks remaining.
Implementation
def empty?
@output.empty?
end
def read_next
Read the next chunk of data from the input stream.
Signature
-
returns
String
The next chunk of data.
-
raises
IOError
If the input stream was explicitly closed.
Implementation
def read_next
if @input
return @input.read
elsif @closed_read
raise IOError, "Stream is not readable, input has been closed!"
end
end