class Async::HTTP::Protocol::HTTP2::Response::Stream

Represents the HTTP/2 stream associated with an outgoing client-side response.

def accept_push_promise_stream(promised_stream_id, headers)

@parameter headers [Array] The promise headers.
@parameter promised_stream_id [Integer] The stream ID for the promised resource.
Handle a push promise stream from the server.
def accept_push_promise_stream(promised_stream_id, headers)
	raise ProtocolError, "Cannot accept push promise stream!"
end

def closed(error)

@parameter error [Exception | Nil] The error that caused the close, if any.
Called when the stream is closed.
def closed(error)
	super
	
	if @response
		@response = nil
	end
	
	unless @ready.resolved?
		error ||= EOFError.new("Stream closed before response headers were received!")
		@ready.reject(error)
	end
end

def initialize(*)

Initialize the response stream.
def initialize(*)
	super
	
	@response = Response.new(self)
	
	@ready = Async::Promise.new
end

def receive_initial_headers(headers, end_stream)

This should be invoked from the background reader, and notifies the task waiting for the headers that we are done.
def receive_initial_headers(headers, end_stream)
	# While in theory, the response pseudo-headers may be extended in the future, currently they only response pseudo-header is :status, so we can assume it is always the first header.
	status_header = headers.shift
	
	if status_header.first != ":status"
		raise ProtocolError, "Invalid response headers: #{headers.inspect}"
	end
	
	status = Integer(status_header.last)
	
	if status >= 100 && status < 200
		return receive_interim_headers(status, headers)
	end
	
	@response.status = status
	@headers = ::Protocol::HTTP::Headers.new
	
	# If the protocol request was successful, ensure the response protocol matches:
	if status == 200 and protocol = @response.request.protocol
		@response.protocol = Array(protocol).first
	end
	
	headers.each do |key, value|
		# It's guaranteed that this should be the first header:
		if key == CONTENT_LENGTH
			@length = Integer(value)
		else
			add_header(key, value)
		end
	end
	
	@response.headers = @headers
	
	if @response.valid?
		if !end_stream
			# We only construct the input/body if data is coming.
			@response.body = prepare_input(@length)
		elsif @response.head?
			@response.body = ::Protocol::HTTP::Body::Head.new(@length)
		end
	else
		send_reset_stream(::Protocol::HTTP2::Error::PROTOCOL_ERROR)
	end
	
	@ready.resolve(nil)
	
	return headers
end

def receive_interim_headers(status, headers)

@parameter headers [Array] The interim response headers.
@parameter status [Integer] The interim status code.
Process interim (1xx) response headers.
def receive_interim_headers(status, headers)
	if headers.any?
		headers = ::Protocol::HTTP::Headers[headers]
	else
		headers = nil
	end
	
	@response.request.send_interim_response(status, headers)
end

def wait

Wait for the headers to be received or for stream reset.
def wait
	@ready.wait
rescue ::Protocol::HTTP2::StreamError => error
	if error.code == ::Protocol::HTTP2::Error::INTERNAL_ERROR
		raise ::Protocol::HTTP::RemoteError, error.message
	end
	
	raise
end

def wait_for_input

@returns [Protocol::HTTP::Body::Readable | Nil] The response body.
Wait for the response headers and return the response body.
def wait_for_input
	response = @response
	
	# The input isn't ready until the response headers have been received:
	response.wait
	
	# There is a possible race condition if you try to access @input - it might already be closed and nil.
	return response.body
end