diff --git a/async-http.gemspec b/async-http.gemspec index 22c99209..5bba293a 100644 --- a/async-http.gemspec +++ b/async-http.gemspec @@ -25,8 +25,9 @@ Gem::Specification.new do |spec| spec.required_ruby_version = ">= 3.1" spec.add_dependency "async", ">= 1.25" - spec.add_dependency "async-io", ">= 1.28" + spec.add_dependency "async-io", ">= 1.43.1" spec.add_dependency "async-pool", ">= 0.6.1" + spec.add_dependency "io-stream", "~> 0.1.1" spec.add_dependency "protocol-http", "~> 0.26.0" spec.add_dependency "protocol-http1", "~> 0.19.0" spec.add_dependency "protocol-http2", "~> 0.17.0" diff --git a/fixtures/async/http/a_protocol.rb b/fixtures/async/http/a_protocol.rb index f584bd72..4250c438 100644 --- a/fixtures/async/http/a_protocol.rb +++ b/fixtures/async/http/a_protocol.rb @@ -202,6 +202,9 @@ module HTTP end it "disconnects slow clients" do + # We won't be able to disconnect slow clients if IO#timeout is not available: + skip_unless_method_defined(:timeout, IO) + response = client.get("/") response.read @@ -478,9 +481,11 @@ def after end it "can't get /" do + skip_unless_method_defined(:timeout, IO) + expect do client.get("/") - end.to raise_exception(Async::TimeoutError) + end.to raise_exception(::IO::TimeoutError) end end diff --git a/gems.rb b/gems.rb index 2173f993..624f8238 100644 --- a/gems.rb +++ b/gems.rb @@ -9,6 +9,7 @@ # gem "async", path: "../async" # gem "async-io", path: "../async-io" +# gem "io-stream", path: "../io-stream" # gem "traces", path: "../traces" # gem "protocol-http", path: "../protocol-http" diff --git a/lib/async/http/body/pipe.rb b/lib/async/http/body/pipe.rb index 7cae7a1e..6ef1c0e1 100644 --- a/lib/async/http/body/pipe.rb +++ b/lib/async/http/body/pipe.rb @@ -1,12 +1,9 @@ # frozen_string_literal: true # Released under the MIT License. -# Copyright, 2019-2023, by Samuel Williams. +# Copyright, 2019-2024, by Samuel Williams. # Copyright, 2020, by Bruno Sutic. -require 'async/io/socket' -require 'async/io/stream' - require_relative 'writable' module Async @@ -18,9 +15,9 @@ def initialize(input, output = Writable.new, task: Task.current) @input = input @output = output - head, tail = IO::Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM) + head, tail = ::Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM) - @head = IO::Stream.new(head) + @head = ::IO::Stream::Buffered.new(head) @tail = tail @reader = nil diff --git a/lib/async/http/protocol/http1.rb b/lib/async/http/protocol/http1.rb index cd810519..e30f3410 100644 --- a/lib/async/http/protocol/http1.rb +++ b/lib/async/http/protocol/http1.rb @@ -1,11 +1,13 @@ # frozen_string_literal: true # Released under the MIT License. -# Copyright, 2017-2023, by Samuel Williams. +# Copyright, 2017-2024, by Samuel Williams. require_relative 'http1/client' require_relative 'http1/server' +require 'io/stream/buffered' + module Async module HTTP module Protocol @@ -21,13 +23,13 @@ def self.trailer? end def self.client(peer) - stream = IO::Stream.new(peer, sync: true) + stream = ::IO::Stream::Buffered.wrap(peer) return HTTP1::Client.new(stream, VERSION) end def self.server(peer) - stream = IO::Stream.new(peer, sync: true) + stream = ::IO::Stream::Buffered.wrap(peer) return HTTP1::Server.new(stream, VERSION) end diff --git a/lib/async/http/protocol/http1/connection.rb b/lib/async/http/protocol/http1/connection.rb index fb8491bb..23a3ed6f 100755 --- a/lib/async/http/protocol/http1/connection.rb +++ b/lib/async/http/protocol/http1/connection.rb @@ -62,7 +62,7 @@ def concurrency # Can we use this connection to make requests? def viable? - @ready && @stream&.connected? + @ready && @stream&.readable? end def reusable? diff --git a/lib/async/http/protocol/http10.rb b/lib/async/http/protocol/http10.rb index 0d1be183..9066d693 100755 --- a/lib/async/http/protocol/http10.rb +++ b/lib/async/http/protocol/http10.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Released under the MIT License. -# Copyright, 2017-2023, by Samuel Williams. +# Copyright, 2017-2024, by Samuel Williams. require_relative 'http1' @@ -20,13 +20,13 @@ def self.trailer? end def self.client(peer) - stream = IO::Stream.new(peer, sync: true) + stream = ::IO::Stream::Buffered.wrap(peer) return HTTP1::Client.new(stream, VERSION) end def self.server(peer) - stream = IO::Stream.new(peer, sync: true) + stream = ::IO::Stream::Buffered.wrap(peer) return HTTP1::Server.new(stream, VERSION) end diff --git a/lib/async/http/protocol/http11.rb b/lib/async/http/protocol/http11.rb index ef929b48..083dc141 100644 --- a/lib/async/http/protocol/http11.rb +++ b/lib/async/http/protocol/http11.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Released under the MIT License. -# Copyright, 2017-2023, by Samuel Williams. +# Copyright, 2017-2024, by Samuel Williams. # Copyright, 2018, by Janko Marohnić. require_relative 'http1' @@ -21,13 +21,13 @@ def self.trailer? end def self.client(peer) - stream = IO::Stream.new(peer, sync: true) + stream = ::IO::Stream::Buffered.wrap(peer) return HTTP1::Client.new(stream, VERSION) end def self.server(peer) - stream = IO::Stream.new(peer, sync: true) + stream = ::IO::Stream::Buffered.wrap(peer) return HTTP1::Server.new(stream, VERSION) end diff --git a/lib/async/http/protocol/http2.rb b/lib/async/http/protocol/http2.rb index 6671f8ee..7a75a34a 100644 --- a/lib/async/http/protocol/http2.rb +++ b/lib/async/http/protocol/http2.rb @@ -1,11 +1,13 @@ # frozen_string_literal: true # Released under the MIT License. -# Copyright, 2018-2023, by Samuel Williams. +# Copyright, 2018-2024, by Samuel Williams. require_relative 'http2/client' require_relative 'http2/server' +require 'io/stream/buffered' + module Async module HTTP module Protocol @@ -35,8 +37,7 @@ def self.trailer? } def self.client(peer, settings = CLIENT_SETTINGS) - stream = IO::Stream.new(peer, sync: true) - + stream = ::IO::Stream::Buffered.wrap(peer) client = Client.new(stream) client.send_connection_preface(settings) @@ -46,8 +47,7 @@ def self.client(peer, settings = CLIENT_SETTINGS) end def self.server(peer, settings = SERVER_SETTINGS) - stream = IO::Stream.new(peer, sync: true) - + stream = ::IO::Stream::Buffered.wrap(peer) server = Server.new(stream) server.read_connection_preface(settings) diff --git a/lib/async/http/protocol/http2/connection.rb b/lib/async/http/protocol/http2/connection.rb index d63cb924..631cc416 100644 --- a/lib/async/http/protocol/http2/connection.rb +++ b/lib/async/http/protocol/http2/connection.rb @@ -122,7 +122,7 @@ def concurrency # Can we use this connection to make requests? def viable? - @stream.connected? + @stream&.readable? end def reusable? diff --git a/test/async/http/body/pipe.rb b/test/async/http/body/pipe.rb index 8efac033..94cdcb07 100644 --- a/test/async/http/body/pipe.rb +++ b/test/async/http/body/pipe.rb @@ -42,7 +42,7 @@ def aftrer end it "returns an io socket" do - expect(io).to be_a(Async::IO::Socket) + expect(io).to be_a(::Socket) expect(io.read).to be == data end diff --git a/test/async/http/proxy.rb b/test/async/http/proxy.rb index 689c5c5a..24bf1659 100644 --- a/test/async/http/proxy.rb +++ b/test/async/http/proxy.rb @@ -131,7 +131,7 @@ Console.logger.debug(self) {"Making connection to #{endpoint}..."} Async::HTTP::Body::Hijack.response(request, 200, {}) do |stream| - upstream = Async::IO::Stream.new(endpoint.connect) + upstream = ::IO::Stream::Buffered.wrap(endpoint.connect) Console.logger.debug(self) {"Connected to #{upstream}..."} reader = Async do |task|