diff options
Diffstat (limited to 'lib/plum/stream.rb')
-rw-r--r-- | lib/plum/stream.rb | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/lib/plum/stream.rb b/lib/plum/stream.rb index 823a41a..733aeaf 100644 --- a/lib/plum/stream.rb +++ b/lib/plum/stream.rb @@ -6,7 +6,6 @@ module Plum class Stream include EventEmitter include FlowControl - include StreamUtils attr_reader :id, :state, :connection attr_reader :weight, :exclusive @@ -92,6 +91,43 @@ module Plum end end + # Reserves a stream to server push. Sends PUSH_PROMISE and create new stream. + # @param headers [Enumerable<String, String>] The *request* headers. It must contain all of them: ':authority', ':method', ':scheme' and ':path'. + # @return [Stream] The stream to send push response. + def promise(headers) + stream = @connection.reserve_stream(weight: self.weight + 1, parent: self) + encoded = @connection.hpack_encoder.encode(headers) + frame = Frame.push_promise(id, stream.id, encoded, end_headers: true) + send frame + stream + end + + # Sends response headers. If the encoded frame is larger than MAX_FRAME_SIZE, the headers will be splitted into HEADERS frame and CONTINUATION frame(s). + # @param headers [Enumerable<String, String>] The response headers. + # @param end_stream [Boolean] Set END_STREAM flag or not. + def send_headers(headers, end_stream:) + encoded = @connection.hpack_encoder.encode(headers) + frame = Frame.headers(id, encoded, end_headers: true, end_stream: end_stream) + send frame + @state = :half_closed_local if end_stream + end + + # Sends DATA frame. If the data is larger than MAX_FRAME_SIZE, DATA frame will be splitted. + # @param data [String, IO] The data to send. + # @param end_stream [Boolean] Set END_STREAM flag or not. + def send_data(data = "", end_stream: true) + max = @connection.remote_settings[:max_frame_size] + if data.is_a?(IO) + until data.eof? + fragment = data.readpartial(max) + send Frame.data(id, fragment, end_stream: end_stream && data.eof?) + end + else + send Frame.data(id, data, end_stream: end_stream) + end + @state = :half_closed_local if end_stream + end + private def send_immediately(frame) @connection.send(frame) |