class Async::HTTP::Protocol::HTTP2
def call(request)
def call(request) request.version ||= self.version stream = @controller.new_stream @count += 1 headers = { SCHEME => HTTPS, METHOD => request.method.to_s, PATH => request.path.to_s, AUTHORITY => request.authority.to_s, }.merge(request.headers) finished = Async::Notification.new exception = nil response = Response.new response.version = self.version response.headers = {} body = Body::Writable.new response.body = body stream.on(:headers) do |headers| headers.each do |key, value| if key == STATUS response.status = value.to_i elsif key == REASON response.reason = value else response.headers[key] = value end end # At this point, we are now expecting two events: data and close. stream.on(:close) do |error| # If we receive close after this point, it's not a request error, but a failure we need to signal to the body. if error body.stop(EOFError.new(error)) else body.finish end end finished.signal end stream.on(:data) do |chunk| body.write(chunk.to_s) unless chunk.empty? end stream.on(:close) do |error| # The remote server has closed the connection while we were sending the request. if error exception = EOFError.new(error) finished.signal end end if request.body.nil? or request.body.empty? stream.headers(headers, end_stream: true) request.body.read if request.body else begin stream.headers(headers, end_stream: false) rescue raise RequestFailed.new end request.body.each do |chunk| stream.data(chunk, end_stream: false) end stream.data("", end_stream: true) end start_connection @stream.flush Async.logger.debug(self) {"Stream flushed, waiting for signal."} finished.wait if exception raise exception end Async.logger.debug(self) {"Stream finished: #{response.inspect}"} return response end