Skip to content

Commit 4191d0a

Browse files
committed
Propagate error handling via close.
1 parent e42e521 commit 4191d0a

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

lib/protocol/http1/connection.rb

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,15 @@ def hijacked?
176176
# @return [IO] the underlying non-blocking IO.
177177
def hijack!
178178
@persistent = false
179-
stream = @stream
180179

181-
@stream.flush
182-
@stream = nil
183-
184-
self.closed!
185-
186-
return stream
180+
if stream = @stream
181+
@stream = nil
182+
stream.flush
183+
184+
self.closed!
185+
186+
return stream
187+
end
187188
end
188189

189190
def close_read
@@ -193,10 +194,15 @@ def close_read
193194
end
194195

195196
# Close the connection and underlying stream.
196-
def close
197+
def close(error = nil)
197198
@persistent = false
198-
@stream&.close
199-
self.closed!
199+
200+
if stream = @stream
201+
@stream = nil
202+
stream.close
203+
end
204+
205+
self.closed!(error)
200206
end
201207

202208
def open!
@@ -518,13 +524,15 @@ def write_body_and_close(body, head)
518524
self.send_end_stream!
519525
end
520526

521-
def idle!
522-
@state = :idle
523-
end
524-
525-
def closed!
526-
if @persistent
527-
self.idle!
527+
# Transition to the closed state.
528+
#
529+
# If no error occurred, and the connection is persistent, this will immediately transition to the idle state.
530+
#
531+
# @parameter error [Exxception] the error that caused the connection to close.
532+
def closed!(error = nil)
533+
if @persistent and !error
534+
# If there was no error, and the connection is persistent, we can reuse it:
535+
@state = :idle
528536
else
529537
@state = :closed
530538
end

test/protocol/http1/connection.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,4 +677,21 @@
677677
server.write_interim_response("HTTP/1.0", 100, {})
678678
end.to raise_exception(Protocol::HTTP1::ProtocolError)
679679
end
680+
681+
with "#close" do
682+
it "enters closed state" do
683+
server.close
684+
expect(server).to be(:closed?)
685+
end
686+
687+
it "enters closed state when given an error" do
688+
expect(server).to be(:persistent)
689+
error = Protocol::HTTP1::InvalidRequest.new("Invalid request")
690+
691+
expect(server).to receive(:closed!).with(error)
692+
693+
server.close(error)
694+
expect(server).to be(:closed?)
695+
end
696+
end
680697
end

0 commit comments

Comments
 (0)