class Polyphony::HTTP::Server::HTTP2StreamHandler
Manages an HTTP
2 stream
Attributes
__next__[RW]
Public Class Methods
new(stream, &block)
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 13 def initialize(stream, &block) @stream = stream @calling_fiber = Fiber.current @stream_fiber = Fiber.new { |req| handle_request(req, &block) } # Stream callbacks occur on the connection fiber (see HTTP2::Protocol#each). # The request handler is run on a separate fiber for each stream, allowing # concurrent handling of incoming requests on the same HTTP/2 connection. # # The different stream adapter APIs suspend the stream fiber, waiting for # stream callbacks to be called. The callbacks, in turn, transfer control to # the stream fiber, effectively causing the return of the adapter API calls. # # Note: the request handler is run once headers are received. Reading the # request body, if present, is at the discretion of the request handler. # This mirrors the behaviour of the HTTP/1 adapter. stream.on(:headers, &method(:on_headers)) stream.on(:data, &method(:on_data)) stream.on(:half_close, &method(:on_half_close)) end
Public Instance Methods
consume_request()
click to toggle source
Wait for request to finish
# File lib/polyphony/http/server/http2_stream.rb, line 90 def consume_request return if @request.complete? @waiting_for_half_close = true suspend ensure @waiting_for_half_close = nil end
finish()
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 120 def finish if @headers_sent @stream.close else headers[':status'] ||= '204' @stream.headers(headers, end_stream: true) end end
get_body_chunk()
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 77 def get_body_chunk # called in the context of the stream fiber return nil if @request.complete? @waiting_for_body_chunk = true # the chunk (or an exception) will be returned once the stream fiber is # resumed suspend ensure @waiting_for_body_chunk = nil end
handle_request(request, &block)
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 34 def handle_request(request, &block) error = nil block.(request) @calling_fiber.transfer rescue Polyphony::MoveOn # ignore rescue Exception => e error = e ensure @done = true @calling_fiber.transfer error end
on_data(data)
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 52 def on_data(data) if @waiting_for_body_chunk @waiting_for_body_chunk = nil @stream_fiber.transfer(data) else @request.buffer_body_chunk(data) end end
on_half_close()
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 61 def on_half_close if @waiting_for_body_chunk @waiting_for_body_chunk = nil @stream_fiber.transfer(nil) elsif @waiting_for_half_close @waiting_for_half_close = nil @stream_fiber.transfer(nil) else @request.complete! end end
on_headers(headers)
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 47 def on_headers(headers) @request = Request.new(headers.to_h, self) @stream_fiber.transfer(@request) end
protocol()
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 73 def protocol 'h2' end
respond(chunk, headers)
click to toggle source
response API
# File lib/polyphony/http/server/http2_stream.rb, line 100 def respond(chunk, headers) headers[':status'] ||= '200' @stream.headers(headers, end_stream: false) @stream.data(chunk, end_stream: true) @headers_sent = true end
send_chunk(chunk, done: false)
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 115 def send_chunk(chunk, done: false) send_headers({}, false) unless @headers_sent @stream.data(chunk, end_stream: done) end
send_headers(headers, empty_response = false)
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 107 def send_headers(headers, empty_response = false) return if @headers_sent headers[':status'] ||= (empty_response ? 204 : 200).to_s @stream.headers(headers, end_stream: false) @headers_sent = true end
stop()
click to toggle source
# File lib/polyphony/http/server/http2_stream.rb, line 129 def stop return if @done @stream.close @stream_fiber.schedule(Polyphony::MoveOn.new) end