Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions lib/protocol/http2/stream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -239,22 +239,21 @@ def open!
return self
end

# The stream has been closed. If closed due to a stream reset, the error will be set.
# The stream has been closed. If closed due to a stream reset with a non-zero error code, the error will be set.
def closed(error = nil)
end

# Transition the stream into the closed state.
# @parameter error_code [Integer] the error code if the stream was closed due to a stream reset.
# @parameter error_code [Integer | Nil] The error code if the stream was closed due to a stream reset.
def close!(error_code = nil)
@state = :closed
@connection.delete(@id)

if error_code
if error_code == REFUSED_STREAM
error = ::Protocol::HTTP::RefusedError.new("Stream refused.")
else
error = StreamError.for(error_code)
end
# `NO_ERROR` represents an orderly stream closure, so it is passed to `closed` as `nil` rather than converted to an exception.
if error_code == REFUSED_STREAM
error = ::Protocol::HTTP::RefusedError.new("Stream refused.")
elsif error_code && error_code != NO_ERROR
error = StreamError.for(error_code)
end

self.closed(error)
Expand Down
4 changes: 4 additions & 0 deletions releases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Releases

## Unreleased

- Treat `RST_STREAM(NO_ERROR)` as an orderly stream closure rather than constructing a `StreamError`.

## v0.27.0

- On a graceful `GOAWAY` (error code `0`), keep the connection open until the streams the remote peer accepted have completed, instead of closing it immediately and failing those requests with `EOFError`.
Expand Down
18 changes: 18 additions & 0 deletions test/protocol/http2/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,24 @@ def closed(error)
expect(stream.error).to be_a(Protocol::HTTP::RefusedError)
end

it "closes stream without an error on NO_ERROR" do
stream = client.create_stream do |connection, id|
stream_class.create(connection, id)
end
stream.send_headers(request_headers, Protocol::HTTP2::END_STREAM)

# Establish request stream on server:
server.read_frame

# Server closes the stream without an error:
server.streams[stream.id].send_reset_stream(Protocol::HTTP2::NO_ERROR)

client.read_frame

expect(stream.state).to be == :closed
expect(stream.error).to be_nil
end

it "closes unprocessed streams with RefusedError on graceful GOAWAY" do
stream.send_headers(request_headers, Protocol::HTTP2::END_STREAM)

Expand Down