Class: Protocol::HTTP::Body::Stream
- Inherits:
-
Object
- Object
- Protocol::HTTP::Body::Stream
- Includes:
- Reader
- Defined in:
- lib/protocol/http/body/stream.rb
Overview
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.
Defined Under Namespace
Modules: Reader
Constant Summary collapse
- NEWLINE =
The default line separator, used by Reader#gets.
"\n"
Instance Attribute Summary collapse
-
#input ⇒ Object
readonly
Returns the value of attribute input.
-
#output ⇒ Object
readonly
Returns the value of attribute output.
- #The output stream.(outputstream.) ⇒ Object readonly
Instance Method Summary collapse
-
#<<(buffer) ⇒ Object
Write data to the stream using #write.
-
#close(error = nil) ⇒ Object
Close the input and output bodies.
-
#close_read(error = nil) ⇒ Object
Close the application-facing input body.
-
#close_write(error = nil) ⇒ Object
Close the application-facing output body.
- #closed? ⇒ Boolean
- #empty? ⇒ Boolean
-
#flush ⇒ Object
Flush the output stream.
-
#initialize(input = nil, output = nil) ⇒ Stream
constructor
Initialize the stream with the given input and output.
-
#inspect ⇒ Object
Inspect the stream.
-
#puts(*arguments, separator: NEWLINE) ⇒ Object
Write lines to the stream.
- #The input stream.=(inputstream. = (value)) ⇒ Object
-
#write(buffer) ⇒ Object
Write data to the underlying stream.
-
#write_nonblock(buffer, exception: nil) ⇒ Object
Write data to the stream using #write.
Methods included from Reader
#each, #gets, #read, #read_nonblock, #read_partial, #read_until, #readpartial
Constructor Details
#initialize(input = nil, output = nil) ⇒ Stream
Initialize the stream with the given input and output.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/protocol/http/body/stream.rb', line 20 def initialize(input = nil, output = nil) @input = input @output = output if @output raise ArgumentError, "Non-writable output!" unless output.respond_to?(:write) end # Will hold remaining data in `#read`. @buffer = nil @closed = false @closed_read = false end |
Instance Attribute Details
#input ⇒ Object (readonly)
Returns the value of attribute input.
36 37 38 |
# File 'lib/protocol/http/body/stream.rb', line 36 def input @input end |
#output ⇒ Object (readonly)
Returns the value of attribute output.
39 40 41 |
# File 'lib/protocol/http/body/stream.rb', line 39 def output @output end |
#The output stream.(outputstream.) ⇒ Object (readonly)
39 |
# File 'lib/protocol/http/body/stream.rb', line 39 attr :output |
Instance Method Details
#<<(buffer) ⇒ Object
Write data to the stream using #write.
324 325 326 |
# File 'lib/protocol/http/body/stream.rb', line 324 def << buffer write(buffer) end |
#close(error = nil) ⇒ Object
Close the input and output bodies.
Closing without an error represents orderly completion or abandonment of both application-facing directions, not cancellation. If the peer has not completed the exchange, the protocol implementation may need to terminate it without reporting an application error.
Repeated calls are safe; each underlying direction will be closed at most once.
395 396 397 398 399 400 401 402 |
# File 'lib/protocol/http/body/stream.rb', line 395 def close(error = nil) self.close_read(error) self.close_write(error) return nil ensure @closed = true end |
#close_read(error = nil) ⇒ Object
Close the application-facing input body. This does not close the output body, which may continue to be written independently.
If the input has not reached end-of-file, any remaining data is abandoned. The protocol implementation must ensure that unread data cannot interfere with subsequent exchanges. Depending on the protocol, it may discard the remaining data, terminate the current exchange, or make the connection non-reusable.
Closing without an error represents orderly application-level abandonment, not a protocol failure.
This method is idempotent. After the first call, subsequent calls have no effect.
If, while processing the data that was read from this stream, an error is encountered, it should be passed to this method.
361 362 363 364 365 366 367 368 369 |
# File 'lib/protocol/http/body/stream.rb', line 361 def close_read(error = nil) if input = @input @input = nil @closed_read = true @buffer = nil input.close(error) end end |
#close_write(error = nil) ⇒ Object
Close the application-facing output body. This does not close the input body, which may continue to be read independently.
Closing without an error indicates that no more output will be produced. Previously written data remains part of the output and should be followed by a normal end-of-stream from the protocol implementation. If an error is provided, the protocol implementation may terminate the exchange instead.
This method is idempotent. After the first call, subsequent calls have no effect.
If, while generating the data that is written to this stream, an error is encountered, it should be passed to this method.
380 381 382 383 384 385 386 |
# File 'lib/protocol/http/body/stream.rb', line 380 def close_write(error = nil) if output = @output @output = nil output.close_write(error) end end |
#closed? ⇒ Boolean
405 406 407 |
# File 'lib/protocol/http/body/stream.rb', line 405 def closed? @closed end |
#empty? ⇒ Boolean
425 426 427 428 429 430 431 |
# File 'lib/protocol/http/body/stream.rb', line 425 def empty? if @output return @output.empty? else return true end end |
#flush ⇒ Object
Flush the output stream.
This is currently a no-op.
347 348 |
# File 'lib/protocol/http/body/stream.rb', line 347 def flush end |
#inspect ⇒ Object
Inspect the stream.
412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/protocol/http/body/stream.rb', line 412 def inspect buffer_info = @buffer ? "#{@buffer.bytesize} bytes buffered" : "no buffer" status = [] status << "closed" if @closed status << "read-closed" if @closed_read status_info = status.empty? ? "open" : status.join(", ") return "#<#{self.class} #{buffer_info}, #{status_info}>" end |
#puts(*arguments, separator: NEWLINE) ⇒ Object
Write lines to the stream.
The current implementation buffers the lines and writes them in a single operation.
334 335 336 337 338 339 340 341 342 |
# File 'lib/protocol/http/body/stream.rb', line 334 def puts(*arguments, separator: NEWLINE) buffer = ::String.new arguments.each do |argument| buffer << argument << separator end write(buffer) end |
#The input stream.=(inputstream. = (value)) ⇒ Object
36 |
# File 'lib/protocol/http/body/stream.rb', line 36 attr :input |
#write(buffer) ⇒ Object
Write data to the underlying stream.
303 304 305 306 307 308 309 310 |
# File 'lib/protocol/http/body/stream.rb', line 303 def write(buffer) if @output @output.write(buffer) return buffer.bytesize else raise IOError, "Stream is not writable, output has been closed!" end end |
#write_nonblock(buffer, exception: nil) ⇒ Object
Write data to the stream using #write.
Provided for compatibility with IO-like objects.
319 320 321 |
# File 'lib/protocol/http/body/stream.rb', line 319 def write_nonblock(buffer, exception: nil) write(buffer) end |