From 9b0bf863c4aab090c158f3da05aab1330212232e Mon Sep 17 00:00:00 2001 From: Anton Zhuravsky Date: Fri, 5 Apr 2024 23:28:00 +0100 Subject: [PATCH 1/2] Avoid writing to the body after full hijack (#151) * Handling partially and fully hijacked connections gracefully * A more precise test of hijacked body * Bumping protocol-http1 and updating hijack check * Closing the body after hijack --------- Co-authored-by: Anton Zhuravsky --- async-http.gemspec | 2 +- lib/async/http/protocol/http1/server.rb | 4 ++-- test/async/http/protocol/http11.rb | 30 ++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/async-http.gemspec b/async-http.gemspec index 5247d9c5..7bd0bcd7 100644 --- a/async-http.gemspec +++ b/async-http.gemspec @@ -23,7 +23,7 @@ Gem::Specification.new do |spec| spec.add_dependency "async-io", ">= 1.28" spec.add_dependency "async-pool", ">= 0.2" spec.add_dependency "protocol-http", "~> 0.26.0" - spec.add_dependency "protocol-http1", "~> 0.18.0" + spec.add_dependency "protocol-http1", "~> 0.19.0" spec.add_dependency "protocol-http2", "~> 0.16.0" spec.add_dependency "traces", ">= 0.10.0" end diff --git a/lib/async/http/protocol/http1/server.rb b/lib/async/http/protocol/http1/server.rb index 901d25c3..79bc2486 100644 --- a/lib/async/http/protocol/http1/server.rb +++ b/lib/async/http/protocol/http1/server.rb @@ -50,8 +50,8 @@ def each(task: Task.current) response = yield(request, self) body = response&.body - if @stream.nil? and body.nil? - # Full hijack. + if hijacked? + body&.close return end diff --git a/test/async/http/protocol/http11.rb b/test/async/http/protocol/http11.rb index 67448c2a..ab36016c 100755 --- a/test/async/http/protocol/http11.rb +++ b/test/async/http/protocol/http11.rb @@ -65,7 +65,7 @@ def around "Hello World!" ) peer.close - + nil end end @@ -82,5 +82,33 @@ def around expect(response.reason).to be == "It worked!" end end + + with 'full hijack with empty response' do + let(:body) {Async::HTTP::Body::Buffered.new([], 0)} + + let(:app) do + ::Protocol::HTTP::Middleware.for do |request| + peer = request.hijack! + + peer.write( + "#{request.version} 200 It worked!\r\n" + + "connection: close\r\n" + + "\r\n" + + "Hello World!" + ) + peer.close + + ::Protocol::HTTP::Response[-1, {}, body] + end + end + + it "works properly" do + expect(body).to receive(:close) + + response = client.get("/") + + expect(response.read).to be == "Hello World!" + end + end end end From 260d8272384d88945fee090c5e9df4bf8b2be0c7 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Sun, 7 Apr 2024 14:14:48 +1200 Subject: [PATCH 2/2] Bump patch version. --- lib/async/http/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/async/http/version.rb b/lib/async/http/version.rb index 68edd75d..1e2bf3da 100644 --- a/lib/async/http/version.rb +++ b/lib/async/http/version.rb @@ -5,6 +5,6 @@ module Async module HTTP - VERSION = "0.64.0" + VERSION = "0.64.1" end end