class Stream
Definitions
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.
Implementation
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
self.notify!
return headers
end
def notify!
Notify anyone waiting on the response headers to be received (or failure).
Implementation
def notify!
if notification = @notification
@notification = nil
notification.signal
end
end
def wait
Wait for the headers to be received or for stream reset.
Implementation
def wait
# If you call wait after the headers were already received, it should return immediately:
@notification&.wait
if @exception
raise @exception
end
end