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.
-
#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.
46 47 48 |
# File 'lib/protocol/htty/stream.rb', line 46 def input @input end |
#output ⇒ Object (readonly)
Returns the value of attribute output.
47 48 49 |
# File 'lib/protocol/htty/stream.rb', line 47 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.
101 102 103 104 105 106 |
# File 'lib/protocol/htty/stream.rb', line 101 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.
112 113 114 |
# File 'lib/protocol/htty/stream.rb', line 112 def closed? @local_closed end |
#flush ⇒ Object
Flush any buffered output through the underlying stream.
94 95 96 |
# File 'lib/protocol/htty/stream.rb', line 94 def flush @output.flush end |
#io ⇒ Object
Return the underlying output stream.
50 51 52 |
# File 'lib/protocol/htty/stream.rb', line 50 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.
76 77 78 |
# File 'lib/protocol/htty/stream.rb', line 76 def read(length = nil) @input.read(length) end |
#read_bootstrap ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/protocol/htty/stream.rb', line 59 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.
118 119 120 |
# File 'lib/protocol/htty/stream.rb', line 118 def readable? !(@input.respond_to?(:closed?) && @input.closed?) end |
#write(data, flush: false) ⇒ Object
Write application bytes after bootstrap.
83 84 85 86 87 88 89 90 |
# File 'lib/protocol/htty/stream.rb', line 83 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
54 55 56 57 |
# File 'lib/protocol/htty/stream.rb', line 54 def write_bootstrap(mode = RAW_MODE) @output.write("#{DCS}#{BOOTSTRAP_PREFIX}#{mode}#{ST}") @output.flush end |