Skip to content

Commit

Permalink
Separate out state machine and closed callback.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Sep 24, 2024
1 parent 08621a0 commit b6f8e19
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
28 changes: 21 additions & 7 deletions lib/protocol/http1/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ def hijack!
@stream = nil
stream.flush

self.closed!
@state = :hijacked
self.closed

return stream
end
Expand All @@ -203,13 +204,20 @@ def close(error = nil)
stream.close
end

self.closed!(error)
unless closed?
@state = :closed
self.closed(error)
end
end

def open!
raise ProtocolError, "Cannot write request in #{@state}!" unless @state == :idle
if @state == :idle
@state = :open
else
raise ProtocolError, "Cannot open connection in state: #{@state}!"
end

@state = :open
return self
end

def write_request(authority, method, path, version, headers)
Expand Down Expand Up @@ -371,7 +379,7 @@ def send_end_stream!
if @state == :open
@state = :half_closed_local
elsif @state == :half_closed_remote
self.closed!
self.close!
else
raise ProtocolError, "Cannot send end stream in #{@state}!"
end
Expand Down Expand Up @@ -525,18 +533,24 @@ def write_body_and_close(body, head)
self.send_end_stream!
end

# The connection (stream) was closed. It may now be in the idle state.
def closed(error = nil)
end

# 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)
def close!(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

self.closed(error)
end

def write_body(version, body, head = false, trailer = nil)
Expand Down Expand Up @@ -574,7 +588,7 @@ def receive_end_stream!
if @state == :open
@state = :half_closed_remote
elsif @state == :half_closed_local
self.closed!
self.close!
else
raise ProtocolError, "Cannot receive end stream in #{@state}!"
end
Expand Down
2 changes: 1 addition & 1 deletion test/protocol/http1/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@
expect(server).to be(:persistent)
error = Protocol::HTTP1::InvalidRequest.new("Invalid request")

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

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

0 comments on commit b6f8e19

Please sign in to comment.