Skip to content

Commit

Permalink
Propagate error handling via close.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Sep 23, 2024
1 parent e42e521 commit 4191d0a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 17 deletions.
42 changes: 25 additions & 17 deletions lib/protocol/http1/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,15 @@ def hijacked?
# @return [IO] the underlying non-blocking IO.
def hijack!
@persistent = false
stream = @stream

@stream.flush
@stream = nil

self.closed!

return stream
if stream = @stream
@stream = nil
stream.flush

self.closed!

return stream
end
end

def close_read
Expand All @@ -193,10 +194,15 @@ def close_read
end

# Close the connection and underlying stream.
def close
def close(error = nil)
@persistent = false
@stream&.close
self.closed!

if stream = @stream
@stream = nil
stream.close
end

self.closed!(error)
end

def open!
Expand Down Expand Up @@ -518,13 +524,15 @@ def write_body_and_close(body, head)
self.send_end_stream!
end

def idle!
@state = :idle
end

def closed!
if @persistent
self.idle!
# Transition to the closed state.
#
# If no error occurred, and the connection is persistent, this will immediately transition to the idle state.
#
# @parameter error [Exxception] the error that caused the connection to close.
def closed!(error = nil)
if @persistent and !error
# If there was no error, and the connection is persistent, we can reuse it:
@state = :idle
else
@state = :closed
end
Expand Down
17 changes: 17 additions & 0 deletions test/protocol/http1/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -677,4 +677,21 @@
server.write_interim_response("HTTP/1.0", 100, {})
end.to raise_exception(Protocol::HTTP1::ProtocolError)
end

with "#close" do
it "enters closed state" do
server.close
expect(server).to be(:closed?)
end

it "enters closed state when given an error" do
expect(server).to be(:persistent)
error = Protocol::HTTP1::InvalidRequest.new("Invalid request")

expect(server).to receive(:closed!).with(error)

server.close(error)
expect(server).to be(:closed?)
end
end
end

0 comments on commit 4191d0a

Please sign in to comment.