class H2::Server::Stream
Constants
- STREAM_DATA_EVENTS
the above take only the event, the following receive both the event and the data
- STREAM_EVENTS
each stream event method is wrapped in a block to call a local instance method of the same name
Attributes
Public Class Methods
# File lib/h2/server/stream.rb, line 29 def initialize connection:, stream: @closed = false @completed = false @connection = connection @push_promises = Set.new @responded = false @stream = stream bind_events end
Public Instance Methods
trigger a GOAWAY frame when this stream is responded to and any/all push promises are complete
# File lib/h2/server/stream.rb, line 110 def goaway_on_complete on_complete { connection.goaway } end
logging helper
# File lib/h2/server/stream.rb, line 116 def log level, msg Logger.__send__ level, "[stream #{@stream.id}] #{msg}" end
begin the new push promise stream from this +@stream+ by sending the initial headers frame
@see +PushPromise#make_on!+ @see +HTTP2::Stream#promise+
# File lib/h2/server/stream.rb, line 81 def make_promise p p.make_on self push_promises << p p end
set or call +@complete+ callback
# File lib/h2/server/stream.rb, line 89 def on_complete &block return true if @completed if block @complete = block elsif @completed = (@responded and push_promises_complete?) @complete[] if Proc === complete true else false end end
create a push promise, send the headers, then queue an asynchronous task on the reactor to deliver the data
# File lib/h2/server/stream.rb, line 60 def push_promise *args pp = push_promise_for(*args) make_promise pp @connection.server.async.handle_push_promise pp end
create a push promise
# File lib/h2/server/stream.rb, line 68 def push_promise_for path:, headers: {}, body: nil headers.merge! AUTHORITY_KEY => @request.authority, SCHEME_KEY => @request.scheme PushPromise.new path: path, headers: headers, body: body end
check for push promises completion
# File lib/h2/server/stream.rb, line 103 def push_promises_complete? @push_promises.empty? or @push_promises.all? {|p| p.kept? or p.canceled?} end
write status, headers, and body to +@stream+
# File lib/h2/server/stream.rb, line 42 def respond status:, headers: {}, body: '' response = Response.new stream: self, status: status, headers: headers, body: body if @closed log :warn, 'stream closed before response sent' else log :info, response response.respond_on(stream) @responded = true end end
make this stream into an SSE event source
raises StreamError
if the request's content-type is not valid
@return [H2::Server::Stream::EventSource]
# File lib/h2/server/stream.rb, line 126 def to_eventsource headers: {} EventSource.new stream: self, headers: headers end
Protected Instance Methods
bind parser events to this instance
# File lib/h2/server/stream.rb, line 134 def bind_events STREAM_EVENTS.each do |e| on = "on_#{e}".to_sym @stream.on(e) { __send__ on } end STREAM_DATA_EVENTS.each do |e| on = "on_#{e}".to_sym @stream.on(e) { |x| __send__ on, x } end end
called by +@stream+ when this stream is activated
# File lib/h2/server/stream.rb, line 147 def on_active log :debug, 'active' @request = H2::Server::Stream::Request.new self end
called by +@stream+ when this stream is closed
# File lib/h2/server/stream.rb, line 154 def on_close log :debug, 'close' on_complete @closed = true end
called by +@stream+ with a String
body part
# File lib/h2/server/stream.rb, line 170 def on_data d log :debug, "data: <<#{d}>>" @request.body << d end
called by +@stream+ when body/request is complete, signaling that client is ready for response(s)
# File lib/h2/server/stream.rb, line 178 def on_half_close log :debug, 'half_close' connection.server.async.handle_stream self end
called by +@stream+ with a Hash
# File lib/h2/server/stream.rb, line 162 def on_headers h incoming_headers = Hash[h] log :debug, "headers: #{incoming_headers}" @request.headers.merge! incoming_headers end