Skip to content

Commit

Permalink
Correctly handle state changes w.r.t. interim responses.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Sep 18, 2024
1 parent e54fe82 commit adb1487
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
26 changes: 18 additions & 8 deletions lib/protocol/http1/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,9 @@ def write_request(authority, method, path, version, headers)
end

def write_response(version, status, headers, reason = Reason::DESCRIPTIONS[status])
raise ProtocolError, "Cannot write response in #{@state}!" unless @state == :open or @state == :half_closed_remote
unless @state == :open or @state == :half_closed_remote
raise ProtocolError, "Cannot write response in #{@state}!"
end

# Safari WebSockets break if no reason is given:
@stream.write("#{version} #{status} #{reason}\r\n")
Expand All @@ -214,7 +216,9 @@ def write_response(version, status, headers, reason = Reason::DESCRIPTIONS[statu
end

def write_interim_response(version, status, headers, reason = Reason::DESCRIPTIONS[status])
raise ProtocolError, "Cannot write interim response!" unless @state == :open
unless @state == :open or @state == :half_closed_remote
raise ProtocolError, "Cannot write interim response in #{@state}!"
end

@stream.write("#{version} #{status} #{reason}\r\n")

Expand Down Expand Up @@ -305,6 +309,10 @@ def read_response_line
return version, status, reason
end

private def interim_status?(status)
status != 101 and status >= 100 and status < 200
end

def read_response(method)
unless @state == :open or @state == :half_closed_local
raise ProtocolError, "Cannot read response in #{@state}!"
Expand All @@ -316,14 +324,16 @@ def read_response(method)

@persistent = persistent?(version, method, headers)

body = read_response_body(method, status, headers)

unless body
self.receive_end_stream!
unless interim_status?(status)
body = read_response_body(method, status, headers)

unless body
self.receive_end_stream!
end

@count += 1
end

@count += 1

return version, status, reason, headers, body
end

Expand Down
8 changes: 8 additions & 0 deletions test/protocol/http1/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -675,4 +675,12 @@
body.join
end.to raise_exception(Protocol::HTTP1::ProtocolError)
end

it "can't write interim response in the closed state" do
server.state = :closed

expect do
server.write_interim_response("HTTP/1.0", 100, {})
end.to raise_exception(Protocol::HTTP1::ProtocolError)
end
end

0 comments on commit adb1487

Please sign in to comment.