Class: Protocol::HTTY::Stream
- Inherits:
-
Object
- Object
- Protocol::HTTY::Stream
- Defined in:
- lib/protocol/htty/stream.rb
Overview
Transport an opaque byte stream after the HTTY bootstrap handshake.
Constant Summary collapse
Instance Attribute Summary collapse
-
#input ⇒ Object
readonly
Returns the value of attribute input.
-
#output ⇒ Object
readonly
Returns the value of attribute output.
Class Method Summary collapse
Instance Method Summary collapse
-
#close_write(error = nil) ⇒ Object
(also: #close)
Close the local write side of this stream abstraction.
-
#closed? ⇒ Boolean
Check whether the local side of the transport is closed.
-
#flush ⇒ Object
Flush any buffered output through the underlying stream.
-
#initialize(input, output) ⇒ Stream
constructor
Create a stream on top of raw byte-preserving endpoints.
-
#io ⇒ Object
Return the underlying output stream.
-
#read(length = nil) ⇒ Object
Read application bytes from the HTTY transport.
- #read_bootstrap ⇒ Object
-
#readable? ⇒ Boolean
Check whether the remote side may still provide more data.
-
#remote_address ⇒ Object
Required by Protocol::HTTP::Peer but not applicable to HTTY, which does not have a concept of remote addresses.
-
#write(data, flush: false) ⇒ Object
Write application bytes after bootstrap.
- #write_bootstrap(mode = RAW_MODE) ⇒ Object
Constructor Details
#initialize(input, output) ⇒ Stream
Create a stream on top of raw byte-preserving endpoints.
40 41 42 43 44 |
# File 'lib/protocol/htty/stream.rb', line 40 def initialize(input, output) @input = input @output = output @local_closed = false end |
Instance Attribute Details
#input ⇒ Object (readonly)
Returns the value of attribute input.
51 52 53 |
# File 'lib/protocol/htty/stream.rb', line 51 def input @input end |
#output ⇒ Object (readonly)
Returns the value of attribute output.
52 53 54 |
# File 'lib/protocol/htty/stream.rb', line 52 def output @output end |
Class Method Details
.open(input, output, bootstrap: nil, mode: RAW_MODE) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/protocol/htty/stream.rb', line 16 def self.open(input, output, bootstrap: nil, mode: RAW_MODE) stream = self.new(input, output) # Disable buffering: input.sync = true output.sync = true case bootstrap when :write stream.write_bootstrap(mode) when :read actual_mode = stream.read_bootstrap unless actual_mode == mode raise ProtocolError, "Expected HTTY bootstrap mode #{mode.inspect}, got #{actual_mode.inspect}" end end return stream end |
Instance Method Details
#close_write(error = nil) ⇒ Object Also known as: close
Close the local write side of this stream abstraction. HTTY does not define a close packet, and closing this object does not close the underlying terminal IO.
106 107 108 109 110 111 |
# File 'lib/protocol/htty/stream.rb', line 106 def close_write(error = nil) unless @local_closed @local_closed = true @output.flush end end |
#closed? ⇒ Boolean
Check whether the local side of the transport is closed.
117 118 119 |
# File 'lib/protocol/htty/stream.rb', line 117 def closed? @local_closed end |
#flush ⇒ Object
Flush any buffered output through the underlying stream.
99 100 101 |
# File 'lib/protocol/htty/stream.rb', line 99 def flush @output.flush end |
#io ⇒ Object
Return the underlying output stream.
55 56 57 |
# File 'lib/protocol/htty/stream.rb', line 55 def io @output end |
#read(length = nil) ⇒ Object
Read application bytes from the HTTY transport. The HTTP/2 framer always requests exact byte counts (header size, then payload length), so we delegate directly to the underlying input.
81 82 83 |
# File 'lib/protocol/htty/stream.rb', line 81 def read(length = nil) @input.read(length) end |
#read_bootstrap ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/protocol/htty/stream.rb', line 64 def read_bootstrap while payload = read_payload next unless payload.start_with?(BOOTSTRAP_PREFIX) mode = payload.delete_prefix(BOOTSTRAP_PREFIX) unless mode == RAW_MODE raise ProtocolError, "Unsupported HTTY bootstrap mode: #{mode.inspect}" end return mode end return nil end |
#readable? ⇒ Boolean
Check whether the remote side may still provide more data.
123 124 125 |
# File 'lib/protocol/htty/stream.rb', line 123 def readable? !(@input.respond_to?(:closed?) && @input.closed?) end |
#remote_address ⇒ Object
Required by Protocol::HTTP::Peer but not applicable to HTTY, which does not have a concept of remote addresses.
47 48 49 |
# File 'lib/protocol/htty/stream.rb', line 47 def remote_address return nil end |
#write(data, flush: false) ⇒ Object
Write application bytes after bootstrap.
88 89 90 91 92 93 94 95 |
# File 'lib/protocol/htty/stream.rb', line 88 def write(data, flush: false) raise IOError, "HTTY stream is closed for writing!" if @local_closed @output.write(data.to_s.b) @output.flush if flush return self end |
#write_bootstrap(mode = RAW_MODE) ⇒ Object
59 60 61 62 |
# File 'lib/protocol/htty/stream.rb', line 59 def write_bootstrap(mode = RAW_MODE) @output.write("#{DCS}#{BOOTSTRAP_PREFIX}#{mode}#{ST}") @output.flush end |