diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2015-08-11 21:10:33 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2015-08-11 21:10:33 +0900 |
commit | 72fc8863a315916237a5e3141432c8926783c2bf (patch) | |
tree | ea88e6277bacc187df3aac9de46a9d9157669039 /lib/plum/stream_utils.rb | |
parent | 45517dac41ca3ae0575a936576b7cc6828458244 (diff) | |
download | plum-72fc8863a315916237a5e3141432c8926783c2bf.tar.gz |
rename StreamHelper to StreamUtils
Diffstat (limited to 'lib/plum/stream_utils.rb')
-rw-r--r-- | lib/plum/stream_utils.rb | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/plum/stream_utils.rb b/lib/plum/stream_utils.rb new file mode 100644 index 0000000..0c4f4a6 --- /dev/null +++ b/lib/plum/stream_utils.rb @@ -0,0 +1,58 @@ +using Plum::BinaryString + +module Plum + module StreamUtils + # Responds to HTTP request. + # + # @param headers [Hash<String, String>] The response headers. + # @param body [String, IO] The response body. + def respond(headers, body = nil, end_stream: true) # TODO: priority, padding + if body + send_headers(headers, end_stream: false) + send_data(body, end_stream: end_stream) + else + send_headers(headers, end_stream: end_stream) + end + end + + # Reserves a stream to server push. Sends PUSH_STREAM and create new stream. + # + # @param headers [Hash<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) + original = Frame.push_promise(id, stream.id, encoded, :end_headers) + original.split_headers(@connection.remote_settings[:max_frame_size]).each do |frame| + send frame + end + stream + end + + private + def send_headers(headers, end_stream:) + max = @connection.remote_settings[:max_frame_size] + encoded = @connection.hpack_encoder.encode(headers) + original_frame = Frame.headers(id, encoded, :end_headers, (end_stream && :end_stream || nil)) + original_frame.split_headers(max).each do |frame| + send frame + end + @state = :half_closed_local if end_stream + end + + def send_data(data, end_stream: true) + max = @connection.remote_settings[:max_frame_size] + if data.is_a?(IO) + while !data.eof? && fragment = data.readpartial(max) + send Frame.data(id, fragment, (end_stream && data.eof? && :end_stream)) + end + else + original = Frame.data(id, data, (end_stream && :end_stream)) + original.split_data(max).each do |frame| + send frame + end + end + @state = :half_closed_local if end_stream + end + end +end |